99
1010class VarInt extends AbstractType
1111{
12- /**
13- * @var array
14- */
15- private $ sizeInfo = [];
16-
17- /**
18- * @param int $byteOrder
19- */
20- public function __construct (int $ byteOrder = ByteOrder::BE )
21- {
22- parent ::__construct ($ byteOrder );
23- $ two = gmp_init (2 , 10 );
24- $ this ->sizeInfo = [
25- [Uint16::class, gmp_pow ($ two , 16 ), 0xfd ],
26- [Uint32::class, gmp_pow ($ two , 32 ), 0xfe ],
27- [Uint64::class, gmp_pow ($ two , 64 ), 0xff ],
28- ];
29- }
30-
3112 /**
3213 * @param \GMP $integer
3314 * @return array
3415 */
35- public function solveWriteSize (\GMP $ integer ): array
16+ public function solveWriteSize (\GMP $ integer )
3617 {
37- foreach ( $ this -> sizeInfo as $ config ) {
38- list ( $ uint , $ limit , $ prefix ) = $ config ;
39- if (gmp_cmp ($ integer , $ limit ) < 0 ) {
40- return [
41- new $ uint (ByteOrder:: LE ),
42- $ prefix
43- ];
44- }
18+ if ( gmp_cmp ( $ integer , gmp_pow ( gmp_init ( 2 ), 16 )) < 0 ) {
19+ return [ new Uint16 (ByteOrder:: LE ), 0xfd ] ;
20+ } else if (gmp_cmp ($ integer , gmp_pow ( gmp_init ( 2 ), 32 ) ) < 0 ) {
21+ return [new Uint32 (ByteOrder:: LE ), 0xfe ];
22+ } else if ( gmp_cmp ( $ integer , gmp_pow ( gmp_init ( 2 ), 64 )) < 0 ) {
23+ return [ new Uint64 (ByteOrder:: LE ), 0xff ];
24+ } else {
25+ throw new \ InvalidArgumentException ( ' Integer too large, exceeds 64 bit ' );
4526 }
46-
47- throw new \InvalidArgumentException ('Integer too large, exceeds 64 bit ' );
4827 }
4928
5029 /**
51- * @param int $givenPrefix
30+ * @param \GMP $givenPrefix
5231 * @return UintInterface[]
5332 * @throws \InvalidArgumentException
5433 */
55- public function solveReadSize (int $ givenPrefix ): array
34+ public function solveReadSize (\ GMP $ givenPrefix )
5635 {
57- foreach ($ this ->sizeInfo as $ config ) {
58- $ uint = $ config [0 ];
59- $ prefix = $ config [2 ];
60- if ($ givenPrefix === $ prefix ) {
61- return [
62- new $ uint (ByteOrder::LE )
63- ];
64- }
36+ if (gmp_cmp ($ givenPrefix , 0xfd ) === 0 ) {
37+ return [new Uint16 (ByteOrder::LE )];
38+ } else if (gmp_cmp ($ givenPrefix , 0xfe ) === 0 ) {
39+ return [new Uint32 (ByteOrder::LE )];
40+ } else if (gmp_cmp ($ givenPrefix , 0xff ) === 0 ) {
41+ return [new Uint64 (ByteOrder::LE )];
6542 }
6643
67- throw new \InvalidArgumentException ('Integer too large, exceeds 64 bit ' );
44+ throw new \InvalidArgumentException ('Unknown varint prefix ' );
6845 }
6946
7047 /**
@@ -73,35 +50,26 @@ public function solveReadSize(int $givenPrefix): array
7350 */
7451 public function write ($ integer ): string
7552 {
76- $ gmp = gmp_init ($ integer , 10 );
77- $ uint8 = new Uint8 ();
78- if (gmp_cmp ($ gmp , gmp_init (0xfd , 10 )) < 0 ) {
79- $ int = $ uint8 ;
80- } else {
81- list ($ int , $ prefix ) = $ this ->solveWriteSize ($ gmp );
82- $ prefix = gmp_strval ($ prefix , 10 );
53+ $ gmpInt = gmp_init ($ integer , 10 );
54+ if (gmp_cmp ($ gmpInt , gmp_init (0xfd , 10 )) < 0 ) {
55+ return pack ("C " , $ integer );
8356 }
84-
85- $ prefix = isset ($ prefix ) ? $ uint8 ->write ($ prefix ) : '' ;
86- $ bits = $ prefix . $ int ->write ($ integer );
87-
88- return $ bits ;
57+ list ($ int , $ prefix ) = $ this ->solveWriteSize ($ gmpInt );
58+ return pack ("C " , $ prefix ) . $ int ->write ($ integer );
8959 }
9060
9161 /**
9262 * {@inheritdoc}
9363 * @see \BitWasp\Buffertools\Types\TypeInterface::read()
9464 */
95- public function read (Parser $ parser ): string
65+ public function read (Parser $ parser )
9666 {
97- $ uint8 = new Uint8 ();
98- $ int = (int ) $ uint8 ->readBits ($ parser );
99-
100- if ($ int < 0xfd ) {
101- return (string ) $ int ;
102- } else {
103- $ uint = $ this ->solveReadSize ($ int )[0 ];
104- return $ uint ->read ($ parser );
67+ $ byte = unpack ("C " , $ parser ->readBytes (1 )->getBinary ())[1 ];
68+ if (gmp_init ($ byte ) < 0xfd ) {
69+ return $ byte ;
10570 }
71+
72+ list ($ uint ) = $ this ->solveReadSize (gmp_init ($ byte , 10 ));
73+ return $ uint ->read ($ parser );
10674 }
10775}
0 commit comments