| Author | Dave Jarvis <email> |
|---|---|
| Date | 2026-02-20 12:42:59 GMT-0800 |
| Commit | 9d8bbef17d0026711140bdca279965133c06feec |
| Parent | d4227e1 |
| +<?php | ||
| +class CompressionStream { | ||
| + private Closure $pumper; | ||
| + private Closure $finisher; | ||
| + private Closure $status; | ||
| + | ||
| + private function __construct( | ||
| + Closure $pumper, | ||
| + Closure $finisher, | ||
| + Closure $status | ||
| + ) { | ||
| + $this->pumper = $pumper; | ||
| + $this->finisher = $finisher; | ||
| + $this->status = $status; | ||
| + } | ||
| + | ||
| + public static function createInflater(): self { | ||
| + $context = inflate_init( ZLIB_ENCODING_DEFLATE ); | ||
| + | ||
| + return new self( | ||
| + function( string $chunk ) use ( $context ): string { | ||
| + $data = @inflate_add( $context, $chunk ); | ||
| + | ||
| + return $data === false ? '' : $data; | ||
| + }, | ||
| + function(): string { | ||
| + return ''; | ||
| + }, | ||
| + function() use ( $context ): bool { | ||
| + return inflate_get_status( $context ) === ZLIB_STREAM_END; | ||
| + } | ||
| + ); | ||
| + } | ||
| + | ||
| + public static function createDeflater(): self { | ||
| + $context = deflate_init( ZLIB_ENCODING_DEFLATE ); | ||
| + | ||
| + return new self( | ||
| + function( string $chunk ) use ( $context ): string { | ||
| + $data = deflate_add( $context, $chunk, ZLIB_NO_FLUSH ); | ||
| + | ||
| + return $data === false ? '' : $data; | ||
| + }, | ||
| + function() use ( $context ): string { | ||
| + $data = deflate_add( $context, '', ZLIB_FINISH ); | ||
| + | ||
| + return $data === false ? '' : $data; | ||
| + }, | ||
| + function(): bool { | ||
| + return false; | ||
| + } | ||
| + ); | ||
| + } | ||
| + | ||
| + public function pump( string $chunk ): string { | ||
| + return $chunk === '' ? '' : ($this->pumper)( $chunk ); | ||
| + } | ||
| + | ||
| + public function finish(): string { | ||
| + return ($this->finisher)(); | ||
| + } | ||
| + | ||
| + public function finished(): bool { | ||
| + return ($this->status)(); | ||
| + } | ||
| +} | ||
| private function streamCompressedObject( string $sha, $ctx ): Generator { | ||
| - $deflate = deflate_init( ZLIB_ENCODING_DEFLATE ); | ||
| - $buffer = ''; | ||
| + $stream = CompressionStream::createDeflater(); | ||
| + $buffer = ''; | ||
| $this->slurp( $sha, function( $chunk ) use ( | ||
| - $deflate, | ||
| + $stream, | ||
| $ctx, | ||
| &$buffer | ||
| ) { | ||
| - $compressed = deflate_add( $deflate, $chunk, ZLIB_NO_FLUSH ); | ||
| + $compressed = $stream->pump( $chunk ); | ||
| if( $compressed !== '' ) { | ||
| hash_update( $ctx, $compressed ); | ||
| $buffer .= $compressed; | ||
| } | ||
| } ); | ||
| - $final = deflate_add( $deflate, '', ZLIB_FINISH ); | ||
| + $final = $stream->finish(); | ||
| if( $final !== '' ) { | ||
| while( $pos < $len ) { | ||
| $chunk = substr( $buffer, $pos, 32768 ); | ||
| + | ||
| yield $chunk; | ||
| - $pos += 32768; | ||
| + $pos += 32768; | ||
| } | ||
| } | ||
| private function streamDecompressionGenerator( $handle ): Generator { | ||
| - $infl = inflate_init( ZLIB_ENCODING_DEFLATE ); | ||
| - | ||
| - if( !$infl ) { | ||
| - return; | ||
| - } | ||
| + $stream = CompressionStream::createInflater(); | ||
| + $done = false; | ||
| - while( !feof( $handle ) ) { | ||
| + while( !$done && !feof( $handle ) ) { | ||
| $chunk = fread( $handle, 8192 ); | ||
| - | ||
| - if( $chunk === '' ) { | ||
| - break; | ||
| - } | ||
| + $done = $chunk === false || $chunk === ''; | ||
| - $data = @inflate_add( $infl, $chunk ); | ||
| + if( !$done ) { | ||
| + $data = $stream->pump( $chunk ); | ||
| - if( $data !== false && $data !== '' ) { | ||
| - yield $data; | ||
| - } | ||
| + if( $data !== '' ) { | ||
| + yield $data; | ||
| + } | ||
| - if( $data === false || | ||
| - inflate_get_status( $infl ) === ZLIB_STREAM_END ) { | ||
| - break; | ||
| + $done = $stream->finished(); | ||
| } | ||
| } |
| Delta | 83 lines added, 23 lines removed, 60-line increase |
|---|