aboutsummaryrefslogtreecommitdiff
path: root/src/deflate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/deflate.cpp')
-rw-r--r--src/deflate.cpp120
1 files changed, 65 insertions, 55 deletions
diff --git a/src/deflate.cpp b/src/deflate.cpp
index aec2a18..10a9c5f 100644
--- a/src/deflate.cpp
+++ b/src/deflate.cpp
@@ -8,10 +8,15 @@
8#include "bu/deflate.h" 8#include "bu/deflate.h"
9#include "bu/trace.h" 9#include "bu/trace.h"
10 10
11#include <zlib.h>
12
13#define pState ((z_stream *)prState)
14
11using namespace Bu; 15using namespace Bu;
12 16
13Bu::Deflate::Deflate( Bu::Stream &rNext, int nCompression, Format eFmt ) : 17Bu::Deflate::Deflate( Bu::Stream &rNext, int nCompression, Format eFmt ) :
14 Bu::Filter( rNext ), 18 Bu::Filter( rNext ),
19 prState( NULL ),
15 nCompression( nCompression ), 20 nCompression( nCompression ),
16 sTotalOut( 0 ), 21 sTotalOut( 0 ),
17 eFmt( eFmt ), 22 eFmt( eFmt ),
@@ -30,10 +35,11 @@ Bu::Deflate::~Deflate()
30void Bu::Deflate::start() 35void Bu::Deflate::start()
31{ 36{
32 TRACE(); 37 TRACE();
33 zState.zalloc = NULL; 38 prState = new z_stream;
34 zState.zfree = NULL; 39 pState->zalloc = NULL;
35 zState.opaque = NULL; 40 pState->zfree = NULL;
36 zState.state = NULL; 41 pState->opaque = NULL;
42 pState->state = NULL;
37 43
38 nBufSize = 64*1024; 44 nBufSize = 64*1024;
39 pBuf = new char[nBufSize]; 45 pBuf = new char[nBufSize];
@@ -42,34 +48,38 @@ void Bu::Deflate::start()
42Bu::size Bu::Deflate::stop() 48Bu::size Bu::Deflate::stop()
43{ 49{
44 TRACE(); 50 TRACE();
45 if( zState.state ) 51 if( pState && pState->state )
46 { 52 {
47 if( bReading ) 53 if( bReading )
48 { 54 {
49 inflateEnd( &zState ); 55 inflateEnd( pState );
50 delete[] pBuf; 56 delete[] pBuf;
51 pBuf = NULL; 57 pBuf = NULL;
58 delete pState;
59 prState = NULL;
52 return 0; 60 return 0;
53 } 61 }
54 else 62 else
55 { 63 {
56 for(;;) 64 for(;;)
57 { 65 {
58 zState.next_in = NULL; 66 pState->next_in = NULL;
59 zState.avail_in = 0; 67 pState->avail_in = 0;
60 zState.avail_out = nBufSize; 68 pState->avail_out = nBufSize;
61 zState.next_out = (Bytef *)pBuf; 69 pState->next_out = (Bytef *)pBuf;
62 int res = deflate( &zState, Z_FINISH ); 70 int res = deflate( pState, Z_FINISH );
63 if( zState.avail_out < nBufSize ) 71 if( pState->avail_out < nBufSize )
64 { 72 {
65 sTotalOut += rNext.write( pBuf, nBufSize-zState.avail_out ); 73 sTotalOut += rNext.write( pBuf, nBufSize-pState->avail_out );
66 } 74 }
67 if( res == Z_STREAM_END ) 75 if( res == Z_STREAM_END )
68 break; 76 break;
69 } 77 }
70 deflateEnd( &zState ); 78 deflateEnd( pState );
71 delete[] pBuf; 79 delete[] pBuf;
72 pBuf = NULL; 80 pBuf = NULL;
81 delete pState;
82 prState = NULL;
73 return sTotalOut; 83 return sTotalOut;
74 } 84 }
75 } 85 }
@@ -87,25 +97,25 @@ void Bu::Deflate::zError( int code )
87 return; 97 return;
88 98
89 case Z_ERRNO: 99 case Z_ERRNO:
90 throw ExceptionBase("Deflate: Errno - %s", zState.msg ); 100 throw ExceptionBase("Deflate: Errno - %s", pState->msg );
91 101
92 case Z_STREAM_ERROR: 102 case Z_STREAM_ERROR:
93 throw ExceptionBase("Deflate: Stream Error - %s", zState.msg ); 103 throw ExceptionBase("Deflate: Stream Error - %s", pState->msg );
94 104
95 case Z_DATA_ERROR: 105 case Z_DATA_ERROR:
96 throw ExceptionBase("Deflate: Data Error - %s", zState.msg ); 106 throw ExceptionBase("Deflate: Data Error - %s", pState->msg );
97 107
98 case Z_MEM_ERROR: 108 case Z_MEM_ERROR:
99 throw ExceptionBase("Deflate: Mem Error - %s", zState.msg ); 109 throw ExceptionBase("Deflate: Mem Error - %s", pState->msg );
100 110
101 case Z_BUF_ERROR: 111 case Z_BUF_ERROR:
102 throw ExceptionBase("Deflate: Buf Error - %s", zState.msg ); 112 throw ExceptionBase("Deflate: Buf Error - %s", pState->msg );
103 113
104 case Z_VERSION_ERROR: 114 case Z_VERSION_ERROR:
105 throw ExceptionBase("Deflate: Version Error - %s", zState.msg ); 115 throw ExceptionBase("Deflate: Version Error - %s", pState->msg );
106 116
107 default: 117 default:
108 throw ExceptionBase("Deflate: Unknown error encountered - %s.", zState.msg ); 118 throw ExceptionBase("Deflate: Unknown error encountered - %s.", pState->msg );
109 119
110 } 120 }
111} 121}
@@ -113,55 +123,55 @@ void Bu::Deflate::zError( int code )
113Bu::size Bu::Deflate::read( void *pData, Bu::size nBytes ) 123Bu::size Bu::Deflate::read( void *pData, Bu::size nBytes )
114{ 124{
115 TRACE( pData, nBytes ); 125 TRACE( pData, nBytes );
116 if( !zState.state ) 126 if( !pState->state )
117 { 127 {
118 bReading = true; 128 bReading = true;
119 if( eFmt&AutoDetect ) 129 if( eFmt&AutoDetect )
120 inflateInit2( &zState, 32+15 ); // Auto-detect, large window 130 inflateInit2( pState, 32+15 ); // Auto-detect, large window
121 else if( eFmt == Raw ) 131 else if( eFmt == Raw )
122 inflateInit2( &zState, -15 ); // Raw 132 inflateInit2( pState, -15 ); // Raw
123 else if( eFmt == Zlib ) 133 else if( eFmt == Zlib )
124 inflateInit2( &zState, 15 ); // Zlib 134 inflateInit2( pState, 15 ); // Zlib
125 else if( eFmt == Gzip ) 135 else if( eFmt == Gzip )
126 inflateInit2( &zState, 16+15 ); // GZip 136 inflateInit2( pState, 16+15 ); // GZip
127 else 137 else
128 throw Bu::ExceptionBase("Format mode for deflate read."); 138 throw Bu::ExceptionBase("Format mode for deflate read.");
129 zState.next_in = (Bytef *)pBuf; 139 pState->next_in = (Bytef *)pBuf;
130 zState.avail_in = 0; 140 pState->avail_in = 0;
131 } 141 }
132 if( bReading == false ) 142 if( bReading == false )
133 throw ExceptionBase("This deflate filter is in writing mode, you can't read."); 143 throw ExceptionBase("This deflate filter is in writing mode, you can't read.");
134 144
135 int nRead = 0; 145 int nRead = 0;
136 int nReadTotal = zState.total_out; 146 int nReadTotal = pState->total_out;
137 zState.next_out = (Bytef *)pData; 147 pState->next_out = (Bytef *)pData;
138 zState.avail_out = nBytes; 148 pState->avail_out = nBytes;
139 for(;;) 149 for(;;)
140 { 150 {
141 int ret = inflate( &zState, Z_NO_FLUSH ); 151 int ret = inflate( pState, Z_NO_FLUSH );
142 printf("inflate returned %d; avail in=%d, out=%d\n", ret, 152 printf("inflate returned %d; avail in=%d, out=%d\n", ret,
143 zState.avail_in, zState.avail_out ); 153 pState->avail_in, pState->avail_out );
144 154
145 nReadTotal += nRead-zState.avail_out; 155 nReadTotal += nRead-pState->avail_out;
146 156
147 if( ret == Z_STREAM_END ) 157 if( ret == Z_STREAM_END )
148 { 158 {
149 bEos = true; 159 bEos = true;
150 if( zState.avail_in > 0 ) 160 if( pState->avail_in > 0 )
151 { 161 {
152 if( rNext.isSeekable() ) 162 if( rNext.isSeekable() )
153 { 163 {
154 rNext.seek( -zState.avail_in ); 164 rNext.seek( -pState->avail_in );
155 } 165 }
156 } 166 }
157 return nBytes-zState.avail_out; 167 return nBytes-pState->avail_out;
158 } 168 }
159 if( ret != Z_BUF_ERROR ) 169 if( ret != Z_BUF_ERROR )
160 zError( ret ); 170 zError( ret );
161 171
162 if( zState.avail_out ) 172 if( pState->avail_out )
163 { 173 {
164 if( zState.avail_in == 0 ) 174 if( pState->avail_in == 0 )
165 { 175 {
166 nRead = rNext.read( pBuf, nBufSize ); 176 nRead = rNext.read( pBuf, nBufSize );
167 if( nRead == 0 && rNext.isEos() ) 177 if( nRead == 0 && rNext.isEos() )
@@ -169,13 +179,13 @@ Bu::size Bu::Deflate::read( void *pData, Bu::size nBytes )
169 throw Bu::ExceptionBase("Premature end of underlying " 179 throw Bu::ExceptionBase("Premature end of underlying "
170 "stream found reading deflate stream."); 180 "stream found reading deflate stream.");
171 } 181 }
172 zState.next_in = (Bytef *)pBuf; 182 pState->next_in = (Bytef *)pBuf;
173 zState.avail_in = nRead; 183 pState->avail_in = nRead;
174 } 184 }
175 } 185 }
176 else 186 else
177 { 187 {
178 return nBytes-zState.avail_out; 188 return nBytes-pState->avail_out;
179 } 189 }
180 } 190 }
181 return 0; 191 return 0;
@@ -184,18 +194,18 @@ Bu::size Bu::Deflate::read( void *pData, Bu::size nBytes )
184Bu::size Bu::Deflate::write( const void *pData, Bu::size nBytes ) 194Bu::size Bu::Deflate::write( const void *pData, Bu::size nBytes )
185{ 195{
186 TRACE( pData, nBytes ); 196 TRACE( pData, nBytes );
187 if( !zState.state ) 197 if( !pState->state )
188 { 198 {
189 bReading = false; 199 bReading = false;
190 int iFmt = eFmt&Gzip; 200 int iFmt = eFmt&Gzip;
191 if( iFmt == Raw ) 201 if( iFmt == Raw )
192 deflateInit2( &zState, nCompression, Z_DEFLATED, -15, 9, 202 deflateInit2( pState, nCompression, Z_DEFLATED, -15, 9,
193 Z_DEFAULT_STRATEGY ); 203 Z_DEFAULT_STRATEGY );
194 else if( iFmt == Zlib ) 204 else if( iFmt == Zlib )
195 deflateInit2( &zState, nCompression, Z_DEFLATED, 15, 9, 205 deflateInit2( pState, nCompression, Z_DEFLATED, 15, 9,
196 Z_DEFAULT_STRATEGY ); 206 Z_DEFAULT_STRATEGY );
197 else if( iFmt == Gzip ) 207 else if( iFmt == Gzip )
198 deflateInit2( &zState, nCompression, Z_DEFLATED, 16+15, 9, 208 deflateInit2( pState, nCompression, Z_DEFLATED, 16+15, 9,
199 Z_DEFAULT_STRATEGY ); 209 Z_DEFAULT_STRATEGY );
200 else 210 else
201 throw Bu::ExceptionBase("Invalid format for deflate."); 211 throw Bu::ExceptionBase("Invalid format for deflate.");
@@ -203,20 +213,20 @@ Bu::size Bu::Deflate::write( const void *pData, Bu::size nBytes )
203 if( bReading == true ) 213 if( bReading == true )
204 throw ExceptionBase("This deflate filter is in reading mode, you can't write."); 214 throw ExceptionBase("This deflate filter is in reading mode, you can't write.");
205 215
206 zState.next_in = (Bytef *)pData; 216 pState->next_in = (Bytef *)pData;
207 zState.avail_in = nBytes; 217 pState->avail_in = nBytes;
208 for(;;) 218 for(;;)
209 { 219 {
210 zState.avail_out = nBufSize; 220 pState->avail_out = nBufSize;
211 zState.next_out = (Bytef *)pBuf; 221 pState->next_out = (Bytef *)pBuf;
212 222
213 zError( deflate( &zState, Z_NO_FLUSH ) ); 223 zError( deflate( pState, Z_NO_FLUSH ) );
214 224
215 if( zState.avail_out < nBufSize ) 225 if( pState->avail_out < nBufSize )
216 { 226 {
217 sTotalOut += rNext.write( pBuf, nBufSize-zState.avail_out ); 227 sTotalOut += rNext.write( pBuf, nBufSize-pState->avail_out );
218 } 228 }
219 if( zState.avail_in == 0 ) 229 if( pState->avail_in == 0 )
220 break; 230 break;
221 } 231 }
222 232
@@ -226,7 +236,7 @@ Bu::size Bu::Deflate::write( const void *pData, Bu::size nBytes )
226bool Bu::Deflate::isOpen() 236bool Bu::Deflate::isOpen()
227{ 237{
228 TRACE(); 238 TRACE();
229 return (zState.state != NULL); 239 return (pState != NULL && pState->state != NULL);
230} 240}
231 241
232bool Bu::Deflate::isEos() 242bool Bu::Deflate::isEos()