<?php require_once __DIR__ . '/StreamReader.php'; class GitPackStream implements StreamReader { private StreamReader $stream; public function __construct( StreamReader $stream ) { $this->stream = $stream; } public function isOpen(): bool { return $this->stream->isOpen(); } public function read( int $length ): string { return $this->stream->read( $length ); } public function write( string $data ): bool { return $this->stream->write( $data ); } public function seek( int $offset, int $whence = SEEK_SET ): bool { return $this->stream->seek( $offset, $whence ); } public function tell(): int { return $this->stream->tell(); } public function eof(): bool { return $this->stream->eof(); } public function rewind(): void { $this->stream->rewind(); } public function readVarInt(): array { $data = $this->stream->read( 12 ); $byte = isset( $data[0] ) ? \ord( $data[0] ) : 0; $val = $byte & 15; $shft = 4; $fst = $byte; $pos = 1; while( $byte & 128 ) { $byte = isset( $data[$pos] ) ? \ord( $data[$pos++] ) : 0; $val |= ($byte & 127) << $shft; $shft += 7; } $rem = \strlen( $data ) - $pos; if( $rem > 0 ) { $this->stream->seek( -$rem, SEEK_CUR ); } return [ 'type' => $fst >> 4 & 7, 'size' => $val ]; } public function readOffsetDelta(): int { $data = $this->stream->read( 12 ); $byte = isset( $data[0] ) ? \ord( $data[0] ) : 0; $result = $byte & 127; $pos = 1; while( $byte & 128 ) { $byte = isset( $data[$pos] ) ? \ord( $data[$pos++] ) : 0; $result = ($result + 1) << 7 | $byte & 127; } $rem = \strlen( $data ) - $pos; if( $rem > 0 ) { $this->stream->seek( -$rem, SEEK_CUR ); } return $result; } }