@@ -524,6 +524,36 @@ func (b *Buffer) readInt32LE(call goja.FunctionCall) goja.Value {
524
524
return b .r .ToValue (value )
525
525
}
526
526
527
+ // readIntBE reads a big-endian signed integer of variable byte length
528
+ func (b * Buffer ) readIntBE (call goja.FunctionCall ) goja.Value {
529
+ bb := Bytes (b .r , call .This )
530
+ offset , byteLength := b .getVariableLengthReadArguments (call , bb )
531
+
532
+ var value int64
533
+ for i := int64 (0 ); i < byteLength ; i ++ {
534
+ value = (value << 8 ) | int64 (bb [offset + i ])
535
+ }
536
+
537
+ value = signExtend (value , byteLength )
538
+
539
+ return b .r .ToValue (value )
540
+ }
541
+
542
+ // readIntLE reads a little-endian signed integer of variable byte length
543
+ func (b * Buffer ) readIntLE (call goja.FunctionCall ) goja.Value {
544
+ bb := Bytes (b .r , call .This )
545
+ offset , byteLength := b .getVariableLengthReadArguments (call , bb )
546
+
547
+ var value int64
548
+ for i := byteLength - 1 ; i >= 0 ; i -- {
549
+ value = (value << 8 ) | int64 (bb [offset + i ])
550
+ }
551
+
552
+ value = signExtend (value , byteLength )
553
+
554
+ return b .r .ToValue (value )
555
+ }
556
+
527
557
// readUInt8 reads an 8-bit unsigned integer from the buffer
528
558
func (b * Buffer ) readUInt8 (call goja.FunctionCall ) goja.Value {
529
559
bb := Bytes (b .r , call .This )
@@ -569,6 +599,32 @@ func (b *Buffer) readUInt32LE(call goja.FunctionCall) goja.Value {
569
599
return b .r .ToValue (value )
570
600
}
571
601
602
+ // readUIntBE reads a big-endian unsigned integer of variable byte length
603
+ func (b * Buffer ) readUIntBE (call goja.FunctionCall ) goja.Value {
604
+ bb := Bytes (b .r , call .This )
605
+ offset , byteLength := b .getVariableLengthReadArguments (call , bb )
606
+
607
+ var value uint64
608
+ for i := int64 (0 ); i < byteLength ; i ++ {
609
+ value = (value << 8 ) | uint64 (bb [offset + i ])
610
+ }
611
+
612
+ return b .r .ToValue (value )
613
+ }
614
+
615
+ // readUIntLE reads a little-endian unsigned integer of variable byte length
616
+ func (b * Buffer ) readUIntLE (call goja.FunctionCall ) goja.Value {
617
+ bb := Bytes (b .r , call .This )
618
+ offset , byteLength := b .getVariableLengthReadArguments (call , bb )
619
+
620
+ var value uint64
621
+ for i := byteLength - 1 ; i >= 0 ; i -- {
622
+ value = (value << 8 ) | uint64 (bb [offset + i ])
623
+ }
624
+
625
+ return b .r .ToValue (value )
626
+ }
627
+
572
628
func (b * Buffer ) getOffsetArgument (call goja.FunctionCall , argIndex int , bb []byte , numBytes int64 ) int64 {
573
629
arg := call .Argument (argIndex )
574
630
var offset int64
@@ -578,16 +634,56 @@ func (b *Buffer) getOffsetArgument(call goja.FunctionCall, argIndex int, bb []by
578
634
// optional arg that defaults to zero
579
635
offset = 0
580
636
} else {
581
- panic (errors . NewTypeError ( b . r , errors . ErrCodeInvalidArgType , "The \" offset\" argument must be of type number. " ))
637
+ panic (b . newArgumentNotNumberTypeError ( " offset" ))
582
638
}
583
639
584
640
if offset < 0 || offset + numBytes > int64 (len (bb )) {
585
- panic (errors . NewError ( b . r , nil , errors . ErrCodedOutOfRange , "The value of \" offset\" %d is out of range " , offset ))
641
+ panic (b . newArgumentOutOfRangeError ( " offset" , offset ))
586
642
}
587
643
588
644
return offset
589
645
}
590
646
647
+ func (b * Buffer ) getVariableLengthReadArguments (call goja.FunctionCall , bb []byte ) (int64 , int64 ) {
648
+ offset := b .getRequiredIntegerArgument (call , "offset" , 0 )
649
+ byteLength := b .getRequiredIntegerArgument (call , "byteLength" , 1 )
650
+
651
+ if byteLength < 1 || byteLength > 6 {
652
+ panic (b .newArgumentOutOfRangeError ("byteLength" , byteLength ))
653
+ }
654
+ if offset < 0 || offset + byteLength > int64 (len (bb )) {
655
+ panic (b .newArgumentOutOfRangeError ("offset" , offset ))
656
+ }
657
+
658
+ return offset , byteLength
659
+ }
660
+
661
+ func signExtend (value int64 , numBytes int64 ) int64 {
662
+ // we don't have to turn this to a uint64 first because numBytes < 8 so
663
+ // the sign bit will never pushed out of the int64 range
664
+ return (value << (64 - 8 * numBytes )) >> (64 - 8 * numBytes )
665
+ }
666
+
667
+ func (b * Buffer ) getRequiredIntegerArgument (call goja.FunctionCall , name string , argIndex int ) int64 {
668
+ arg := call .Argument (argIndex )
669
+ if isNumber (arg ) {
670
+ return arg .ToInteger ()
671
+ }
672
+ if goja .IsUndefined (arg ) {
673
+ panic (errors .NewTypeError (b .r , errors .ErrCodeInvalidArgType , "The \" %s\" argument is required." , name ))
674
+ }
675
+
676
+ panic (b .newArgumentNotNumberTypeError (name ))
677
+ }
678
+
679
+ func (b * Buffer ) newArgumentNotNumberTypeError (name string ) * goja.Object {
680
+ return errors .NewTypeError (b .r , errors .ErrCodeInvalidArgType , "The \" %s\" argument must be of type number." , name )
681
+ }
682
+
683
+ func (b * Buffer ) newArgumentOutOfRangeError (name string , v int64 ) * goja.Object {
684
+ return errors .NewRangeError (b .r , errors .ErrCodeOutOfRange , "The value of \" %s\" %d is out of range" , name , v )
685
+ }
686
+
591
687
func Require (runtime * goja.Runtime , module * goja.Object ) {
592
688
b := & Buffer {r : runtime }
593
689
uint8Array := runtime .Get ("Uint8Array" )
@@ -612,7 +708,13 @@ func Require(runtime *goja.Runtime, module *goja.Object) {
612
708
proto .Set ("readBigInt64BE" , b .readBigInt64BE )
613
709
proto .Set ("readBigInt64LE" , b .readBigInt64LE )
614
710
proto .Set ("readBigUInt64BE" , b .readBigUInt64BE )
711
+ // aliases for readBigUInt64BE
712
+ proto .Set ("readBigUint64BE" , b .readBigUInt64BE )
713
+
615
714
proto .Set ("readBigUInt64LE" , b .readBigUInt64LE )
715
+ // aliases for readBigUInt64LE
716
+ proto .Set ("readBigUint64LE" , b .readBigUInt64LE )
717
+
616
718
proto .Set ("readDoubleBE" , b .readDoubleBE )
617
719
proto .Set ("readDoubleLE" , b .readDoubleLE )
618
720
proto .Set ("readFloatBE" , b .readFloatBE )
@@ -622,11 +724,35 @@ func Require(runtime *goja.Runtime, module *goja.Object) {
622
724
proto .Set ("readInt16LE" , b .readInt16LE )
623
725
proto .Set ("readInt32BE" , b .readInt32BE )
624
726
proto .Set ("readInt32LE" , b .readInt32LE )
727
+ proto .Set ("readIntBE" , b .readIntBE )
728
+ proto .Set ("readIntLE" , b .readIntLE )
625
729
proto .Set ("readUInt8" , b .readUInt8 )
730
+ // aliases for readUInt8
731
+ proto .Set ("readUint8" , b .readUInt8 )
732
+
626
733
proto .Set ("readUInt16BE" , b .readUInt16BE )
734
+ // aliases for readUInt16BE
735
+ proto .Set ("readUint16BE" , b .readUInt16BE )
736
+
627
737
proto .Set ("readUInt16LE" , b .readUInt16LE )
738
+ // aliases for readUInt16LE
739
+ proto .Set ("readUint16LE" , b .readUInt16LE )
740
+
628
741
proto .Set ("readUInt32BE" , b .readUInt32BE )
742
+ // aliases for readUInt32BE
743
+ proto .Set ("readUint32BE" , b .readUInt32BE )
744
+
629
745
proto .Set ("readUInt32LE" , b .readUInt32LE )
746
+ // aliases for readUInt32LE
747
+ proto .Set ("readUint32LE" , b .readUInt32LE )
748
+
749
+ proto .Set ("readUIntBE" , b .readUIntBE )
750
+ // aliases for readUIntBE
751
+ proto .Set ("readUintBE" , b .readUIntBE )
752
+
753
+ proto .Set ("readUIntLE" , b .readUIntLE )
754
+ // aliases for readUIntLE
755
+ proto .Set ("readUintLE" , b .readUIntLE )
630
756
631
757
ctor .Set ("prototype" , proto )
632
758
ctor .Set ("poolSize" , 8192 )
0 commit comments