143 [ zip := self readOpenOn:in. |
146 [ zip := self readOpenOn:in. |
144 uncompContents := zip contents. |
147 uncompContents := zip contents. |
145 ] valueNowOrOnUnwindDo:[ zip ifNotNil:[ zip close ] ]. |
148 ] valueNowOrOnUnwindDo:[ zip ifNotNil:[ zip close ] ]. |
146 |
149 |
147 fileContents = uncompContents ifFalse:[ |
150 fileContents = uncompContents ifFalse:[ |
148 self halt:'contents differs'. |
151 self halt:'contents differs'. |
149 ^ self |
152 ^ self |
150 ]. |
153 ]. |
151 Transcript showCR:'uncompressed size: ', fileContents size printString. |
154 Transcript showCR:'uncompressed size: ', fileContents size printString. |
152 Transcript showCR:'compressed size: ', compContents size printString. |
155 Transcript showCR:'compressed size: ', compContents size printString. |
153 |
156 |
154 Transcript showCR:'OK'. |
157 Transcript showCR:'OK'. |
155 |
158 ! |
|
159 |
|
160 testFile |
|
161 " |
|
162 ZipStream testFile |
|
163 " |
|
164 |fileContents in zip out gzipCmd| |
|
165 |
|
166 fileContents := 'smalltalk.rc' asFilename contentsOfEntireFile. |
|
167 |
|
168 in := fileContents readStream. |
|
169 out := FileStream newFileNamed:'YYY.gz'. |
|
170 out ifNil:[ ^ self ]. |
|
171 |
|
172 [ zip := self writeOpenOn:out. |
|
173 |
|
174 [in atEnd] whileFalse:[ |buf| |
|
175 buf := in nextAvailable:512. |
|
176 buf do:[:n| |
|
177 zip nextPut:n |
|
178 ] |
|
179 "/ zip nextPutAll:buf. |
|
180 ]. |
|
181 ] valueNowOrOnUnwindDo:[ |
|
182 zip ifNotNil:[ zip close ]. |
|
183 out close. |
|
184 ]. |
|
185 gzipCmd := 'gzip -dc YYY.gz > YYY; diff YYY smalltalk.rc'. |
|
186 |
|
187 Transcript showCR:gzipCmd. |
|
188 gzipCmd printCR. |
156 ! ! |
189 ! ! |
157 |
190 |
158 !ZipStream methodsFor:'accessing'! |
191 !ZipStream methodsFor:'accessing'! |
159 |
192 |
160 binary |
193 binary |
191 self error:( 'error: ', anErrorOrNumber printString ). |
224 self error:( 'error: ', anErrorOrNumber printString ). |
192 ! ! |
225 ! ! |
193 |
226 |
194 !ZipStream methodsFor:'low level'! |
227 !ZipStream methodsFor:'low level'! |
195 |
228 |
|
229 zFlushInputBuffer |
|
230 %{ |
|
231 OBJ _zstreamObj = __INST( zstream ); |
|
232 |
|
233 if( _zstreamObj != nil ) |
|
234 { |
|
235 zstream_s * _zstream; |
|
236 uInt _inpos; |
|
237 Bytef * _in_ref; |
|
238 |
|
239 _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
240 _inpos = _zstream->in_position; |
|
241 |
|
242 if( _inpos == 0 ) |
|
243 { |
|
244 _zstream->stream.avail_in = 0; |
|
245 _zstream->stream.next_in = Z_NULL; |
|
246 RETURN( self ); |
|
247 } |
|
248 _in_ref = _zstream->in_ref; |
|
249 |
|
250 _zstream->stream.avail_in = _inpos; |
|
251 _zstream->stream.next_in = _in_ref; |
|
252 _zstream->crc_32 = crc32( _zstream->crc_32, _in_ref, _inpos ); |
|
253 } |
|
254 %}. |
|
255 zstream ifNil:[ self errorNotOpen ]. |
|
256 |
|
257 [ |
|
258 self zflush:false. |
|
259 self zdeflate:Z_NO_FLUSH. |
|
260 self zinputAvailable |
|
261 |
|
262 ] whileTrue. |
|
263 ! |
|
264 |
|
265 zFlushOutPutBuffer |
|
266 |errorNo| |
|
267 |
|
268 errorNo := nil. |
|
269 " hitEOF == true ifTrue:[^ 0]. |
|
270 " |
|
271 %{ |
|
272 OBJ _zstreamObj = __INST( zstream ); |
|
273 |
|
274 if( _zstreamObj != nil ) |
|
275 { |
|
276 zstream_s * _zstream; |
|
277 int _errorNo; |
|
278 |
|
279 _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
280 _zstream->out_position = 0; |
|
281 |
|
282 if( _zstream->out_atStreamEnd ) |
|
283 { |
|
284 _zstream->out_limit = 0; |
|
285 __INST(hitEOF) = true; |
|
286 |
|
287 RETURN( __MKSMALLINT (0) ) |
|
288 } |
|
289 _zstream->stream.avail_out = _zstream->out_total; |
|
290 _zstream->stream.next_out = _zstream->out_ref; |
|
291 |
|
292 _errorNo = inflate( & _zstream->stream, Z_NO_FLUSH ); |
|
293 |
|
294 if( _errorNo == Z_STREAM_END ) |
|
295 { |
|
296 _errorNo = inflateEnd( & _zstream->stream ); |
|
297 _zstream->out_atStreamEnd = 1; |
|
298 } |
|
299 if( _errorNo == Z_OK ) |
|
300 { |
|
301 uInt _limit = _zstream->out_total - _zstream->stream.avail_out; |
|
302 |
|
303 _zstream->out_limit = _limit; |
|
304 _zstream->out_position = 0; |
|
305 _zstream->stream.avail_out = 0; |
|
306 _zstream->stream.next_out = Z_NULL; |
|
307 |
|
308 RETURN( __MKSMALLINT (_limit) ); |
|
309 } |
|
310 errorNo = __MKSMALLINT( _errorNo ); |
|
311 } |
|
312 %}. |
|
313 zstream ifNil:[ self errorNotOpen ]. |
|
314 self zerror:errorNo. |
|
315 ! |
|
316 |
|
317 zNextAvailableBytes:count into:inBytes startingAt:start |
|
318 %{ |
|
319 OBJ _zstreamObj = __INST( zstream ); |
|
320 |
|
321 if( (_zstreamObj != nil) && __bothSmallInteger(count, start) ) |
|
322 { |
|
323 char * _bytes; |
|
324 zstream_s * _zstream; |
|
325 int _count, _offs, _capacity; |
|
326 uInt _outpos; |
|
327 uInt _limit; |
|
328 |
|
329 _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
330 |
|
331 _limit = _zstream->out_limit; |
|
332 _outpos = _zstream->out_position; |
|
333 _count = __intVal( count ); |
|
334 |
|
335 if( (_outpos >= _limit) || (_count <= 0) ) |
|
336 RETURN( __MKSMALLINT (0) ); |
|
337 |
|
338 if( (_offs = __intVal (start) - 1) < 0 ) |
|
339 goto bad; |
|
340 |
|
341 if (__isBytes (inBytes)) { |
|
342 _bytes = __ByteArrayInstPtr(inBytes)->ba_element; |
|
343 } else if ( __isString(inBytes) ) { |
|
344 _bytes = __stringVal( inBytes ); |
|
345 } else |
|
346 goto bad; |
|
347 |
|
348 _capacity = (int) _limit - _outpos; |
|
349 |
|
350 if(_count > _capacity ) |
|
351 _count = _capacity; |
|
352 |
|
353 zmemcpy( (Bytef *) & _bytes[_offs], _zstream->out_ref + _outpos, _count ); |
|
354 _zstream->out_position += _count; |
|
355 RETURN( __MKSMALLINT (_count) ); |
|
356 } |
|
357 bad:; |
|
358 %}. |
|
359 zstream ifNil:[ self errorNotOpen ]. |
|
360 self invalidArguments . |
|
361 ! |
|
362 |
|
363 zNextPutByte:aByte |
|
364 %{ |
|
365 OBJ _zstreamObj = __INST( zstream ); |
|
366 |
|
367 if( _zstreamObj != nil ) |
|
368 { |
|
369 zstream_s * _zstream; |
|
370 uInt _inpos; |
|
371 int _theByte; |
|
372 |
|
373 _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
374 _inpos = _zstream->in_position; |
|
375 |
|
376 if( _inpos >= _zstream->in_total ) |
|
377 RETURN( __MKSMALLINT (0) ); |
|
378 |
|
379 _theByte = -1; |
|
380 |
|
381 if( __isCharacter(aByte) ) |
|
382 _theByte = __intVal(__characterVal(aByte)) & 0xFF; |
|
383 else if( __isSmallInteger(aByte) ) |
|
384 { |
|
385 _theByte = __intVal( aByte ); |
|
386 |
|
387 if( (_theByte < 0) || (_theByte > 255) ) |
|
388 goto bad; |
|
389 } |
|
390 else |
|
391 goto bad; |
|
392 |
|
393 _zstream->in_ref[_inpos] = (Byte) _theByte; |
|
394 _zstream->in_position += 1; |
|
395 RETURN( __MKSMALLINT (1) ); |
|
396 } |
|
397 bad:; |
|
398 %}. |
|
399 zstream ifNil:[ self errorNotOpen ]. |
|
400 self invalidArguments. |
|
401 ! |
|
402 |
|
403 zNextPutBytes:count from:inBytes startingAt:start |
|
404 %{ |
|
405 OBJ _zstreamObj = __INST( zstream ); |
|
406 |
|
407 if( (_zstreamObj != nil) && __bothSmallInteger(count, start) ) |
|
408 { |
|
409 int _count, _offs, _bsize; |
|
410 char * _bytes; |
|
411 zstream_s * _zstream; |
|
412 uInt _inpos; |
|
413 uInt _total; |
|
414 |
|
415 _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
416 _inpos = _zstream->in_position; |
|
417 _total = _zstream->in_total; |
|
418 _count = __intVal( count ); |
|
419 |
|
420 if( (_inpos >= _total) || (_count <= 0) ) |
|
421 RETURN( __MKSMALLINT (0) ); |
|
422 |
|
423 if( (_offs = __intVal (start) - 1) < 0 ) |
|
424 goto bad; |
|
425 |
|
426 if (__isBytes (inBytes)) { |
|
427 _bytes = __ByteArrayInstPtr(inBytes)->ba_element; |
|
428 _bsize = __byteArraySize( inBytes ); |
|
429 } |
|
430 else if (__isString(inBytes)) { |
|
431 _bytes = __stringVal ( inBytes ); |
|
432 _bsize = __stringSize( inBytes ); |
|
433 } else |
|
434 goto bad; |
|
435 |
|
436 if( (_count + _offs) < _bsize ) |
|
437 { |
|
438 int _capacity = (int) _total - _inpos; |
|
439 |
|
440 if(_count > _capacity ) |
|
441 _count = _capacity; |
|
442 |
|
443 zmemcpy( _zstream->in_ref + _inpos, (Bytef *) & _bytes[_offs], _count ); |
|
444 _zstream->in_position += _count; |
|
445 RETURN( __MKSMALLINT (_count) ); |
|
446 } |
|
447 } |
|
448 bad:; |
|
449 %}. |
|
450 zstream ifNil:[ self errorNotOpen ]. |
|
451 self invalidArguments. |
|
452 ! |
|
453 |
196 zclose |
454 zclose |
197 |
455 |
198 onStream := nil. |
456 onStream := nil. |
199 hitEOF := true. |
457 hitEOF := true. |
200 zstream ifNil:[^ self]. |
458 zstream ifNil:[^ self]. |
321 %{ |
584 %{ |
322 OBJ _zstreamObj = __INST( zstream ); |
585 OBJ _zstreamObj = __INST( zstream ); |
323 |
586 |
324 if( _zstreamObj != nil ) |
587 if( _zstreamObj != nil ) |
325 { |
588 { |
326 uInt _max, _len; |
589 uInt _max, _len; |
327 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
590 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
328 |
591 |
329 _max = _zstream->out_total; |
592 _max = _zstream->out_total; |
330 _len = _max - _zstream->stream.avail_out; |
593 _len = _max - _zstream->stream.avail_out; |
331 |
594 |
332 if( (_len == 0) || ((forced == false) && (_len != _max)) ) |
595 if( (_len == 0) || ((forced == false) && (_len != _max)) ) |
333 RETURN( __MKSMALLINT(0) ); |
596 RETURN( __MKSMALLINT(0) ); |
334 |
597 |
335 _zstream->stream.avail_out = _max; |
598 _zstream->stream.avail_out = _max; |
336 _zstream->stream.next_out = _zstream->out_ref; |
599 _zstream->stream.next_out = _zstream->out_ref; |
337 |
600 |
338 len = __MKSMALLINT( _len ); |
601 len = __MKSMALLINT( _len ); |
339 } |
602 } |
340 %}. |
603 %}. |
341 zstream ifNil:[ self errorNotOpen ]. |
604 zstream ifNil:[ self errorNotOpen ]. |
342 self onStreamPutBytes:len from:outputBytes. |
605 self onStreamPutBytes:len from:outputBytes. |
343 ! |
606 ! |
344 |
607 |
345 zgetAvailableOutBufferInto:inBytes startingAt:start |
608 zgetCrc32 |
346 |
609 |
347 %{ |
610 %{ |
348 OBJ _zstreamObj = __INST( zstream ); |
611 OBJ _zstreamObj = __INST( zstream ); |
349 |
612 |
350 if( (_zstreamObj != nil) && __isSmallInteger(start) ) |
613 if( _zstreamObj != nil ) |
351 { |
614 { |
352 char * _bytes; |
615 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
353 zstream_s * _zstream; |
616 RETURN ( __MKUINT(_zstream->crc_32) ); |
354 int _count, _offs, _bsize; |
617 } |
355 |
618 %}. |
356 if (__isBytes (inBytes)) { |
619 self errorNotOpen |
357 _bytes = __ByteArrayInstPtr(inBytes)->ba_element; |
620 ! |
358 _bsize = __byteArraySize( inBytes ); |
621 |
359 } else if ( __isString(inBytes) ) { |
622 zgetTotalIn |
360 _bytes = __stringVal( inBytes ); |
623 %{ |
361 _bsize = __stringSize( inBytes ); |
624 OBJ _zstreamObj = __INST( zstream ); |
362 } else |
625 |
363 goto bad; |
626 if( _zstreamObj != nil ) |
364 |
627 { |
365 _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
628 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
366 _count = _zstream->out_used - _zstream->stream.avail_out; |
629 RETURN ( __MKUINT(_zstream->stream.total_in) ); |
367 |
630 } |
368 _zstream->stream.avail_out = _zstream->out_used = 0; |
631 %}. |
369 _zstream->stream.next_out = Z_NULL; |
632 self errorNotOpen |
370 |
633 ! |
371 if( _count < 1 ) { RETURN( __MKSMALLINT(0) ); } |
634 |
372 |
635 zinflateInit |
373 _offs = __intVal( start ) - 1; |
636 |errorNo| |
374 |
637 |
375 if( (_count + _offs) <= _bsize ) |
638 errorNo := nil. |
376 { |
639 |
377 zmemcpy( (Bytef *) & _bytes[_offs], _zstream->out_ref, _count ); |
640 %{ |
378 RETURN ( __MKSMALLINT(_count) ); |
641 OBJ _zstreamObj = __INST( zstream ); |
379 } |
642 |
380 } |
643 if( _zstreamObj != nil ) |
381 bad:; |
644 { |
|
645 int _errorNo; |
|
646 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
647 |
|
648 _errorNo = inflateInit2( & _zstream->stream, -MAX_WBITS ); |
|
649 |
|
650 if( _errorNo == Z_OK ) |
|
651 RETURN( self ); |
|
652 |
|
653 _zstream->stream.avail_in = 0; |
|
654 errorNo = __MKSMALLINT( _errorNo ); |
|
655 } |
|
656 %}. |
|
657 errorNo ifNil:[ self errorNotOpen ]. |
|
658 self zerror:errorNo. |
|
659 ! |
|
660 |
|
661 zinputAvailable |
|
662 %{ |
|
663 OBJ _zstreamObj = __INST( zstream ); |
|
664 |
|
665 if( _zstreamObj != nil ) |
|
666 { |
|
667 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
668 |
|
669 if( _zstream->stream.avail_in != 0 ) |
|
670 RETURN( true ); |
|
671 |
|
672 RETURN( false ); |
|
673 } |
|
674 %}. |
|
675 self errorNotOpen |
|
676 ! |
|
677 |
|
678 zinputPosition:count |
|
679 %{ |
|
680 OBJ _zstreamObj = __INST( zstream ); |
|
681 |
|
682 if( (_zstreamObj != nil) && __isSmallInteger(count) ) |
|
683 { |
|
684 int _count; |
|
685 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
686 |
|
687 _count = __intVal( count ); |
|
688 |
|
689 if( _count < 0 ) |
|
690 { |
|
691 _zstream->stream.next_in = Z_NULL; |
|
692 _count = 0; |
|
693 } |
|
694 else |
|
695 _zstream->stream.next_in = _zstream->in_ref; |
|
696 |
|
697 _zstream->stream.avail_in = _count; |
|
698 RETURN( __MKSMALLINT (_count) ); |
|
699 } |
382 %}. |
700 %}. |
383 zstream ifNil:[ self errorNotOpen ]. |
701 zstream ifNil:[ self errorNotOpen ]. |
384 self invalidArguments . |
702 self invalidArguments . |
385 ! |
|
386 |
|
387 zgetCrc32 |
|
388 |
|
389 %{ |
|
390 OBJ _zstreamObj = __INST( zstream ); |
|
391 |
|
392 if( _zstreamObj != nil ) |
|
393 { |
|
394 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
395 RETURN ( __MKUINT(_zstream->crc_32) ); |
|
396 } |
|
397 %}. |
|
398 self errorNotOpen |
|
399 ! |
|
400 |
|
401 zgetTotalIn |
|
402 %{ |
|
403 OBJ _zstreamObj = __INST( zstream ); |
|
404 |
|
405 if( _zstreamObj != nil ) |
|
406 { |
|
407 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
408 RETURN ( __MKUINT(_zstream->stream.total_in) ); |
|
409 } |
|
410 %}. |
|
411 self errorNotOpen |
|
412 ! |
|
413 |
|
414 zinflate |
|
415 |errorNo| |
|
416 |
|
417 errorNo := nil. |
|
418 |
|
419 %{ |
|
420 OBJ _zstreamObj = __INST( zstream ); |
|
421 |
|
422 if( _zstreamObj != nil ) |
|
423 { |
|
424 int _errorNo; |
|
425 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
426 |
|
427 _errorNo = inflate( & _zstream->stream, Z_NO_FLUSH ); |
|
428 |
|
429 if( _errorNo == Z_STREAM_END ) |
|
430 { |
|
431 __INST(hitEOF) = true; |
|
432 _errorNo = inflateEnd( & _zstream->stream ); |
|
433 } |
|
434 if( _errorNo == Z_OK ) |
|
435 RETURN( self ); |
|
436 |
|
437 errorNo = __MKSMALLINT( _errorNo ); |
|
438 } |
|
439 %}. |
|
440 errorNo ifNil:[ self errorNotOpen ]. |
|
441 self zerror:errorNo. |
|
442 ! |
|
443 |
|
444 zinflateInit |
|
445 |errorNo| |
|
446 |
|
447 errorNo := nil. |
|
448 |
|
449 %{ |
|
450 OBJ _zstreamObj = __INST( zstream ); |
|
451 |
|
452 if( _zstreamObj != nil ) |
|
453 { |
|
454 int _errorNo; |
|
455 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
456 |
|
457 _errorNo = inflateInit2( & _zstream->stream, -MAX_WBITS ); |
|
458 |
|
459 if( _errorNo == Z_OK ) |
|
460 RETURN( self ); |
|
461 |
|
462 errorNo = __MKSMALLINT( _errorNo ); |
|
463 } |
|
464 %}. |
|
465 errorNo ifNil:[ self errorNotOpen ]. |
|
466 self zerror:errorNo. |
|
467 ! |
|
468 zinputAvailable |
|
469 %{ |
|
470 OBJ _zstreamObj = __INST( zstream ); |
|
471 |
|
472 if( _zstreamObj != nil ) |
|
473 { |
|
474 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
475 |
|
476 if( _zstream->stream.avail_in != 0 ) |
|
477 RETURN( true ); |
|
478 |
|
479 RETURN( false ); |
|
480 } |
|
481 %}. |
|
482 self errorNotOpen |
|
483 ! |
|
484 |
|
485 zinputPosition:count |
|
486 %{ |
|
487 OBJ _zstreamObj = __INST( zstream ); |
|
488 |
|
489 if( (_zstreamObj != nil) && __isSmallInteger(count) ) |
|
490 { |
|
491 int _count; |
|
492 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
493 |
|
494 _count = __intVal( count ); |
|
495 |
|
496 if( _count < 0 ) |
|
497 { |
|
498 _zstream->stream.next_in = Z_NULL; |
|
499 _count = 0; |
|
500 } |
|
501 else |
|
502 _zstream->stream.next_in = _zstream->in_ref; |
|
503 |
|
504 _zstream->stream.avail_in = _count; |
|
505 RETURN( __MKSMALLINT (_count) ); |
|
506 } |
|
507 %}. |
|
508 zstream ifNil:[ self errorNotOpen ]. |
|
509 self invalidArguments . |
|
510 ! |
|
511 |
|
512 znextPutBytes:count from:inBytes startingAt:start |
|
513 %{ |
|
514 OBJ _zstreamObj = __INST( zstream ); |
|
515 |
|
516 if( (_zstreamObj != nil) && __bothSmallInteger(count, start) ) |
|
517 { |
|
518 int _count, _offs, _bsize; |
|
519 char * _bytes; |
|
520 Bytef * _in_ref; |
|
521 zstream_s * _zstream; |
|
522 |
|
523 _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
524 _in_ref = _zstream->in_ref; |
|
525 |
|
526 if( (_count = __intVal (count)) <= 0 ) |
|
527 { |
|
528 uInt _b; |
|
529 |
|
530 if( _count < 0 ) goto bad; |
|
531 |
|
532 if( __isCharacter(inBytes) ) |
|
533 _b = __intVal(__characterVal(inBytes)) & 0xFF; |
|
534 else if( __isSmallInteger(inBytes) ) |
|
535 { |
|
536 _b = __intVal( inBytes ); |
|
537 |
|
538 if( (_b < 0) || (_b > 255) ) goto bad; |
|
539 } |
|
540 else |
|
541 { RETURN(__MKSMALLINT (0) ); } |
|
542 |
|
543 _in_ref[0] = (Byte) _b; |
|
544 _zstream->stream.avail_in = 1; |
|
545 _zstream->stream.next_in = _in_ref; |
|
546 _zstream->crc_32 = crc32( _zstream->crc_32, _in_ref, 1 ); |
|
547 |
|
548 RETURN(__MKSMALLINT (1) ); |
|
549 } |
|
550 |
|
551 if( (_offs = __intVal (start) - 1) < 0 ) |
|
552 goto bad; |
|
553 |
|
554 if (__isBytes (inBytes)) { |
|
555 _bytes = __ByteArrayInstPtr(inBytes)->ba_element; |
|
556 _bsize = __byteArraySize( inBytes ); |
|
557 } |
|
558 else if (__isString(inBytes)) { |
|
559 _bytes = __stringVal ( inBytes ); |
|
560 _bsize = __stringSize( inBytes ); |
|
561 } else |
|
562 goto bad; |
|
563 |
|
564 if( (_count + _offs) < _bsize ) |
|
565 { |
|
566 if(_count > _zstream->in_total ) |
|
567 _count = _zstream->in_total; |
|
568 |
|
569 _zstream->stream.avail_in = _count; |
|
570 _zstream->stream.next_in = _in_ref; |
|
571 |
|
572 zmemcpy( _in_ref, (Bytef *) & _bytes[_offs], _count ); |
|
573 _zstream->crc_32 = crc32( _zstream->crc_32, _in_ref, _count ); |
|
574 |
|
575 RETURN( __MKSMALLINT (_count) ); |
|
576 } |
|
577 } |
|
578 bad:; |
|
579 %}. |
|
580 zstream ifNil:[ self errorNotOpen ]. |
|
581 self invalidArguments. |
|
582 ! |
703 ! |
583 |
704 |
584 zopen:aStream |
705 zopen:aStream |
585 |outTotal inTotal| |
706 |outTotal inTotal| |
586 |
707 |
595 %{ |
716 %{ |
596 zstream_s * _zstream = (zstream_s *) malloc( sizeof(zstream_s) ); |
717 zstream_s * _zstream = (zstream_s *) malloc( sizeof(zstream_s) ); |
597 |
718 |
598 if( _zstream ) |
719 if( _zstream ) |
599 { |
720 { |
600 OBJ _zobj = __MKEXTERNALADDRESS( _zstream ); |
721 OBJ _zobj = __MKEXTERNALADDRESS( _zstream ); |
601 OBJ _outObj = __INST( outputBytes ); |
722 OBJ _outObj = __INST( outputBytes ); |
602 OBJ _inpObj = __INST( inputBytes ); |
723 OBJ _inpObj = __INST( inputBytes ); |
603 |
724 |
604 zmemzero( _zstream, sizeof(zstream_s) ); |
725 zmemzero( _zstream, sizeof(zstream_s) ); |
605 |
726 |
606 _zstream->in_total = __intVal( inTotal ); |
727 _zstream->in_total = __intVal( inTotal ); |
607 _zstream->in_ref = (Bytef *) __externalBytesAddress( _inpObj ); |
728 _zstream->in_position = 0; |
608 _zstream->stream.next_in = Z_NULL; |
729 _zstream->in_ref = (Bytef *) __externalBytesAddress( _inpObj ); |
609 _zstream->stream.avail_in = 0; |
730 _zstream->stream.next_in = Z_NULL; |
610 _zstream->stream.total_in = 0; |
731 _zstream->stream.avail_in = 0; |
611 |
732 _zstream->stream.total_in = 0; |
612 _zstream->out_used = 0; |
733 |
613 _zstream->out_total = __intVal( outTotal ); |
734 _zstream->out_position = 0; |
614 _zstream->out_ref = (Bytef *) __externalBytesAddress( _outObj ); |
735 _zstream->out_limit = 0; |
615 _zstream->stream.next_out = _zstream->out_ref; |
736 _zstream->out_atStreamEnd = 0; |
616 _zstream->stream.avail_out = _zstream->out_total; |
737 _zstream->out_total = __intVal( outTotal ); |
617 _zstream->stream.total_out = 0; |
738 _zstream->out_ref = (Bytef *) __externalBytesAddress( _outObj ); |
618 |
739 _zstream->stream.next_out = _zstream->out_ref; |
619 _zstream->stream.zalloc = (alloc_func)0; |
740 _zstream->stream.avail_out = _zstream->out_total; |
620 _zstream->stream.zfree = (free_func) 0; |
741 _zstream->stream.total_out = 0; |
621 _zstream->stream.opaque = (voidpf) 0; |
742 |
622 |
743 _zstream->stream.zalloc = (alloc_func)0; |
623 _zstream->crc_32 = crc32( 0L, Z_NULL, 0 ); |
744 _zstream->stream.zfree = (free_func) 0; |
624 |
745 _zstream->stream.opaque = (voidpf) 0; |
625 __INST (zstream) = _zobj; |
746 |
626 __STORE(self, _zobj); |
747 _zstream->crc_32 = crc32( 0L, Z_NULL, 0 ); |
|
748 |
|
749 __INST (zstream) = _zobj; |
|
750 __STORE(self, _zobj); |
627 } |
751 } |
628 %}. |
752 %}. |
629 zstream ifNil:[ self zerror:'cannot allocate zbuffer' ]. |
753 zstream ifNil:[ self zerror:'cannot allocate zbuffer' ]. |
630 hitEOF := false. |
754 hitEOF := false. |
631 ! |
|
632 |
|
633 zoutputLimit:count |
|
634 %{ |
|
635 OBJ _zstreamObj = __INST( zstream ); |
|
636 |
|
637 if( (_zstreamObj != nil) && __isSmallInteger(count) ) |
|
638 { |
|
639 int _usedSz; |
|
640 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
641 |
|
642 _usedSz = __intVal (count); |
|
643 |
|
644 if( _usedSz > 0 ) |
|
645 { |
|
646 if( _usedSz > _zstream->out_total ) |
|
647 _usedSz = _zstream->out_total; |
|
648 } |
|
649 else |
|
650 _usedSz = 0; |
|
651 |
|
652 _zstream->stream.next_out = _zstream->out_ref; |
|
653 _zstream->stream.avail_out = _zstream->out_used = _usedSz; |
|
654 |
|
655 RETURN( __MKSMALLINT(_usedSz) ); |
|
656 } |
|
657 %}. |
|
658 zstream ifNil:[ self errorNotOpen ]. |
|
659 self invalidArguments . |
|
660 ! |
|
661 |
|
662 zoutputLimitReached |
|
663 "returns true if the write limit is reached; must flush the buffer |
|
664 " |
|
665 %{ |
|
666 OBJ _zstreamObj = __INST( zstream ); |
|
667 |
|
668 if( _zstreamObj != nil ) |
|
669 { |
|
670 zstream_s * _zstream = (zstream_s *) __externalBytesAddress( _zstreamObj ); |
|
671 |
|
672 if( _zstream->stream.avail_out == 0 ) |
|
673 RETURN( true ); |
|
674 |
|
675 RETURN( false ); |
|
676 } |
|
677 %}. |
|
678 self errorNotOpen |
|
679 ! ! |
755 ! ! |
680 |
756 |
681 !ZipStream methodsFor:'private'! |
757 !ZipStream methodsFor:'private'! |
682 |
758 |
683 onStreamPutBytes:count from:data |
759 onStreamPutBytes:count from:data |
713 self isReadOpen ifFalse:[ self pastEnd ]. |
789 self isReadOpen ifFalse:[ self pastEnd ]. |
714 |
790 |
715 "Check the gzip magic id |
791 "Check the gzip magic id |
716 " |
792 " |
717 GZ_MAGIC_ID do:[:b| |
793 GZ_MAGIC_ID do:[:b| |
718 onStream nextByte ~~ b ifTrue:[ self zerror:'version error' ] |
794 onStream nextByte ~~ b ifTrue:[ self zerror:'version error' ] |
719 ]. |
795 ]. |
720 |
796 |
721 method := onStream nextByte. |
797 method := onStream nextByte. |
722 method ~~ Z_DEFLATED ifTrue:[ |
798 method ~~ Z_DEFLATED ifTrue:[ |
723 self zerror:'invalid method (not deflated)' |
799 self zerror:'invalid method (not deflated)' |
724 ]. |
800 ]. |
725 |
801 |
726 flags := onStream nextByte. |
802 flags := onStream nextByte. |
727 (flags bitAnd:HEAD_RESERVED) ~~ 0 ifTrue:[ |
803 (flags bitAnd:HEAD_RESERVED) ~~ 0 ifTrue:[ |
728 self zerror:'wrong data format' |
804 self zerror:'wrong data format' |
729 ]. |
805 ]. |
730 |
806 |
731 "discard time, xflags and OS code |
807 "discard time, xflags and OS code |
732 " |
808 " |
733 onStream skip:6. |
809 onStream skip:6. |
734 |
810 |
735 (flags bitAnd:HEAD_EXTRA_FIELD) ~~ 0 ifTrue:[|len| |
811 (flags bitAnd:HEAD_EXTRA_FIELD) ~~ 0 ifTrue:[|len| |
736 "skip the extra field" |
812 "skip the extra field" |
737 len := onStream nextByte + (onStream nextByte bitShift:8). |
813 len := onStream nextByte + (onStream nextByte bitShift:8). |
738 len timesRepeat:[ onStream nextByte ]. |
814 len timesRepeat:[ onStream nextByte ]. |
739 ]. |
815 ]. |
740 |
816 |
741 (flags bitAnd:HEAD_ORIG_NAME) ~~ 0 ifTrue:[|b| |
817 (flags bitAnd:HEAD_ORIG_NAME) ~~ 0 ifTrue:[|b| |
742 "skip the original file name" |
818 "skip the original file name" |
743 Transcript show:'header name: '. |
819 Transcript show:'header name: '. |
744 [ (b := onStream nextByte) ~~ 0 ] whileTrue:[ |
820 [ (b := onStream nextByte) ~~ 0 ] whileTrue:[ |
745 Transcript show:(Character value:b) |
821 Transcript show:(Character value:b) |
746 ]. |
822 ]. |
747 Transcript cr. |
823 Transcript cr. |
748 ]. |
824 ]. |
749 |
825 |
750 (flags bitAnd:HEAD_CRC) ~~ 0 ifTrue:[ |
826 (flags bitAnd:HEAD_CRC) ~~ 0 ifTrue:[ |
751 "skip the header crc" |
827 "skip the header crc" |
752 onStream skip:2. |
828 onStream skip:2. |
753 ]. |
829 ]. |
754 |
830 |
755 ! |
831 ! |
756 |
832 |
757 writeHeader |
833 writeHeader |
855 |b| |
930 |b| |
856 |
931 |
857 b := self nextByte. |
932 b := self nextByte. |
858 |
933 |
859 b ifNotNil:[ |
934 b ifNotNil:[ |
860 binary ifTrue:[^ b ]. |
935 binary ifTrue:[^ b ]. |
861 ^ Character value:b |
936 ^ Character value:b |
862 ]. |
937 ]. |
863 ^ nil |
938 ^ nil |
864 ! |
939 ! |
865 |
940 |
866 next:count |
941 next:count |
867 ^ self nextAvailable:count |
942 ^ self nextAvailable:count |
868 ! |
943 ! |
|
944 |
869 nextAvailable:count |
945 nextAvailable:count |
870 |n buffer| |
946 |n buffer| |
871 |
947 |
872 self isReadOpen ifFalse:[ self pastEnd ]. |
948 self isReadOpen ifFalse:[ self pastEnd ]. |
873 |
949 |
874 binary ifTrue:[ |
950 binary ifTrue:[ |
875 buffer := ByteArray uninitializedNew:count |
951 buffer := ByteArray uninitializedNew:count |
876 ] ifFalse:[ |
952 ] ifFalse:[ |
877 buffer := String new:count |
953 buffer := String new:count |
878 ]. |
954 ]. |
879 |
955 |
880 n := self nextAvailableBytes:count into:buffer startingAt:1. |
956 n := self nextAvailableBytes:count into:buffer startingAt:1. |
881 |
957 |
882 n == 0 ifTrue:[ |
958 n == 0 ifTrue:[ |
883 binary ifTrue:[ |
959 binary ifTrue:[ |
884 ^ #[] |
960 ^ #[] |
885 ]. |
961 ]. |
886 ^ '' |
962 ^ '' |
887 ]. |
963 ]. |
888 n ~~ count ifTrue:[ ^ buffer copyTo:n ]. |
964 n ~~ count ifTrue:[ ^ buffer copyTo:n ]. |
889 ^ buffer. |
965 ^ buffer. |
890 ! |
966 ! |
891 |
967 |
892 nextAvailableBytes:count into:buffer startingAt:start |
968 nextAvailableBytes:aCount into:inBytes startingAt:start |
893 |eoStream| |
969 |count offs| |
894 |
970 |
895 self isReadOpen ifFalse:[ self pastEnd ]. |
971 self isReadOpen ifFalse:[ self pastEnd ]. |
896 |
972 |
897 (self zoutputLimit:count) < 0 ifTrue:[^ 0]. |
973 count := aCount. |
898 |
974 offs := start. |
899 eoStream := false. |
975 |
900 |
976 [count > 0] whileTrue:[ |n| |
901 [ self atEnd or:[self zoutputLimitReached] ] whileFalse:[ |
977 n := self zNextAvailableBytes:count into:inBytes startingAt:offs. |
902 self zinputAvailable ifFalse:[ |n| |
978 |
903 n := self onStreamReadBytesInto:inputBytes. |
979 n == 0 ifTrue:[ |
904 |
980 n := self zFlushOutPutBuffer. |
905 n == 0 ifTrue:[ |
981 |
906 eoStream ifTrue:[ self pastEnd ]. |
982 n == 0 ifTrue:[ |
907 eoStream := true. |
983 self atEnd ifTrue:[ ^ offs - 1 ]. |
908 ]. |
984 |
909 self zinputPosition:n. |
985 n := self onStreamReadBytesInto:inputBytes. |
910 ]. |
986 n == 0 ifTrue:[ |
911 self zinflate. |
987 self pastEnd |
912 ]. |
988 ]. |
913 ^ self zgetAvailableOutBufferInto:buffer startingAt:start. |
989 self zinputPosition:n. |
|
990 ] |
|
991 ] ifFalse:[ |
|
992 count := count - n. |
|
993 offs := offs + n. |
|
994 ] |
|
995 ]. |
|
996 ^ aCount |
914 ! |
997 ! |
915 |
998 |
916 nextByte |
999 nextByte |
917 |buff size| |
1000 |buff size| |
918 |
1001 |
919 buff := ByteArray new:1. |
1002 buff := ByteArray new:1. |
920 size := self nextAvailableBytes:1 into:buff startingAt:1. |
1003 size := self nextAvailableBytes:1 into:buff startingAt:1. |
921 |
1004 |
922 size ~~ 0 ifTrue:[ |
1005 size ~~ 0 ifTrue:[ |
923 ^ buff at:1 |
1006 ^ buff at:1 |
924 ]. |
1007 ]. |
925 ^ nil |
1008 ^ nil |
926 ! ! |
1009 ! ! |
927 |
1010 |
928 !ZipStream methodsFor:'startup & release'! |
1011 !ZipStream methodsFor:'startup & release'! |
929 |
1012 |
930 close |
1013 close |
931 zstream ifNil:[^ self]. |
1014 zstream ifNil:[^ self]. |
932 |
1015 |
933 self isWriteOpen ifTrue:[ |
1016 self isWriteOpen ifTrue:[ |
934 [ self zflush:true. |
1017 self zFlushInputBuffer. |
935 self zdeflate:Z_FINISH |
1018 |
936 ] whileFalse. |
1019 [ self zflush:true. |
937 |
1020 self zdeflate:Z_FINISH |
938 self zflush:true. |
1021 ] whileFalse. |
939 self zdeflateEnd. |
1022 |
940 |
1023 self zflush:true. |
941 self onStreamPutLong:(self zgetCrc32 ). " write crc " |
1024 self zdeflateEnd. |
942 self onStreamPutLong:(self zgetTotalIn). " write total size " |
1025 |
|
1026 self onStreamPutLong:(self zgetCrc32 ). " write crc " |
|
1027 self onStreamPutLong:(self zgetTotalIn). " write total size " |
943 ]. |
1028 ]. |
944 self zclose. |
1029 self zclose. |
945 ! |
1030 ! |
946 |
1031 |
947 readOpenOn:aStream |
1032 readOpenOn:aStream |
|
1033 |n| |
948 |
1034 |
949 isReadOpen := true. |
1035 isReadOpen := true. |
950 |
1036 |
951 self zopen:aStream. |
1037 self zopen:aStream. |
952 self zinflateInit. |
1038 self zinflateInit. |
953 self readHeader. |
1039 self readHeader. |
|
1040 |
|
1041 n := self onStreamReadBytesInto:inputBytes. |
|
1042 n == 0 ifTrue:[ self pastEnd ]. |
|
1043 self zinputPosition:n. |
954 ! |
1044 ! |
955 |
1045 |
956 writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy |
1046 writeOpenOn:aStream level:level memLevel:memLevel strategy:strategy |
957 |
1047 |
958 isReadOpen := false. |
1048 isReadOpen := false. |
963 ! ! |
1053 ! ! |
964 |
1054 |
965 !ZipStream methodsFor:'writing'! |
1055 !ZipStream methodsFor:'writing'! |
966 |
1056 |
967 flush |
1057 flush |
968 "force flush output |
1058 "flush output buffer |
969 " |
1059 " |
970 self flush:true |
1060 self flush:true |
971 ! |
1061 ! |
972 |
1062 |
973 flush:forced |
1063 flush:forced |
974 |
1064 |
975 self isWriteOpen ifTrue:[ |
1065 self isWriteOpen ifTrue:[ |
976 self zflush:forced |
1066 self zflush:forced |
977 ] ifFalse:[ |
1067 ] ifFalse:[ |
978 onStream ifNil:[self pastEnd] |
1068 onStream ifNil:[self pastEnd] |
979 ]. |
1069 ]. |
980 ! |
1070 ! |
981 |
1071 |
982 nextPut:aCharacter |
1072 nextPut:aCharacter |
983 |count| |
|
984 |
1073 |
985 self isWriteOpen ifFalse:[ self pastEnd ]. |
1074 self isWriteOpen ifFalse:[ self pastEnd ]. |
986 |
1075 |
987 count := self znextPutBytes:0 from:aCharacter startingAt:0. |
1076 [ (self zNextPutByte:aCharacter) == 0 ] whileTrue:[ |
988 |
1077 self zFlushInputBuffer |
989 [ |
1078 ]. |
990 self zflush:false. |
1079 ! |
991 self zdeflate:Z_NO_FLUSH. |
1080 |
992 self zinputAvailable |
1081 nextPutAll:buffer |
993 ] whileTrue. |
1082 self nextPutBytes:(buffer size) from:buffer startingAt:1 |
|
1083 ! |
|
1084 |
|
1085 nextPutAll:aCollection startingAt:start to:stop |
|
1086 self nextPutBytes:(stop - start + 1) from:aCollection startingAt:start |
994 ! |
1087 ! |
995 |
1088 |
996 nextPutByte:aByte |
1089 nextPutByte:aByte |
997 self nextPut:aByte. |
1090 self nextPut:aByte. |
998 ! |
1091 ! |
999 |
1092 |
1000 nextPutAll:buffer |
1093 nextPutBytes:aCount from:inBytes startingAt:start |
1001 |count offset| |
1094 |count offs| |
1002 |
|
1003 count := buffer size. |
|
1004 offset := 1. |
|
1005 |
|
1006 [ count > 0 ] whileTrue:[ |n| |
|
1007 n := self nextPutBytes:count from:buffer startingAt:offset. |
|
1008 offset := offset + n. |
|
1009 count := count - n. |
|
1010 ]. |
|
1011 ! |
|
1012 |
|
1013 nextPutBytes:count from:inBytes startingAt:start |
|
1014 |n| |
|
1015 |
1095 |
1016 self isWriteOpen ifFalse:[ self pastEnd ]. |
1096 self isWriteOpen ifFalse:[ self pastEnd ]. |
1017 |
1097 |
1018 n := self znextPutBytes:count from:inBytes startingAt:start. |
1098 count := aCount. |
1019 |
1099 offs := start. |
1020 n ~~ 0 ifTrue:[ |
1100 |
1021 [ |
1101 [count > 0] whileTrue:[ |n| |
1022 self zflush:false. |
1102 n := self zNextPutBytes:count from:inBytes startingAt:offs. |
1023 self zdeflate:Z_NO_FLUSH. |
1103 |
1024 self zinputAvailable |
1104 n == 0 ifTrue:[ |
1025 ] whileTrue. |
1105 self zFlushInputBuffer |
1026 ]. |
1106 ] ifFalse:[ |
1027 ^ n |
1107 count := count - n. |
|
1108 offs := offs + n. |
|
1109 ] |
|
1110 ]. |
|
1111 ^ aCount |
1028 ! ! |
1112 ! ! |
1029 |
1113 |
1030 !ZipStream class methodsFor:'documentation'! |
1114 !ZipStream class methodsFor:'documentation'! |
1031 |
1115 |
1032 version |
1116 version |
1033 ^ '$Header: /cvs/stx/stx/libbasic2/ZipStream.st,v 1.3 2002-06-19 15:04:58 ca Exp $' |
1117 ^ '$Header: /cvs/stx/stx/libbasic2/ZipStream.st,v 1.4 2002-06-20 08:57:17 ca Exp $' |
1034 ! ! |
1118 ! ! |
|
1119 ZipStream initialize! |