1198 lines
36 KiB
Go
1198 lines
36 KiB
Go
package buffer
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
"encoding/binary"
|
|
"encoding/hex"
|
|
"math"
|
|
"math/big"
|
|
"reflect"
|
|
"strconv"
|
|
|
|
"github.com/dop251/goja"
|
|
"github.com/dop251/goja_nodejs/errors"
|
|
"github.com/dop251/goja_nodejs/goutil"
|
|
"github.com/dop251/goja_nodejs/require"
|
|
|
|
"github.com/dop251/base64dec"
|
|
"golang.org/x/text/encoding/unicode"
|
|
)
|
|
|
|
const ModuleName = "buffer"
|
|
|
|
type Buffer struct {
|
|
r *goja.Runtime
|
|
|
|
bufferCtorObj *goja.Object
|
|
|
|
uint8ArrayCtorObj *goja.Object
|
|
uint8ArrayCtor goja.Constructor
|
|
}
|
|
|
|
var (
|
|
symApi = goja.NewSymbol("api")
|
|
)
|
|
|
|
var (
|
|
reflectTypeArrayBuffer = reflect.TypeOf(goja.ArrayBuffer{})
|
|
reflectTypeString = reflect.TypeOf("")
|
|
reflectTypeInt = reflect.TypeOf(int64(0))
|
|
reflectTypeFloat = reflect.TypeOf(0.0)
|
|
reflectTypeBytes = reflect.TypeOf(([]byte)(nil))
|
|
)
|
|
|
|
func Enable(runtime *goja.Runtime) {
|
|
runtime.Set("Buffer", require.Require(runtime, ModuleName).ToObject(runtime).Get("Buffer"))
|
|
}
|
|
|
|
func Bytes(r *goja.Runtime, v goja.Value) []byte {
|
|
var b []byte
|
|
err := r.ExportTo(v, &b)
|
|
if err != nil {
|
|
return []byte(v.String())
|
|
}
|
|
return b
|
|
}
|
|
|
|
func mod(r *goja.Runtime) *goja.Object {
|
|
res := r.Get("Buffer")
|
|
if res == nil {
|
|
res = require.Require(r, ModuleName).ToObject(r).Get("Buffer")
|
|
}
|
|
m, ok := res.(*goja.Object)
|
|
if !ok {
|
|
panic(r.NewTypeError("Could not extract Buffer"))
|
|
}
|
|
return m
|
|
}
|
|
|
|
func api(mod *goja.Object) *Buffer {
|
|
if s := mod.GetSymbol(symApi); s != nil {
|
|
b, _ := s.Export().(*Buffer)
|
|
return b
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func GetApi(r *goja.Runtime) *Buffer {
|
|
return api(mod(r))
|
|
}
|
|
|
|
func DecodeBytes(r *goja.Runtime, arg, enc goja.Value) []byte {
|
|
switch arg.ExportType() {
|
|
case reflectTypeArrayBuffer:
|
|
return arg.Export().(goja.ArrayBuffer).Bytes()
|
|
case reflectTypeString:
|
|
var codec StringCodec
|
|
if !goja.IsUndefined(enc) {
|
|
codec = stringCodecs[enc.String()]
|
|
}
|
|
if codec == nil {
|
|
codec = utf8Codec
|
|
}
|
|
return codec.DecodeAppend(arg.String(), nil)
|
|
default:
|
|
if o, ok := arg.(*goja.Object); ok {
|
|
if o.ExportType() == reflectTypeBytes {
|
|
return o.Export().([]byte)
|
|
}
|
|
}
|
|
}
|
|
panic(errors.NewTypeError(r, errors.ErrCodeInvalidArgType, "The \"data\" argument must be of type string or an instance of Buffer, TypedArray, or DataView."))
|
|
}
|
|
|
|
func WrapBytes(r *goja.Runtime, data []byte) *goja.Object {
|
|
m := mod(r)
|
|
if api := api(m); api != nil {
|
|
return api.WrapBytes(data)
|
|
}
|
|
if from, ok := goja.AssertFunction(m.Get("from")); ok {
|
|
ab := r.NewArrayBuffer(data)
|
|
v, err := from(m, r.ToValue(ab))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return v.ToObject(r)
|
|
}
|
|
panic(r.NewTypeError("Buffer.from is not a function"))
|
|
}
|
|
|
|
// EncodeBytes returns the given byte slice encoded as string with the given encoding. If encoding
|
|
// is not specified or not supported, returns a Buffer that wraps the data.
|
|
func EncodeBytes(r *goja.Runtime, data []byte, enc goja.Value) goja.Value {
|
|
var codec StringCodec
|
|
if !goja.IsUndefined(enc) {
|
|
codec = StringCodecByName(enc.String())
|
|
}
|
|
if codec != nil {
|
|
return r.ToValue(codec.Encode(data))
|
|
}
|
|
return WrapBytes(r, data)
|
|
}
|
|
|
|
func (b *Buffer) WrapBytes(data []byte) *goja.Object {
|
|
return b.fromBytes(data)
|
|
}
|
|
|
|
func (b *Buffer) ctor(call goja.ConstructorCall) (res *goja.Object) {
|
|
arg := call.Argument(0)
|
|
switch arg.ExportType() {
|
|
case reflectTypeInt, reflectTypeFloat:
|
|
panic(b.r.NewTypeError("Calling the Buffer constructor with numeric argument is not implemented yet"))
|
|
// TODO implement
|
|
}
|
|
return b._from(call.Arguments...)
|
|
}
|
|
|
|
type StringCodec interface {
|
|
DecodeAppend(string, []byte) []byte
|
|
Encode([]byte) string
|
|
Decode(s string) []byte
|
|
}
|
|
|
|
type hexCodec struct{}
|
|
|
|
func (hexCodec) DecodeAppend(s string, b []byte) []byte {
|
|
l := hex.DecodedLen(len(s))
|
|
dst, res := expandSlice(b, l)
|
|
n, err := hex.Decode(dst, []byte(s))
|
|
if err != nil {
|
|
res = res[:len(b)+n]
|
|
}
|
|
return res
|
|
}
|
|
|
|
func (hexCodec) Decode(s string) []byte {
|
|
n, _ := hex.DecodeString(s)
|
|
return n
|
|
}
|
|
func (hexCodec) Encode(b []byte) string {
|
|
return hex.EncodeToString(b)
|
|
}
|
|
|
|
type _utf8Codec struct{}
|
|
|
|
func (c _utf8Codec) DecodeAppend(s string, b []byte) []byte {
|
|
r := c.Decode(s)
|
|
dst, res := expandSlice(b, len(r))
|
|
copy(dst, r)
|
|
return res
|
|
}
|
|
|
|
func (_utf8Codec) Decode(s string) []byte {
|
|
r, _ := unicode.UTF8.NewEncoder().String(s)
|
|
return []byte(r)
|
|
}
|
|
func (_utf8Codec) Encode(b []byte) string {
|
|
r, _ := unicode.UTF8.NewDecoder().Bytes(b)
|
|
return string(r)
|
|
}
|
|
|
|
type base64Codec struct{}
|
|
|
|
type base64UrlCodec struct {
|
|
base64Codec
|
|
}
|
|
|
|
func (base64Codec) DecodeAppend(s string, b []byte) []byte {
|
|
res, _ := Base64DecodeAppend(b, s)
|
|
return res
|
|
}
|
|
|
|
func (base64Codec) Decode(s string) []byte {
|
|
res, _ := base64.StdEncoding.DecodeString(s)
|
|
return res
|
|
}
|
|
func (base64Codec) Encode(b []byte) string {
|
|
return base64.StdEncoding.EncodeToString(b)
|
|
}
|
|
|
|
func (base64UrlCodec) Encode(b []byte) string {
|
|
return base64.RawURLEncoding.EncodeToString(b)
|
|
}
|
|
|
|
var utf8Codec StringCodec = _utf8Codec{}
|
|
|
|
var stringCodecs = map[string]StringCodec{
|
|
"hex": hexCodec{},
|
|
"utf8": utf8Codec,
|
|
"utf-8": utf8Codec,
|
|
"base64": base64Codec{},
|
|
"base64Url": base64UrlCodec{},
|
|
}
|
|
|
|
func expandSlice(b []byte, l int) (dst, res []byte) {
|
|
if cap(b)-len(b) < l {
|
|
b1 := make([]byte, len(b)+l)
|
|
copy(b1, b)
|
|
dst = b1[len(b):]
|
|
res = b1
|
|
} else {
|
|
dst = b[len(b) : len(b)+l]
|
|
res = b[:len(b)+l]
|
|
}
|
|
return
|
|
}
|
|
|
|
func Base64DecodeAppend(dst []byte, src string) ([]byte, error) {
|
|
l := base64.RawStdEncoding.DecodedLen(len(src))
|
|
d, res := expandSlice(dst, l)
|
|
n, err := base64dec.DecodeBase64(d, src)
|
|
|
|
res = res[:len(dst)+n]
|
|
return res, err
|
|
}
|
|
|
|
func (b *Buffer) fromString(str, enc string) *goja.Object {
|
|
codec := stringCodecs[enc]
|
|
if codec == nil {
|
|
codec = utf8Codec
|
|
}
|
|
return b.fromBytes(codec.DecodeAppend(str, nil))
|
|
}
|
|
|
|
func (b *Buffer) fromBytes(data []byte) *goja.Object {
|
|
o, err := b.uint8ArrayCtor(b.bufferCtorObj, b.r.ToValue(b.r.NewArrayBuffer(data)))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return o
|
|
}
|
|
|
|
func (b *Buffer) _from(args ...goja.Value) *goja.Object {
|
|
if len(args) == 0 {
|
|
panic(errors.NewTypeError(b.r, errors.ErrCodeInvalidArgType, "The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined"))
|
|
}
|
|
arg := args[0]
|
|
switch arg.ExportType() {
|
|
case reflectTypeArrayBuffer:
|
|
v, err := b.uint8ArrayCtor(b.bufferCtorObj, args...)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return v
|
|
case reflectTypeString:
|
|
var enc string
|
|
if len(args) > 1 {
|
|
enc = args[1].String()
|
|
}
|
|
return b.fromString(arg.String(), enc)
|
|
default:
|
|
if o, ok := arg.(*goja.Object); ok {
|
|
if o.ExportType() == reflectTypeBytes {
|
|
bb, _ := o.Export().([]byte)
|
|
a := make([]byte, len(bb))
|
|
copy(a, bb)
|
|
return b.fromBytes(a)
|
|
} else {
|
|
if f, ok := goja.AssertFunction(o.Get("valueOf")); ok {
|
|
valueOf, err := f(o)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if valueOf != o {
|
|
args[0] = valueOf
|
|
return b._from(args...)
|
|
}
|
|
}
|
|
|
|
if s := o.GetSymbol(goja.SymToPrimitive); s != nil {
|
|
if f, ok := goja.AssertFunction(s); ok {
|
|
str, err := f(o, b.r.ToValue("string"))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
args[0] = str
|
|
return b._from(args...)
|
|
}
|
|
}
|
|
}
|
|
// array-like
|
|
if v := o.Get("length"); v != nil {
|
|
length := int(v.ToInteger())
|
|
a := make([]byte, length)
|
|
for i := 0; i < length; i++ {
|
|
item := o.Get(strconv.Itoa(i))
|
|
if item != nil {
|
|
a[i] = byte(item.ToInteger())
|
|
}
|
|
}
|
|
return b.fromBytes(a)
|
|
}
|
|
}
|
|
}
|
|
panic(errors.NewTypeError(b.r, errors.ErrCodeInvalidArgType, "The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received %s", arg))
|
|
}
|
|
|
|
func (b *Buffer) from(call goja.FunctionCall) goja.Value {
|
|
return b._from(call.Arguments...)
|
|
}
|
|
|
|
func StringCodecByName(name string) StringCodec {
|
|
return stringCodecs[name]
|
|
}
|
|
|
|
func (b *Buffer) getStringCodec(enc goja.Value) (codec StringCodec) {
|
|
if !goja.IsUndefined(enc) {
|
|
codec = stringCodecs[enc.String()]
|
|
if codec == nil {
|
|
panic(errors.NewTypeError(b.r, "ERR_UNKNOWN_ENCODING", "Unknown encoding: %s", enc))
|
|
}
|
|
} else {
|
|
codec = utf8Codec
|
|
}
|
|
return
|
|
}
|
|
|
|
func (b *Buffer) fill(buf []byte, fill string, enc goja.Value) []byte {
|
|
codec := b.getStringCodec(enc)
|
|
b1 := codec.DecodeAppend(fill, buf[:0])
|
|
if len(b1) > len(buf) {
|
|
return b1[:len(buf)]
|
|
}
|
|
for i := len(b1); i < len(buf); {
|
|
i += copy(buf[i:], buf[:i])
|
|
}
|
|
return buf
|
|
}
|
|
|
|
func (b *Buffer) alloc(call goja.FunctionCall) goja.Value {
|
|
arg0 := call.Argument(0)
|
|
size := -1
|
|
if goja.IsNumber(arg0) {
|
|
size = int(arg0.ToInteger())
|
|
}
|
|
if size < 0 {
|
|
panic(errors.NewArgumentNotNumberTypeError(b.r, "size"))
|
|
}
|
|
fill := call.Argument(1)
|
|
buf := make([]byte, size)
|
|
if !goja.IsUndefined(fill) {
|
|
if goja.IsString(fill) {
|
|
var enc goja.Value
|
|
if a := call.Argument(2); goja.IsString(a) {
|
|
enc = a
|
|
} else {
|
|
enc = goja.Undefined()
|
|
}
|
|
buf = b.fill(buf, fill.String(), enc)
|
|
} else {
|
|
fill = fill.ToNumber()
|
|
if !goja.IsNaN(fill) && !goja.IsInfinity(fill) {
|
|
fillByte := byte(fill.ToInteger())
|
|
if fillByte != 0 {
|
|
for i := range buf {
|
|
buf[i] = fillByte
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return b.fromBytes(buf)
|
|
}
|
|
|
|
func (b *Buffer) proto_toString(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
codec := b.getStringCodec(call.Argument(0))
|
|
start := goutil.CoercedIntegerArgument(call, 1, 0, 0)
|
|
|
|
// Node's Buffer class makes this zero if it is negative
|
|
if start < 0 {
|
|
start = 0
|
|
} else if start >= int64(len(bb)) {
|
|
// returns an empty string if start is beyond the length of the buffer
|
|
return b.r.ToValue("")
|
|
}
|
|
|
|
// NOTE that Node will default to the length of the buffer, but uses 0 for type mismatch defaults
|
|
end := goutil.CoercedIntegerArgument(call, 2, int64(len(bb)), 0)
|
|
if end < 0 || start >= end {
|
|
// returns an empty string if end < 0 or start >= end
|
|
return b.r.ToValue("")
|
|
} else if end > int64(len(bb)) {
|
|
// and Node ensures you don't go past the Buffer
|
|
end = int64(len(bb))
|
|
}
|
|
|
|
return b.r.ToValue(codec.Encode(bb[start:end]))
|
|
}
|
|
|
|
func (b *Buffer) proto_equals(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
other := call.Argument(0)
|
|
if b.r.InstanceOf(other, b.uint8ArrayCtorObj) {
|
|
otherBytes := Bytes(b.r, other)
|
|
return b.r.ToValue(bytes.Equal(bb, otherBytes))
|
|
}
|
|
panic(errors.NewTypeError(b.r, errors.ErrCodeInvalidArgType, "The \"otherBuffer\" argument must be an instance of Buffer or Uint8Array."))
|
|
}
|
|
|
|
// readBigInt64BE reads a big-endian 64-bit signed integer from the buffer
|
|
func (b *Buffer) readBigInt64BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 8)
|
|
value := int64(binary.BigEndian.Uint64(bb[offset : offset+8]))
|
|
|
|
return b.r.ToValue(big.NewInt(value))
|
|
}
|
|
|
|
// readBigInt64LE reads a little-endian 64-bit signed integer from the buffer
|
|
func (b *Buffer) readBigInt64LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 8)
|
|
value := int64(binary.LittleEndian.Uint64(bb[offset : offset+8]))
|
|
|
|
return b.r.ToValue(big.NewInt(value))
|
|
}
|
|
|
|
// readBigUInt64BE reads a big-endian 64-bit unsigned integer from the buffer
|
|
func (b *Buffer) readBigUInt64BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 8)
|
|
value := binary.BigEndian.Uint64(bb[offset : offset+8])
|
|
|
|
return b.r.ToValue(new(big.Int).SetUint64(value))
|
|
}
|
|
|
|
// readBigUInt64LE reads a little-endian 64-bit unsigned integer from the buffer
|
|
func (b *Buffer) readBigUInt64LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 8)
|
|
value := binary.LittleEndian.Uint64(bb[offset : offset+8])
|
|
|
|
return b.r.ToValue(new(big.Int).SetUint64(value))
|
|
}
|
|
|
|
// readDoubleBE reads a big-endian 64-bit floating-point number from the buffer
|
|
func (b *Buffer) readDoubleBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 8)
|
|
value := binary.BigEndian.Uint64(bb[offset : offset+8])
|
|
|
|
return b.r.ToValue(math.Float64frombits(value))
|
|
}
|
|
|
|
// readDoubleLE reads a little-endian 64-bit floating-point number from the buffer
|
|
func (b *Buffer) readDoubleLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 8)
|
|
value := binary.LittleEndian.Uint64(bb[offset : offset+8])
|
|
|
|
return b.r.ToValue(math.Float64frombits(value))
|
|
}
|
|
|
|
// readFloatBE reads a big-endian 32-bit floating-point number from the buffer
|
|
func (b *Buffer) readFloatBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 4)
|
|
value := binary.BigEndian.Uint32(bb[offset : offset+4])
|
|
|
|
return b.r.ToValue(math.Float32frombits(value))
|
|
}
|
|
|
|
// readFloatLE reads a little-endian 32-bit floating-point number from the buffer
|
|
func (b *Buffer) readFloatLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 4)
|
|
value := binary.LittleEndian.Uint32(bb[offset : offset+4])
|
|
|
|
return b.r.ToValue(math.Float32frombits(value))
|
|
}
|
|
|
|
// readInt8 reads an 8-bit signed integer from the buffer
|
|
func (b *Buffer) readInt8(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 1)
|
|
value := int8(bb[offset])
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readInt16BE reads a big-endian 16-bit signed integer from the buffer
|
|
func (b *Buffer) readInt16BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 2)
|
|
value := int16(binary.BigEndian.Uint16(bb[offset : offset+2]))
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readInt16LE reads a little-endian 16-bit signed integer from the buffer
|
|
func (b *Buffer) readInt16LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 2)
|
|
value := int16(binary.LittleEndian.Uint16(bb[offset : offset+2]))
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readInt32BE reads a big-endian 32-bit signed integer from the buffer
|
|
func (b *Buffer) readInt32BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 4)
|
|
value := int32(binary.BigEndian.Uint32(bb[offset : offset+4]))
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readInt32LE reads a little-endian 32-bit signed integer from the buffer
|
|
func (b *Buffer) readInt32LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 4)
|
|
value := int32(binary.LittleEndian.Uint32(bb[offset : offset+4]))
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readIntBE reads a big-endian signed integer of variable byte length
|
|
func (b *Buffer) readIntBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset, byteLength := b.getVariableLengthReadArguments(call, bb)
|
|
|
|
var value int64
|
|
for i := int64(0); i < byteLength; i++ {
|
|
value = (value << 8) | int64(bb[offset+i])
|
|
}
|
|
|
|
value = signExtend(value, byteLength)
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readIntLE reads a little-endian signed integer of variable byte length
|
|
func (b *Buffer) readIntLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset, byteLength := b.getVariableLengthReadArguments(call, bb)
|
|
|
|
var value int64
|
|
for i := byteLength - 1; i >= 0; i-- {
|
|
value = (value << 8) | int64(bb[offset+i])
|
|
}
|
|
|
|
value = signExtend(value, byteLength)
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readUInt8 reads an 8-bit unsigned integer from the buffer
|
|
func (b *Buffer) readUInt8(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 1)
|
|
value := bb[offset]
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readUInt16BE reads a big-endian 16-bit unsigned integer from the buffer
|
|
func (b *Buffer) readUInt16BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 2)
|
|
value := binary.BigEndian.Uint16(bb[offset : offset+2])
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readUInt16LE reads a little-endian 16-bit unsigned integer from the buffer
|
|
func (b *Buffer) readUInt16LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 2)
|
|
value := binary.LittleEndian.Uint16(bb[offset : offset+2])
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readUInt32BE reads a big-endian 32-bit unsigned integer from the buffer
|
|
func (b *Buffer) readUInt32BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 4)
|
|
value := binary.BigEndian.Uint32(bb[offset : offset+4])
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readUInt32LE reads a little-endian 32-bit unsigned integer from the buffer
|
|
func (b *Buffer) readUInt32LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset := b.getOffsetArgument(call, 0, bb, 4)
|
|
value := binary.LittleEndian.Uint32(bb[offset : offset+4])
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readUIntBE reads a big-endian unsigned integer of variable byte length
|
|
func (b *Buffer) readUIntBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset, byteLength := b.getVariableLengthReadArguments(call, bb)
|
|
|
|
var value uint64
|
|
for i := int64(0); i < byteLength; i++ {
|
|
value = (value << 8) | uint64(bb[offset+i])
|
|
}
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// readUIntLE reads a little-endian unsigned integer of variable byte length
|
|
func (b *Buffer) readUIntLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
offset, byteLength := b.getVariableLengthReadArguments(call, bb)
|
|
|
|
var value uint64
|
|
for i := byteLength - 1; i >= 0; i-- {
|
|
value = (value << 8) | uint64(bb[offset+i])
|
|
}
|
|
|
|
return b.r.ToValue(value)
|
|
}
|
|
|
|
// write will write a string to the Buffer at offset according to the character encoding. The length parameter is
|
|
// the number of bytes to write. If buffer did not contain enough space to fit the entire string, only part of string
|
|
// will be written.
|
|
func (b *Buffer) write(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
str := goutil.RequiredStringArgument(b.r, call, "string", 0)
|
|
// note that we are passing in zero for numBytes, since the length parameter, which depends on offset,
|
|
// will dictate the number of bytes
|
|
offset := b.getOffsetArgument(call, 1, bb, 0)
|
|
// the length defaults to the size of the buffer - offset
|
|
maxLength := int64(len(bb)) - offset
|
|
length := goutil.OptionalIntegerArgument(b.r, call, "length", 2, maxLength)
|
|
codec := b.getStringCodec(call.Argument(3))
|
|
|
|
raw := codec.Decode(str)
|
|
if int64(len(raw)) < length {
|
|
// make sure we only write up to raw bytes
|
|
length = int64(len(raw))
|
|
}
|
|
n := copy(bb[offset:], raw[:length])
|
|
return b.r.ToValue(n)
|
|
}
|
|
|
|
// writeBigInt64BE writes a big-endian 64-bit signed integer to the buffer
|
|
func (b *Buffer) writeBigInt64BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredBigIntArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 8)
|
|
|
|
intValue := value.Int64()
|
|
binary.BigEndian.PutUint64(bb[offset:offset+8], uint64(intValue))
|
|
|
|
return b.r.ToValue(offset + 8)
|
|
}
|
|
|
|
// writeBigInt64LE writes a little-endian 64-bit signed integer to the buffer
|
|
func (b *Buffer) writeBigInt64LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredBigIntArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 8)
|
|
|
|
intValue := value.Int64()
|
|
binary.LittleEndian.PutUint64(bb[offset:offset+8], uint64(intValue))
|
|
|
|
return b.r.ToValue(offset + 8)
|
|
}
|
|
|
|
// writeBigUInt64BE writes a big-endian 64-bit unsigned integer to the buffer
|
|
func (b *Buffer) writeBigUInt64BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredBigIntArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 8)
|
|
|
|
uintValue := value.Uint64()
|
|
binary.BigEndian.PutUint64(bb[offset:offset+8], uintValue)
|
|
|
|
return b.r.ToValue(offset + 8)
|
|
}
|
|
|
|
// writeBigUInt64LE writes a little-endian 64-bit unsigned integer to the buffer
|
|
func (b *Buffer) writeBigUInt64LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredBigIntArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 8)
|
|
|
|
uintValue := value.Uint64()
|
|
binary.LittleEndian.PutUint64(bb[offset:offset+8], uintValue)
|
|
|
|
return b.r.ToValue(offset + 8)
|
|
}
|
|
|
|
// writeDoubleBE writes a big-endian 64-bit double to the buffer
|
|
func (b *Buffer) writeDoubleBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredFloatArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 8)
|
|
|
|
bits := math.Float64bits(value)
|
|
binary.BigEndian.PutUint64(bb[offset:offset+8], bits)
|
|
|
|
return b.r.ToValue(offset + 8)
|
|
}
|
|
|
|
// writeDoubleLE writes a little-endian 64-bit double to the buffer
|
|
func (b *Buffer) writeDoubleLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredFloatArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 8)
|
|
|
|
bits := math.Float64bits(value)
|
|
binary.LittleEndian.PutUint64(bb[offset:offset+8], bits)
|
|
|
|
return b.r.ToValue(offset + 8)
|
|
}
|
|
|
|
// writeFloatBE writes a big-endian 32-bit float to the buffer
|
|
func (b *Buffer) writeFloatBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredFloatArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 4)
|
|
|
|
b.ensureWithinFloat32Range(value)
|
|
|
|
bits := math.Float32bits(float32(value))
|
|
binary.BigEndian.PutUint32(bb[offset:offset+4], bits)
|
|
|
|
return b.r.ToValue(offset + 4)
|
|
}
|
|
|
|
// writeFloatLE writes a little-endian 32-bit floating-point number to the buffer
|
|
func (b *Buffer) writeFloatLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredFloatArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 4)
|
|
|
|
b.ensureWithinFloat32Range(value)
|
|
|
|
bits := math.Float32bits(float32(value))
|
|
binary.LittleEndian.PutUint32(bb[offset:offset+4], bits)
|
|
|
|
return b.r.ToValue(offset + 4)
|
|
}
|
|
|
|
// writeInt8 writes an 8-bit signed integer to the buffer
|
|
func (b *Buffer) writeInt8(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 1)
|
|
|
|
if value < math.MinInt8 || value > math.MaxInt8 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
|
|
bb[offset] = byte(int8(value))
|
|
|
|
return b.r.ToValue(offset + 1)
|
|
}
|
|
|
|
// writeInt16BE writes a big-endian 16-bit signed integer to the buffer
|
|
func (b *Buffer) writeInt16BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 2)
|
|
|
|
b.ensureWithinInt16Range(value)
|
|
|
|
binary.BigEndian.PutUint16(bb[offset:offset+2], uint16(value))
|
|
|
|
return b.r.ToValue(offset + 2)
|
|
}
|
|
|
|
// writeInt16LE writes a little-endian 16-bit signed integer to the buffer
|
|
func (b *Buffer) writeInt16LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 2)
|
|
|
|
b.ensureWithinInt16Range(value)
|
|
|
|
binary.LittleEndian.PutUint16(bb[offset:offset+2], uint16(value))
|
|
|
|
return b.r.ToValue(offset + 2)
|
|
}
|
|
|
|
// writeInt32BE writes a big-endian 32-bit signed integer to the buffer
|
|
func (b *Buffer) writeInt32BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 4)
|
|
|
|
b.ensureWithinInt32Range(value)
|
|
|
|
binary.BigEndian.PutUint32(bb[offset:offset+4], uint32(value))
|
|
|
|
return b.r.ToValue(offset + 4)
|
|
}
|
|
|
|
// writeInt32LE writes a little-endian 32-bit signed integer to the buffer
|
|
func (b *Buffer) writeInt32LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 4)
|
|
|
|
b.ensureWithinInt32Range(value)
|
|
|
|
binary.LittleEndian.PutUint32(bb[offset:offset+4], uint32(value))
|
|
|
|
return b.r.ToValue(offset + 4)
|
|
}
|
|
|
|
// writeIntBE writes a big-endian signed integer of variable byte length
|
|
func (b *Buffer) writeIntBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset, byteLength := b.getVariableLengthWriteArguments(call, bb)
|
|
|
|
b.ensureWithinIntRange(byteLength, value)
|
|
|
|
// Write bytes in big-endian order (most significant byte first)
|
|
for i := int64(0); i < byteLength; i++ {
|
|
shift := uint(8 * (byteLength - 1 - i))
|
|
bb[offset+i] = byte(value >> shift)
|
|
}
|
|
|
|
return b.r.ToValue(offset + byteLength)
|
|
}
|
|
|
|
// writeIntLE writes a little-endian signed integer of variable byte length
|
|
func (b *Buffer) writeIntLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset, byteLength := b.getVariableLengthWriteArguments(call, bb)
|
|
|
|
b.ensureWithinIntRange(byteLength, value)
|
|
|
|
// Write bytes in little-endian order
|
|
for i := int64(0); i < byteLength; i++ {
|
|
shift := uint(8 * i)
|
|
bb[offset+i] = byte(value >> shift)
|
|
}
|
|
|
|
return b.r.ToValue(offset + byteLength)
|
|
}
|
|
|
|
// writeUInt8 writes an 8-bit unsigned integer to the buffer
|
|
func (b *Buffer) writeUInt8(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 1)
|
|
|
|
if value < 0 || value > 255 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
|
|
bb[offset] = uint8(value)
|
|
|
|
return b.r.ToValue(offset + 1)
|
|
}
|
|
|
|
// writeUInt16BE writes a big-endian 16-bit unsigned integer to the buffer
|
|
func (b *Buffer) writeUInt16BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 2)
|
|
|
|
b.ensureWithinUInt16Range(value)
|
|
|
|
binary.BigEndian.PutUint16(bb[offset:offset+2], uint16(value))
|
|
|
|
return b.r.ToValue(offset + 2)
|
|
}
|
|
|
|
// writeUInt16LE writes a little-endian 16-bit unsigned integer to the buffer
|
|
func (b *Buffer) writeUInt16LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 2)
|
|
|
|
b.ensureWithinUInt16Range(value)
|
|
|
|
binary.LittleEndian.PutUint16(bb[offset:offset+2], uint16(value))
|
|
|
|
return b.r.ToValue(offset + 2)
|
|
}
|
|
|
|
// writeUInt32BE writes a big-endian 32-bit unsigned integer to the buffer
|
|
func (b *Buffer) writeUInt32BE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 4)
|
|
|
|
b.ensureWithinUInt32Range(value)
|
|
|
|
binary.BigEndian.PutUint32(bb[offset:offset+4], uint32(value))
|
|
|
|
return b.r.ToValue(offset + 4)
|
|
}
|
|
|
|
// writeUInt32LE writes a little-endian 32-bit unsigned integer to the buffer
|
|
func (b *Buffer) writeUInt32LE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset := b.getOffsetArgument(call, 1, bb, 4)
|
|
|
|
b.ensureWithinUInt32Range(value)
|
|
|
|
binary.LittleEndian.PutUint32(bb[offset:offset+4], uint32(value))
|
|
|
|
return b.r.ToValue(offset + 4)
|
|
}
|
|
|
|
// writeUIntBE writes a big-endian unsigned integer of variable byte length
|
|
func (b *Buffer) writeUIntBE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset, byteLength := b.getVariableLengthWriteArguments(call, bb)
|
|
|
|
b.ensureWithinUIntRange(byteLength, value)
|
|
|
|
// Write the bytes in big-endian order (most significant byte first)
|
|
for i := int64(0); i < byteLength; i++ {
|
|
shift := (byteLength - 1 - i) * 8
|
|
bb[offset+i] = byte(value >> shift)
|
|
}
|
|
|
|
return b.r.ToValue(offset + byteLength)
|
|
}
|
|
|
|
// writeUIntLE writes a little-endian unsigned integer of variable byte length
|
|
func (b *Buffer) writeUIntLE(call goja.FunctionCall) goja.Value {
|
|
bb := Bytes(b.r, call.This)
|
|
value := goutil.RequiredIntegerArgument(b.r, call, "value", 0)
|
|
offset, byteLength := b.getVariableLengthWriteArguments(call, bb)
|
|
|
|
b.ensureWithinUIntRange(byteLength, value)
|
|
|
|
// Write the bytes in little-endian order
|
|
for i := int64(0); i < byteLength; i++ {
|
|
shift := uint(8 * i)
|
|
bb[offset+i] = byte(value >> shift)
|
|
}
|
|
|
|
return b.r.ToValue(offset + byteLength)
|
|
}
|
|
|
|
func (b *Buffer) getOffsetArgument(call goja.FunctionCall, argIndex int, bb []byte, numBytes int64) int64 {
|
|
offset := goutil.OptionalIntegerArgument(b.r, call, "offset", argIndex, 0)
|
|
|
|
if offset < 0 || offset+numBytes > int64(len(bb)) {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "offset", offset))
|
|
}
|
|
|
|
return offset
|
|
}
|
|
|
|
func (b *Buffer) getVariableLengthReadArguments(call goja.FunctionCall, bb []byte) (int64, int64) {
|
|
return b.getVariableLengthArguments(call, bb, 0, 1)
|
|
}
|
|
|
|
func (b *Buffer) getVariableLengthWriteArguments(call goja.FunctionCall, bb []byte) (int64, int64) {
|
|
return b.getVariableLengthArguments(call, bb, 1, 2)
|
|
}
|
|
|
|
func (b *Buffer) getVariableLengthArguments(call goja.FunctionCall, bb []byte, offsetArgIndex, byteLengthArgIndex int) (int64, int64) {
|
|
offset := goutil.RequiredIntegerArgument(b.r, call, "offset", offsetArgIndex)
|
|
byteLength := goutil.RequiredIntegerArgument(b.r, call, "byteLength", byteLengthArgIndex)
|
|
|
|
if byteLength < 1 || byteLength > 6 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "byteLength", byteLength))
|
|
}
|
|
if offset < 0 || offset+byteLength > int64(len(bb)) {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "offset", offset))
|
|
}
|
|
|
|
return offset, byteLength
|
|
}
|
|
|
|
func (b *Buffer) ensureWithinFloat32Range(value float64) {
|
|
if value < -math.MaxFloat32 || value > math.MaxFloat32 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
}
|
|
|
|
func (b *Buffer) ensureWithinInt16Range(value int64) {
|
|
if value < math.MinInt16 || value > math.MaxInt16 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
}
|
|
|
|
func (b *Buffer) ensureWithinInt32Range(value int64) {
|
|
if value < math.MinInt32 || value > math.MaxInt32 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
}
|
|
|
|
// ensureWithinIntRange checks to make sure that value is within the integer range
|
|
// defined by the byteLength. Note that byteLength can be at most 6 bytes, so a
|
|
// 48 bit integer is the largest possible value.
|
|
func (b *Buffer) ensureWithinIntRange(byteLength, value int64) {
|
|
// Calculate the valid range for the given byte length
|
|
bits := byteLength * 8
|
|
minValue := -(int64(1) << (bits - 1))
|
|
maxValue := (int64(1) << (bits - 1)) - 1
|
|
|
|
if value < minValue || value > maxValue {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
}
|
|
|
|
func (b *Buffer) ensureWithinUInt16Range(value int64) {
|
|
if value < 0 || value > math.MaxUint16 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
}
|
|
|
|
func (b *Buffer) ensureWithinUInt32Range(value int64) {
|
|
if value < 0 || value > math.MaxUint32 {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
}
|
|
|
|
// ensureWithinUIntRange checks to make sure that value is within the unsigned integer
|
|
// range defined by the byteLength. Note that byteLength can be at most 6 bytes, so a
|
|
// 48 bit unsigned integer is the largest possible value.
|
|
func (b *Buffer) ensureWithinUIntRange(byteLength, value int64) {
|
|
// Validate that the value is within the valid range for the given byteLength
|
|
maxValue := (int64(1) << (8 * byteLength)) - 1
|
|
if value < 0 || value > maxValue {
|
|
panic(errors.NewArgumentOutOfRangeError(b.r, "value", value))
|
|
}
|
|
}
|
|
|
|
func signExtend(value int64, numBytes int64) int64 {
|
|
// we don't have to turn this to a uint64 first because numBytes < 8 so
|
|
// the sign bit will never pushed out of the int64 range
|
|
return (value << (64 - 8*numBytes)) >> (64 - 8*numBytes)
|
|
}
|
|
|
|
func Require(runtime *goja.Runtime, module *goja.Object) {
|
|
b := &Buffer{r: runtime}
|
|
uint8Array := runtime.Get("Uint8Array")
|
|
if c, ok := goja.AssertConstructor(uint8Array); ok {
|
|
b.uint8ArrayCtor = c
|
|
} else {
|
|
panic(runtime.NewTypeError("Uint8Array is not a constructor"))
|
|
}
|
|
uint8ArrayObj := uint8Array.ToObject(runtime)
|
|
|
|
ctor := runtime.ToValue(b.ctor).ToObject(runtime)
|
|
ctor.SetPrototype(uint8ArrayObj)
|
|
ctor.DefineDataPropertySymbol(symApi, runtime.ToValue(b), goja.FLAG_FALSE, goja.FLAG_FALSE, goja.FLAG_FALSE)
|
|
b.bufferCtorObj = ctor
|
|
b.uint8ArrayCtorObj = uint8ArrayObj
|
|
|
|
proto := runtime.NewObject()
|
|
proto.SetPrototype(uint8ArrayObj.Get("prototype").ToObject(runtime))
|
|
proto.DefineDataProperty("constructor", ctor, goja.FLAG_TRUE, goja.FLAG_TRUE, goja.FLAG_FALSE)
|
|
proto.Set("equals", b.proto_equals)
|
|
proto.Set("toString", b.proto_toString)
|
|
proto.Set("readBigInt64BE", b.readBigInt64BE)
|
|
proto.Set("readBigInt64LE", b.readBigInt64LE)
|
|
proto.Set("readBigUInt64BE", b.readBigUInt64BE)
|
|
// aliases for readBigUInt64BE
|
|
proto.Set("readBigUint64BE", b.readBigUInt64BE)
|
|
|
|
proto.Set("readBigUInt64LE", b.readBigUInt64LE)
|
|
// aliases for readBigUInt64LE
|
|
proto.Set("readBigUint64LE", b.readBigUInt64LE)
|
|
|
|
proto.Set("readDoubleBE", b.readDoubleBE)
|
|
proto.Set("readDoubleLE", b.readDoubleLE)
|
|
proto.Set("readFloatBE", b.readFloatBE)
|
|
proto.Set("readFloatLE", b.readFloatLE)
|
|
proto.Set("readInt8", b.readInt8)
|
|
proto.Set("readInt16BE", b.readInt16BE)
|
|
proto.Set("readInt16LE", b.readInt16LE)
|
|
proto.Set("readInt32BE", b.readInt32BE)
|
|
proto.Set("readInt32LE", b.readInt32LE)
|
|
proto.Set("readIntBE", b.readIntBE)
|
|
proto.Set("readIntLE", b.readIntLE)
|
|
proto.Set("readUInt8", b.readUInt8)
|
|
// aliases for readUInt8
|
|
proto.Set("readUint8", b.readUInt8)
|
|
|
|
proto.Set("readUInt16BE", b.readUInt16BE)
|
|
// aliases for readUInt16BE
|
|
proto.Set("readUint16BE", b.readUInt16BE)
|
|
|
|
proto.Set("readUInt16LE", b.readUInt16LE)
|
|
// aliases for readUInt16LE
|
|
proto.Set("readUint16LE", b.readUInt16LE)
|
|
|
|
proto.Set("readUInt32BE", b.readUInt32BE)
|
|
// aliases for readUInt32BE
|
|
proto.Set("readUint32BE", b.readUInt32BE)
|
|
|
|
proto.Set("readUInt32LE", b.readUInt32LE)
|
|
// aliases for readUInt32LE
|
|
proto.Set("readUint32LE", b.readUInt32LE)
|
|
|
|
proto.Set("readUIntBE", b.readUIntBE)
|
|
// aliases for readUIntBE
|
|
proto.Set("readUintBE", b.readUIntBE)
|
|
|
|
proto.Set("readUIntLE", b.readUIntLE)
|
|
// aliases for readUIntLE
|
|
proto.Set("readUintLE", b.readUIntLE)
|
|
proto.Set("write", b.write)
|
|
proto.Set("writeBigInt64BE", b.writeBigInt64BE)
|
|
proto.Set("writeBigInt64LE", b.writeBigInt64LE)
|
|
proto.Set("writeBigUInt64BE", b.writeBigUInt64BE)
|
|
// aliases for writeBigUInt64BE
|
|
proto.Set("writeBigUint64BE", b.writeBigUInt64BE)
|
|
|
|
proto.Set("writeBigUInt64LE", b.writeBigUInt64LE)
|
|
// aliases for writeBigUInt64LE
|
|
proto.Set("writeBigUint64LE", b.writeBigUInt64LE)
|
|
|
|
proto.Set("writeDoubleBE", b.writeDoubleBE)
|
|
proto.Set("writeDoubleLE", b.writeDoubleLE)
|
|
proto.Set("writeFloatBE", b.writeFloatBE)
|
|
proto.Set("writeFloatLE", b.writeFloatLE)
|
|
proto.Set("writeInt8", b.writeInt8)
|
|
proto.Set("writeInt16BE", b.writeInt16BE)
|
|
proto.Set("writeInt16LE", b.writeInt16LE)
|
|
proto.Set("writeInt32BE", b.writeInt32BE)
|
|
proto.Set("writeInt32LE", b.writeInt32LE)
|
|
proto.Set("writeIntBE", b.writeIntBE)
|
|
proto.Set("writeIntLE", b.writeIntLE)
|
|
proto.Set("writeUInt8", b.writeUInt8)
|
|
// aliases for writeUInt8
|
|
proto.Set("writeUint8", b.writeUInt8)
|
|
|
|
proto.Set("writeUInt16BE", b.writeUInt16BE)
|
|
// aliases for writeUInt16BE
|
|
proto.Set("writeUint16BE", b.writeUInt16BE)
|
|
|
|
proto.Set("writeUInt16LE", b.writeUInt16LE)
|
|
// aliases for writeUInt16LE
|
|
proto.Set("writeUint16LE", b.writeUInt16LE)
|
|
|
|
proto.Set("writeUInt32BE", b.writeUInt32BE)
|
|
// aliases for writeUInt32BE
|
|
proto.Set("writeUint32BE", b.writeUInt32BE)
|
|
|
|
proto.Set("writeUInt32LE", b.writeUInt32LE)
|
|
// aliases for writeUInt32LE
|
|
proto.Set("writeUint32LE", b.writeUInt32LE)
|
|
|
|
proto.Set("writeUIntBE", b.writeUIntBE)
|
|
// aliases for writeUIntBE
|
|
proto.Set("writeUintBE", b.writeUIntBE)
|
|
|
|
proto.Set("writeUIntLE", b.writeUIntLE)
|
|
// aliases for writeUIntLE
|
|
proto.Set("writeUintLE", b.writeUIntLE)
|
|
|
|
ctor.Set("prototype", proto)
|
|
ctor.Set("poolSize", 8192)
|
|
ctor.Set("from", b.from)
|
|
ctor.Set("alloc", b.alloc)
|
|
|
|
exports := module.Get("exports").(*goja.Object)
|
|
exports.Set("Buffer", ctor)
|
|
}
|
|
|
|
func init() {
|
|
require.RegisterCoreModule(ModuleName, Require)
|
|
}
|