@@ -131,26 +131,29 @@ void Trap_ZStream_Error(z_stream *stream, int err, REBOOL while_compression)
131
131
stream .next_in = cast (const z_Bytef * , BIN_HEAD (input ) + index );
132
132
133
133
output = Make_Binary (size );
134
- stream .avail_out = size ;
134
+ stream .avail_out = SERIES_AVAIL ( output ) ;
135
135
stream .next_out = BIN_HEAD (output );
136
136
137
- err = deflate (& stream , Z_FINISH );
138
- //printf("deflate err: %i stream.total_out: %i .avail_out: %i\n", err, stream.total_out, stream.avail_out);
139
-
140
- if (err != Z_STREAM_END )
141
- Trap_ZStream_Error (& stream , err , TRUE);
137
+ for (;;) {
138
+ err = deflate (& stream , Z_FINISH );
139
+ if (err == Z_STREAM_END )
140
+ break ; // Finished or we have enough data.
141
+ //printf("deflate err: %i stream.total_out: %i .avail_out: %i\n", err, stream.total_out, stream.avail_out);
142
+ if (err != Z_OK )
143
+ Trap_ZStream_Error (& stream , err , FALSE);
144
+ if (stream .avail_out == 0 ) {
145
+ // expand output buffer...
146
+ SERIES_TAIL (output ) = stream .total_out ;
147
+ Expand_Series (output , AT_TAIL , in_len );
148
+ stream .next_out = BIN_SKIP (output , stream .total_out );
149
+ stream .avail_out = SERIES_REST (output ) - stream .total_out ;
150
+ }
151
+ }
142
152
143
153
SET_STR_END (output , stream .total_out );
144
154
SERIES_TAIL (output ) = stream .total_out ;
145
-
146
- if ((windowBits & 16 ) != 16 ) { // Not GZIP
147
- // Tag the size to the end. Only when not using GZIP envelope.
148
- REBYTE out_size [sizeof (REBCNT )];
149
- REBCNT_To_Bytes (out_size , (REBCNT )in_len );
150
- Append_Series (output , (REBYTE * )out_size , sizeof (REBCNT ));
151
- }
152
155
153
- if (SERIES_AVAIL (output ) > 1024 ) // Is there wasted space?
156
+ if (SERIES_AVAIL (output ) > 4096 ) // Is there wasted space?
154
157
output = Copy_Series (output ); // Trim it down if too big. !!! Revisit this based on mem alloc alg.
155
158
156
159
deflateEnd (& stream );
@@ -171,19 +174,7 @@ void Trap_ZStream_Error(z_stream *stream, int err, REBOOL while_compression)
171
174
REBINT err ;
172
175
173
176
if (len < 0 || (index + len > BIN_LEN (input ))) len = BIN_LEN (input ) - index ;
174
- if (limit > 0 ) {
175
- size = limit ;
176
- } else if (windowBits < 0 ) {
177
- // limit was not specified, but data are supposed to be raw DEFLATE data
178
- // max teoretic DEFLATE ration is 1032:1, but that is quite unrealistic
179
- // it will be more around 3:1 or 4:1, so 10:1 could be enough for automatic setup.
180
- size = 10 * (REBCNT )len ; //@@ fix me, if you don't agree with above claim
181
- } else {
182
- // Get the uncompressed size from last 4 source data bytes.
183
- if (len < 4 ) Trap0 (RE_PAST_END ); // !!! better msg needed
184
- size = cast (REBU64 , Bytes_To_REBCNT (BIN_SKIP (input , index + len ) - sizeof (REBCNT )));
185
- if (size > (uLongf )len * 14 ) Trap_Num (RE_SIZE_LIMIT , size ); // check for a realistic limit
186
- }
177
+ size = (limit > 0 ) ? limit : (uLongf )len * 3 ;
187
178
188
179
output = Make_Binary (size );
189
180
@@ -194,30 +185,40 @@ void Trap_ZStream_Error(z_stream *stream, int err, REBOOL while_compression)
194
185
stream .total_out = 0 ;
195
186
196
187
stream .avail_in = len ;
197
- stream .next_in = cast (const Bytef * , BIN_HEAD (input ) + index );
188
+ stream .next_in = cast (const Bytef * , BIN_SKIP (input , index ) );
198
189
199
190
err = inflateInit2 (& stream , windowBits );
200
191
if (err != Z_OK ) Trap_ZStream_Error (& stream , err , FALSE);
201
192
202
- stream .avail_out = size ;
193
+ stream .avail_out = SERIES_AVAIL ( output ) ;
203
194
stream .next_out = BIN_HEAD (output );
204
195
205
196
for (;;) {
206
197
err = inflate (& stream , Z_NO_FLUSH );
207
- if (err == Z_STREAM_END || stream .total_out == size )
208
- break ; // Finished. (and buffer was big enough)
198
+ if (err == Z_STREAM_END || ( limit && stream .total_out >= limit ) )
199
+ break ; // Finished or we have enough data.
209
200
//printf("err: %i size: %i avail_out: %i total_out: %i\n", err, size, stream.avail_out, stream.total_out);
210
- if (err != Z_OK ) Trap_ZStream_Error (& stream , err , FALSE);
211
- //@@: may need to resize the destination buffer! But...
212
- //@@: so far let's expect that size is always correct
213
- //@@: and introduce self expanding buffers in compression port implementation
201
+ if (err != Z_OK ) Trap_ZStream_Error (& stream , err , FALSE);
202
+ if (stream .avail_out == 0 ) {
203
+ // expand output buffer...
204
+ SERIES_TAIL (output ) = stream .total_out ;
205
+ Expand_Series (output , AT_TAIL , len );
206
+ stream .next_out = BIN_SKIP (output , stream .total_out );
207
+ stream .avail_out = SERIES_REST (output ) - stream .total_out ;
208
+ }
214
209
}
215
210
//printf("total_out: %i\n", stream.total_out);
216
211
inflateEnd (& stream );
217
212
213
+ if (limit && stream .total_out > limit ) {
214
+ stream .total_out = limit ;
215
+ }
218
216
SET_STR_END (output , stream .total_out );
219
217
SERIES_TAIL (output ) = stream .total_out ;
220
218
219
+ if (SERIES_AVAIL (output ) > 4096 ) // Is there wasted space?
220
+ output = Copy_Series (output ); // Trim it down if too big. !!! Revisit this based on mem alloc alg.
221
+
221
222
return output ;
222
223
}
223
224
0 commit comments