Comparing version 0.2.0 to 1.0.0
@@ -8,3 +8,3 @@ { | ||
"parserOptions": { | ||
"ecmaVersion": 8 | ||
"ecmaVersion": 9 | ||
}, | ||
@@ -11,0 +11,0 @@ "root": true, |
@@ -9,3 +9,5 @@ /*! | ||
const custom = require('./custom'); | ||
const encoding = require('./encoding'); | ||
const enforce = require('./enforce'); | ||
const EncodingError = require('./error'); | ||
@@ -15,6 +17,5 @@ const BufferReader = require('./reader'); | ||
const StaticWriter = require('./staticwriter'); | ||
const SizeWriter = require('./sizewriter'); | ||
const HashWriter = require('./hashwriter'); | ||
const Struct = require('./struct'); | ||
exports.custom = custom; | ||
exports.encoding = encoding; | ||
@@ -25,4 +26,2 @@ exports.EncodingError = EncodingError; | ||
exports.StaticWriter = StaticWriter; | ||
exports.SizeWriter = SizeWriter; | ||
exports.HashWriter = HashWriter; | ||
exports.Struct = Struct; | ||
@@ -44,14 +43,10 @@ | ||
exports.size = function size(_size) { | ||
return new SizeWriter(_size); | ||
}; | ||
exports.hash = function hash(ctx) { | ||
return new HashWriter(ctx); | ||
}; | ||
function _read(func, size) { | ||
return function(data, off) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
if (off + size > data.length) | ||
throw new EncodingError(off, 'Out of bounds read'); | ||
return func(data, off); | ||
@@ -63,4 +58,9 @@ }; | ||
return function(data, off, len) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
enforce((len >>> 0) === len, 'len', 'integer'); | ||
if (off + len > data.length) | ||
throw new EncodingError(off, 'Out of bounds read'); | ||
return func(data, off, len); | ||
@@ -70,6 +70,18 @@ }; | ||
function _readvar(func) { | ||
return function(data, off) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
return func(data, off); | ||
}; | ||
} | ||
function _write(func, size) { | ||
return function(data, num, off) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
if (off + size > data.length) | ||
throw new EncodingError(off, 'Out of bounds write'); | ||
return func(data, num, off); | ||
@@ -80,6 +92,11 @@ }; | ||
function _writen(func) { | ||
return function(dst, num, off, len) { | ||
if (off + len > dst.length) | ||
return function(data, num, off, len) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
enforce((len >>> 0) === len, 'len', 'integer'); | ||
if (off + len > data.length) | ||
throw new EncodingError(off, 'Out of bounds write'); | ||
return func(dst, num, off, len); | ||
return func(data, num, off, len); | ||
}; | ||
@@ -90,4 +107,8 @@ } | ||
return function(data, num, off) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
if (off + size(num) > data.length) | ||
throw new EncodingError(off, 'Out of bounds write'); | ||
return func(data, num, off); | ||
@@ -183,6 +204,6 @@ }; | ||
exports.readVarint = encoding.readVarint; | ||
exports.readVarint = _readvar(encoding.readVarint); | ||
exports.writeVarint = _writecb(encoding.writeVarint, encoding.sizeVarint); | ||
exports.sizeVarint = encoding.sizeVarint; | ||
exports.readVarint2 = encoding.readVarint2; | ||
exports.readVarint2 = _readvar(encoding.readVarint2); | ||
exports.writeVarint2 = _writecb(encoding.writeVarint2, encoding.sizeVarint2); | ||
@@ -189,0 +210,0 @@ exports.sizeVarint2 = encoding.sizeVarint2; |
@@ -12,2 +12,3 @@ /*! | ||
const enforce = require('./enforce'); | ||
const EncodingError = require('./error'); | ||
@@ -19,12 +20,12 @@ | ||
const HI = 1 / 0x100000000; | ||
const {MAX_SAFE_INTEGER} = Number; | ||
const {floor} = Math; | ||
const float32Array = new Float32Array(1); | ||
const uInt8Float32Array = new Uint8Array(float32Array.buffer); | ||
const float64Array = new Float64Array(1); | ||
const uInt8Float64Array = new Uint8Array(float64Array.buffer); | ||
const F32_ARRAY = new Float32Array(1); | ||
const F328_ARRAY = new Uint8Array(F32_ARRAY.buffer); | ||
const F64_ARRAY = new Float64Array(1); | ||
const F648_ARRAY = new Uint8Array(F64_ARRAY.buffer); | ||
float32Array[0] = -1; | ||
F32_ARRAY[0] = -1; | ||
const bigEndian = uInt8Float32Array[3] === 0; | ||
const BIG_ENDIAN = F328_ARRAY[3] === 0; | ||
@@ -61,3 +62,3 @@ /* | ||
const lo = readU32(data, off); | ||
enforce((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
check((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -69,3 +70,3 @@ } | ||
const lo = readU32(data, off); | ||
enforce((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
check((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -75,45 +76,33 @@ } | ||
function readU48(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 5]; | ||
return first + | ||
data[++off] * 2 ** 8 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 24 + | ||
(data[++off] + last * 2 ** 8) * 2 ** 32; | ||
return (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x1000000 | ||
+ data[off++] * 0x100000000 | ||
+ data[off] * 0x10000000000); | ||
} | ||
function readU40(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 4]; | ||
return first + | ||
data[++off] * 2 ** 8 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 24 + | ||
last * 2 ** 32; | ||
return (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x1000000 | ||
+ data[off] * 0x100000000); | ||
} | ||
function readU32(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 3]; | ||
return first + | ||
data[++off] * 2 ** 8 + | ||
data[++off] * 2 ** 16 + | ||
last * 2 ** 24; | ||
return (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off++] * 0x10000 | ||
+ data[off] * 0x1000000); | ||
} | ||
function readU24(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 2]; | ||
return first + data[++off] * 2 ** 8 + last * 2 ** 16; | ||
return (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off] * 0x10000); | ||
} | ||
function readU16(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 1]; | ||
return first + last * 2 ** 8; | ||
return data[off++] + data[off] * 0x100; | ||
} | ||
@@ -155,3 +144,3 @@ | ||
const lo = readU32BE(data, off + 4); | ||
enforce((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
check((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -163,3 +152,3 @@ } | ||
const lo = readU32BE(data, off + 3); | ||
enforce((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
check((hi & 0xffe00000) === 0, off, 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -169,45 +158,33 @@ } | ||
function readU48BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 5]; | ||
return (first * 2 ** 8 + data[++off]) * 2 ** 32 + | ||
data[++off] * 2 ** 24 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 8 + | ||
last; | ||
return (data[off++] * 0x10000000000 | ||
+ data[off++] * 0x100000000 | ||
+ data[off++] * 0x1000000 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
} | ||
function readU40BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 4]; | ||
return first * 2 ** 32 + | ||
data[++off] * 2 ** 24 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 8 + | ||
last; | ||
return (data[off++] * 0x100000000 | ||
+ data[off++] * 0x1000000 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
} | ||
function readU32BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 3]; | ||
return first * 2 ** 24 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 8 + | ||
last; | ||
return (data[off++] * 0x1000000 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
} | ||
function readU24BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 2]; | ||
return first * 2 ** 16 + data[++off] * 2 ** 8 + last; | ||
return (data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
} | ||
function readU16BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 1]; | ||
return first * 2 ** 8 + last; | ||
return data[off++] * 0x100 + data[off]; | ||
} | ||
@@ -245,3 +222,3 @@ | ||
const lo = readU32(data, off); | ||
enforce(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
check(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -253,3 +230,3 @@ } | ||
const lo = readU32(data, off); | ||
enforce(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
check(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -259,47 +236,36 @@ } | ||
function readI48(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 5]; | ||
const val = data[off + 4] + data[off + 5] * 0x100; | ||
const val = data[off + 4] + last * 2 ** 8; | ||
return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + | ||
first + | ||
data[++off] * 2 ** 8 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 24; | ||
return (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off++] * 0x10000 | ||
+ data[off] * 0x1000000 | ||
+ (val | (val & 0x8000) * 0x1fffe) * 0x100000000); | ||
} | ||
function readI40(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 4]; | ||
return (last | (last & 2 ** 7) * 0x1fffffe) * 2 ** 32 + | ||
first + | ||
data[++off] * 2 ** 8 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 24; | ||
return (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x1000000 | ||
+ (data[off] | (data[off] & 0x80) * 0x1fffffe) * 0x100000000); | ||
} | ||
function readI32(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 3]; | ||
return first + | ||
data[++off] * 2 ** 8 + | ||
data[++off] * 2 ** 16 + | ||
(last << 24); // Overflow | ||
return (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off++] * 0x10000 | ||
+ (data[off] << 24)); | ||
} | ||
function readI24(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 2]; | ||
const val = first + data[++off] * 2 ** 8 + last * 2 ** 16; | ||
return val | (val & 2 ** 23) * 0x1fe; | ||
const val = (data[off++] | ||
+ data[off++] * 0x100 | ||
+ data[off] * 0x10000); | ||
return val | (val & 0x800000) * 0x1fe; | ||
} | ||
function readI16(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 1]; | ||
const val = first + last * 2 ** 8; | ||
return val | (val & 2 ** 15) * 0x1fffe; | ||
const val = data[off++] + data[off] * 0x100; | ||
return val | (val & 0x8000) * 0x1fffe; | ||
} | ||
@@ -309,3 +275,3 @@ | ||
const val = data[off]; | ||
return val | (val & 2 ** 7) * 0x1fffffe; | ||
return val | (val & 0x80) * 0x1fffffe; | ||
} | ||
@@ -343,3 +309,3 @@ | ||
const lo = readU32BE(data, off + 4); | ||
enforce(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
check(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -351,3 +317,3 @@ } | ||
const lo = readU32BE(data, off + 3); | ||
enforce(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
check(isSafe(hi, lo), 'Number exceeds 2^53-1'); | ||
return hi * 0x100000000 + lo; | ||
@@ -357,48 +323,39 @@ } | ||
function readI48BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 5]; | ||
const val = data[off++] * 0x100 + data[off++]; | ||
const val = data[++off] + first * 2 ** 8; | ||
return (val | (val & 2 ** 15) * 0x1fffe) * 2 ** 32 + | ||
data[++off] * 2 ** 24 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 8 + | ||
last; | ||
return ((val | (val & 0x8000) * 0x1fffe) * 0x100000000 | ||
+ data[off++] * 0x1000000 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
} | ||
function readI40BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 4]; | ||
const val = data[off++]; | ||
return (first | (first & 2 ** 7) * 0x1fffffe) * 2 ** 32 + | ||
data[++off] * 2 ** 24 + | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 8 + | ||
last; | ||
return ((val | (val & 0x80) * 0x1fffffe) * 0x100000000 | ||
+ data[off++] * 0x1000000 | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
} | ||
function readI32BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 3]; | ||
return (first << 24) + // Overflow | ||
data[++off] * 2 ** 16 + | ||
data[++off] * 2 ** 8 + | ||
last; | ||
return ((data[off++] << 24) | ||
+ data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
} | ||
function readI24BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 2]; | ||
const val = (data[off++] * 0x10000 | ||
+ data[off++] * 0x100 | ||
+ data[off]); | ||
const val = first * 2 ** 16 + data[++off] * 2 ** 8 + last; | ||
return val | (val & 2 ** 23) * 0x1fe; | ||
return val | (val & 0x800000) * 0x1fe; | ||
} | ||
function readI16BE(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 1]; | ||
const val = first * 2 ** 8 + last; | ||
return val | (val & 2 ** 15) * 0x1fffe; | ||
const val = data[off++] * 0x100 + data[off]; | ||
return val | (val & 0x8000) * 0x1fffe; | ||
} | ||
@@ -411,57 +368,45 @@ | ||
function _readFloatBackwards(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 3]; | ||
uInt8Float32Array[3] = first; | ||
uInt8Float32Array[2] = data[++off]; | ||
uInt8Float32Array[1] = data[++off]; | ||
uInt8Float32Array[0] = last; | ||
return float32Array[0]; | ||
F328_ARRAY[3] = data[off++]; | ||
F328_ARRAY[2] = data[off++]; | ||
F328_ARRAY[1] = data[off++]; | ||
F328_ARRAY[0] = data[off]; | ||
return F32_ARRAY[0]; | ||
} | ||
function _readFloatForwards(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 3]; | ||
uInt8Float32Array[0] = first; | ||
uInt8Float32Array[1] = data[++off]; | ||
uInt8Float32Array[2] = data[++off]; | ||
uInt8Float32Array[3] = last; | ||
return float32Array[0]; | ||
F328_ARRAY[0] = data[off++]; | ||
F328_ARRAY[1] = data[off++]; | ||
F328_ARRAY[2] = data[off++]; | ||
F328_ARRAY[3] = data[off]; | ||
return F32_ARRAY[0]; | ||
} | ||
function _readDoubleBackwards(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 7]; | ||
uInt8Float64Array[7] = first; | ||
uInt8Float64Array[6] = data[++off]; | ||
uInt8Float64Array[5] = data[++off]; | ||
uInt8Float64Array[4] = data[++off]; | ||
uInt8Float64Array[3] = data[++off]; | ||
uInt8Float64Array[2] = data[++off]; | ||
uInt8Float64Array[1] = data[++off]; | ||
uInt8Float64Array[0] = last; | ||
return float64Array[0]; | ||
F648_ARRAY[7] = data[off++]; | ||
F648_ARRAY[6] = data[off++]; | ||
F648_ARRAY[5] = data[off++]; | ||
F648_ARRAY[4] = data[off++]; | ||
F648_ARRAY[3] = data[off++]; | ||
F648_ARRAY[2] = data[off++]; | ||
F648_ARRAY[1] = data[off++]; | ||
F648_ARRAY[0] = data[off]; | ||
return F64_ARRAY[0]; | ||
} | ||
function _readDoubleForwards(data, off) { | ||
const first = data[off]; | ||
const last = data[off + 7]; | ||
uInt8Float64Array[0] = first; | ||
uInt8Float64Array[1] = data[++off]; | ||
uInt8Float64Array[2] = data[++off]; | ||
uInt8Float64Array[3] = data[++off]; | ||
uInt8Float64Array[4] = data[++off]; | ||
uInt8Float64Array[5] = data[++off]; | ||
uInt8Float64Array[6] = data[++off]; | ||
uInt8Float64Array[7] = last; | ||
return float64Array[0]; | ||
F648_ARRAY[0] = data[off++]; | ||
F648_ARRAY[1] = data[off++]; | ||
F648_ARRAY[2] = data[off++]; | ||
F648_ARRAY[3] = data[off++]; | ||
F648_ARRAY[4] = data[off++]; | ||
F648_ARRAY[5] = data[off++]; | ||
F648_ARRAY[6] = data[off++]; | ||
F648_ARRAY[7] = data[off]; | ||
return F64_ARRAY[0]; | ||
} | ||
const readFloat = bigEndian ? _readFloatBackwards : _readFloatForwards; | ||
const readFloatBE = bigEndian ? _readFloatForwards : _readFloatBackwards; | ||
const readDouble = bigEndian ? _readDoubleBackwards : _readDoubleForwards; | ||
const readDoubleBE = bigEndian ? _readDoubleForwards : _readDoubleBackwards; | ||
const readFloat = BIG_ENDIAN ? _readFloatBackwards : _readFloatForwards; | ||
const readFloatBE = BIG_ENDIAN ? _readFloatForwards : _readFloatBackwards; | ||
const readDouble = BIG_ENDIAN ? _readDoubleBackwards : _readDoubleForwards; | ||
const readDoubleBE = BIG_ENDIAN ? _readDoubleForwards : _readDoubleBackwards; | ||
@@ -496,2 +441,3 @@ /* | ||
function writeU64(dst, num, off) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
return write64(dst, num, off, false); | ||
@@ -501,2 +447,3 @@ } | ||
function writeU56(dst, num, off) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
return write56(dst, num, off, false); | ||
@@ -506,14 +453,16 @@ } | ||
function writeU48(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
const newVal = floor(num * 2 ** -32); | ||
const hi = (num * HI) | 0; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
dst[off++] = newVal; | ||
dst[off++] = (newVal >>> 8); | ||
dst[off++] = hi; | ||
dst[off++] = hi >>> 8; | ||
return off; | ||
@@ -523,13 +472,15 @@ } | ||
function writeU40(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
const newVal = num; | ||
const hi = (num * HI) | 0; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
dst[off++] = floor(newVal * 2 ** -32); | ||
dst[off++] = hi; | ||
return off; | ||
@@ -539,10 +490,10 @@ } | ||
function writeU32(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
@@ -553,8 +504,8 @@ return off; | ||
function writeU24(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off++] = num; | ||
@@ -565,6 +516,5 @@ return off; | ||
function writeU16(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off++] = num; | ||
dst[off++] = (num >>> 8); | ||
dst[off++] = num >>> 8; | ||
return off; | ||
@@ -574,3 +524,3 @@ } | ||
function writeU8(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off] = num; | ||
@@ -608,2 +558,3 @@ return off + 1; | ||
function writeU64BE(dst, num, off) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
return write64(dst, num, off, true); | ||
@@ -613,2 +564,3 @@ } | ||
function writeU56BE(dst, num, off) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
return write56(dst, num, off, true); | ||
@@ -618,14 +570,16 @@ } | ||
function writeU48BE(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
const newVal = floor(num * 2 ** -32); | ||
dst[off++] = (newVal >>> 8); | ||
dst[off++] = newVal; | ||
const hi = (num * HI) | 0; | ||
dst[off++] = hi >>> 8; | ||
dst[off++] = hi; | ||
dst[off + 3] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off + 2] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off + 1] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off] = num; | ||
return off + 4; | ||
@@ -635,12 +589,15 @@ } | ||
function writeU40BE(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off++] = floor(num * 2 ** -32); | ||
const hi = (num * HI) | 0; | ||
dst[off++] = hi; | ||
dst[off + 3] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off + 2] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off + 1] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off] = num; | ||
return off + 4; | ||
@@ -650,10 +607,9 @@ } | ||
function writeU32BE(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off + 3] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off + 2] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off + 1] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off] = num; | ||
@@ -664,8 +620,7 @@ return off + 4; | ||
function writeU24BE(dst, num, off) { | ||
num = +num; | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off + 2] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off + 1] = num; | ||
num = num >>> 8; | ||
num >>>= 8; | ||
dst[off] = num; | ||
@@ -676,5 +631,4 @@ return off + 3; | ||
function writeU16BE(dst, num, off) { | ||
num = +num; | ||
dst[off++] = (num >>> 8); | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
dst[off++] = num >>> 8; | ||
dst[off++] = num; | ||
@@ -799,13 +753,12 @@ return off; | ||
function _writeDoubleForwards(dst, num, off) { | ||
num = +num; | ||
float64Array[0] = num; | ||
dst[off++] = uInt8Float64Array[0]; | ||
dst[off++] = uInt8Float64Array[1]; | ||
dst[off++] = uInt8Float64Array[2]; | ||
dst[off++] = uInt8Float64Array[3]; | ||
dst[off++] = uInt8Float64Array[4]; | ||
dst[off++] = uInt8Float64Array[5]; | ||
dst[off++] = uInt8Float64Array[6]; | ||
dst[off++] = uInt8Float64Array[7]; | ||
enforce(isNumber(num), 'num', 'number'); | ||
F64_ARRAY[0] = num; | ||
dst[off++] = F648_ARRAY[0]; | ||
dst[off++] = F648_ARRAY[1]; | ||
dst[off++] = F648_ARRAY[2]; | ||
dst[off++] = F648_ARRAY[3]; | ||
dst[off++] = F648_ARRAY[4]; | ||
dst[off++] = F648_ARRAY[5]; | ||
dst[off++] = F648_ARRAY[6]; | ||
dst[off++] = F648_ARRAY[7]; | ||
return off; | ||
@@ -815,13 +768,12 @@ } | ||
function _writeDoubleBackwards(dst, num, off) { | ||
num = +num; | ||
float64Array[0] = num; | ||
dst[off++] = uInt8Float64Array[7]; | ||
dst[off++] = uInt8Float64Array[6]; | ||
dst[off++] = uInt8Float64Array[5]; | ||
dst[off++] = uInt8Float64Array[4]; | ||
dst[off++] = uInt8Float64Array[3]; | ||
dst[off++] = uInt8Float64Array[2]; | ||
dst[off++] = uInt8Float64Array[1]; | ||
dst[off++] = uInt8Float64Array[0]; | ||
enforce(isNumber(num), 'num', 'number'); | ||
F64_ARRAY[0] = num; | ||
dst[off++] = F648_ARRAY[7]; | ||
dst[off++] = F648_ARRAY[6]; | ||
dst[off++] = F648_ARRAY[5]; | ||
dst[off++] = F648_ARRAY[4]; | ||
dst[off++] = F648_ARRAY[3]; | ||
dst[off++] = F648_ARRAY[2]; | ||
dst[off++] = F648_ARRAY[1]; | ||
dst[off++] = F648_ARRAY[0]; | ||
return off; | ||
@@ -831,9 +783,8 @@ } | ||
function _writeFloatForwards(dst, num, off) { | ||
num = +num; | ||
float32Array[0] = num; | ||
dst[off++] = uInt8Float32Array[0]; | ||
dst[off++] = uInt8Float32Array[1]; | ||
dst[off++] = uInt8Float32Array[2]; | ||
dst[off++] = uInt8Float32Array[3]; | ||
enforce(isNumber(num), 'num', 'number'); | ||
F32_ARRAY[0] = num; | ||
dst[off++] = F328_ARRAY[0]; | ||
dst[off++] = F328_ARRAY[1]; | ||
dst[off++] = F328_ARRAY[2]; | ||
dst[off++] = F328_ARRAY[3]; | ||
return off; | ||
@@ -843,16 +794,15 @@ } | ||
function _writeFloatBackwards(dst, num, off) { | ||
num = +num; | ||
float32Array[0] = num; | ||
dst[off++] = uInt8Float32Array[3]; | ||
dst[off++] = uInt8Float32Array[2]; | ||
dst[off++] = uInt8Float32Array[1]; | ||
dst[off++] = uInt8Float32Array[0]; | ||
enforce(isNumber(num), 'num', 'number'); | ||
F32_ARRAY[0] = num; | ||
dst[off++] = F328_ARRAY[3]; | ||
dst[off++] = F328_ARRAY[2]; | ||
dst[off++] = F328_ARRAY[1]; | ||
dst[off++] = F328_ARRAY[0]; | ||
return off; | ||
} | ||
const writeFloat = bigEndian ? _writeFloatBackwards : _writeFloatForwards; | ||
const writeFloatBE = bigEndian ? _writeFloatForwards : _writeFloatBackwards; | ||
const writeDouble = bigEndian ? _writeDoubleBackwards : _writeDoubleForwards; | ||
const writeDoubleBE = bigEndian ? _writeDoubleForwards : _writeDoubleBackwards; | ||
const writeFloat = BIG_ENDIAN ? _writeFloatBackwards : _writeFloatForwards; | ||
const writeFloatBE = BIG_ENDIAN ? _writeFloatForwards : _writeFloatBackwards; | ||
const writeDouble = BIG_ENDIAN ? _writeDoubleBackwards : _writeDoubleForwards; | ||
const writeDoubleBE = BIG_ENDIAN ? _writeDoubleForwards : _writeDoubleBackwards; | ||
@@ -866,3 +816,3 @@ /* | ||
check(off < data.length, off); | ||
checkRead(off < data.length, off); | ||
@@ -872,17 +822,17 @@ switch (data[off]) { | ||
size = 9; | ||
check(off + size <= data.length, off); | ||
checkRead(off + size <= data.length, off); | ||
value = readU64(data, off + 1); | ||
enforce(value > 0xffffffff, off, 'Non-canonical varint'); | ||
check(value > 0xffffffff, off, 'Non-canonical varint'); | ||
break; | ||
case 0xfe: | ||
size = 5; | ||
check(off + size <= data.length, off); | ||
checkRead(off + size <= data.length, off); | ||
value = readU32(data, off + 1); | ||
enforce(value > 0xffff, off, 'Non-canonical varint'); | ||
check(value > 0xffff, off, 'Non-canonical varint'); | ||
break; | ||
case 0xfd: | ||
size = 3; | ||
check(off + size <= data.length, off); | ||
value = data[off + 1] | (data[off + 2] << 8); | ||
enforce(value >= 0xfd, off, 'Non-canonical varint'); | ||
checkRead(off + size <= data.length, off); | ||
value = readU16(data, off + 1); | ||
check(value >= 0xfd, off, 'Non-canonical varint'); | ||
break; | ||
@@ -899,4 +849,6 @@ default: | ||
function writeVarint(dst, num, off) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
if (num < 0xfd) { | ||
dst[off++] = num & 0xff; | ||
dst[off++] = num; | ||
return off; | ||
@@ -907,5 +859,3 @@ } | ||
dst[off++] = 0xfd; | ||
dst[off++] = num & 0xff; | ||
dst[off++] = (num >> 8) & 0xff; | ||
return off; | ||
return writeU16(dst, num, off); | ||
} | ||
@@ -915,15 +865,12 @@ | ||
dst[off++] = 0xfe; | ||
dst[off++] = num & 0xff; | ||
dst[off++] = (num >> 8) & 0xff; | ||
dst[off++] = (num >> 16) & 0xff; | ||
dst[off++] = num >>> 24; | ||
return off; | ||
return writeU32(dst, num, off); | ||
} | ||
dst[off++] = 0xff; | ||
off = writeU64(dst, num, off); | ||
return off; | ||
return writeU64(dst, num, off); | ||
} | ||
function sizeVarint(num) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
if (num < 0xfd) | ||
@@ -946,3 +893,3 @@ return 1; | ||
for (;;) { | ||
check(off < data.length, off); | ||
checkRead(off < data.length, off); | ||
@@ -953,3 +900,3 @@ const ch = data[off++]; | ||
// Number.MAX_SAFE_INTEGER >>> 7 | ||
enforce(num <= 0x3fffffffffff - (ch & 0x7f), off, 'Number exceeds 2^53-1'); | ||
check(num <= 0x3fffffffffff - (ch & 0x7f), off, 'Number exceeds 2^53-1'); | ||
@@ -962,3 +909,3 @@ // num = (num << 7) | (ch & 0x7f); | ||
enforce(num !== MAX_SAFE_INTEGER, off, 'Number exceeds 2^53-1'); | ||
check(num !== MAX_SAFE_INTEGER, off, 'Number exceeds 2^53-1'); | ||
num += 1; | ||
@@ -971,2 +918,4 @@ } | ||
function writeVarint2(dst, num, off) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
const tmp = []; | ||
@@ -985,3 +934,3 @@ | ||
check(off + len + 1 <= dst.length, off); | ||
checkRead(off + len + 1 <= dst.length, off); | ||
@@ -996,2 +945,4 @@ do { | ||
function sizeVarint2(num) { | ||
enforce(Number.isSafeInteger(num), 'num', 'integer'); | ||
let size = 0; | ||
@@ -1015,2 +966,6 @@ | ||
function sliceBytes(data, off, size) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
if (off + size > data.length) | ||
@@ -1023,2 +978,6 @@ throw new EncodingError(off, 'Out of bounds read'); | ||
function readBytes(data, off, size) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
if (off + size > data.length) | ||
@@ -1033,2 +992,6 @@ throw new EncodingError(off, 'Out of bounds read'); | ||
function writeBytes(data, value, off) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
if (off + value.length > data.length) | ||
@@ -1041,5 +1004,10 @@ throw new EncodingError(off, 'Out of bounds write'); | ||
function readString(data, off, size, enc) { | ||
if (!enc) | ||
enc = 'ascii'; | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
if (off + size > data.length) | ||
@@ -1052,5 +1020,10 @@ throw new EncodingError(off, 'Out of bounds read'); | ||
function writeString(data, str, off, enc) { | ||
if (!enc) | ||
enc = 'ascii'; | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce(typeof str === 'string', 'str', 'string'); | ||
enforce((off >>> 0) === off, 'off', 'integer'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
if (str.length === 0) | ||
@@ -1064,8 +1037,8 @@ return 0; | ||
data.write(str, off, enc); | ||
return size; | ||
return data.write(str, off, enc); | ||
} | ||
function realloc(data, size) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
const buf = Buffer.allocUnsafe(size); | ||
@@ -1077,2 +1050,3 @@ data.copy(buf, 0); | ||
function copy(data) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
return realloc(data, data.length); | ||
@@ -1082,6 +1056,11 @@ } | ||
function concat(a, b) { | ||
enforce(Buffer.isBuffer(a), 'a', 'buffer'); | ||
enforce(Buffer.isBuffer(b), 'b', 'buffer'); | ||
const size = a.length + b.length; | ||
const buf = Buffer.allocUnsafe(size); | ||
a.copy(buf, 0); | ||
b.copy(buf, a.length); | ||
return buf; | ||
@@ -1095,2 +1074,3 @@ } | ||
function sizeVarBytes(data) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
return sizeVarint(data.length) + data.length; | ||
@@ -1104,5 +1084,11 @@ } | ||
function sizeVarString(str, enc) { | ||
if (typeof str !== 'string') | ||
return sizeVarBytes(str); | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(typeof str === 'string', 'str', 'string'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
if (str.length === 0) | ||
return 1; | ||
const len = Buffer.byteLength(str, enc); | ||
@@ -1135,3 +1121,3 @@ | ||
let hi = (num * (1 / 0x100000000)) | 0; | ||
let hi = (num * HI) | 0; | ||
let lo = num | 0; | ||
@@ -1167,3 +1153,3 @@ | ||
let hi = (num * (1 / 0x100000000)) | 0; | ||
let hi = (num * HI) | 0; | ||
let lo = num | 0; | ||
@@ -1198,10 +1184,14 @@ | ||
function check(value, offset) { | ||
function isNumber(num) { | ||
return typeof num === 'number' && isFinite(num); | ||
} | ||
function checkRead(value, offset) { | ||
if (!value) | ||
throw new EncodingError(offset, 'Out of bounds read', check); | ||
throw new EncodingError(offset, 'Out of bounds read', checkRead); | ||
} | ||
function enforce(value, offset, reason) { | ||
function check(value, offset, reason) { | ||
if (!value) | ||
throw new EncodingError(offset, reason, enforce); | ||
throw new EncodingError(offset, reason, check); | ||
} | ||
@@ -1208,0 +1198,0 @@ |
@@ -27,2 +27,4 @@ /*! | ||
this.type = 'EncodingError'; | ||
this.name = 'EncodingError'; | ||
this.code = 'ERR_ENCODING'; | ||
this.message = `${reason} (offset=${offset}).`; | ||
@@ -29,0 +31,0 @@ |
@@ -10,3 +10,3 @@ /*! | ||
const assert = require('assert'); | ||
const enforce = require('./enforce'); | ||
const encoding = require('./encoding'); | ||
@@ -35,8 +35,9 @@ const EncodingError = require('./error'); | ||
constructor(data, zeroCopy) { | ||
assert(Buffer.isBuffer(data), 'Must pass a Buffer.'); | ||
constructor(data, zeroCopy = false) { | ||
enforce(Buffer.isBuffer(data), 'data', 'buffer'); | ||
enforce(typeof zeroCopy === 'boolean', 'zeroCopy', 'boolean'); | ||
this.data = data; | ||
this.offset = 0; | ||
this.zeroCopy = zeroCopy || false; | ||
this.zeroCopy = zeroCopy; | ||
this.stack = []; | ||
@@ -47,22 +48,11 @@ } | ||
* Assertion. | ||
* @param {Boolean} value | ||
* @param {Number} size | ||
*/ | ||
assert(value) { | ||
if (!value) | ||
throw new EncodingError(this.offset, 'Out of bounds read', this.assert); | ||
check(size) { | ||
if (this.offset + size > this.data.length) | ||
throw new EncodingError(this.offset, 'Out of bounds read', this.check); | ||
} | ||
/** | ||
* Assertion. | ||
* @param {Boolean} value | ||
* @param {String} reason | ||
*/ | ||
enforce(value, reason) { | ||
if (!value) | ||
throw new EncodingError(this.offset, reason, this.enforce); | ||
} | ||
/** | ||
* Get total size of passed-in Buffer. | ||
@@ -82,3 +72,3 @@ * @returns {Buffer} | ||
left() { | ||
this.assert(this.offset <= this.data.length); | ||
this.check(0); | ||
return this.data.length - this.offset; | ||
@@ -93,5 +83,10 @@ } | ||
seek(off) { | ||
this.assert(this.offset + off >= 0); | ||
this.assert(this.offset + off <= this.data.length); | ||
enforce(Number.isSafeInteger(off), 'off', 'integer'); | ||
if (this.offset + off < 0) | ||
throw new EncodingError(this.offset, 'Out of bounds read'); | ||
this.check(off); | ||
this.offset += off; | ||
return this; | ||
@@ -117,3 +112,4 @@ } | ||
end() { | ||
assert(this.stack.length > 0); | ||
if (this.stack.length === 0) | ||
throw new Error('Cannot end without a stack item.'); | ||
@@ -135,5 +131,8 @@ const start = this.stack.pop(); | ||
endData(zeroCopy) { | ||
assert(this.stack.length > 0); | ||
endData(zeroCopy = false) { | ||
enforce(typeof zeroCopy === 'boolean', 'zeroCopy', 'boolean'); | ||
if (this.stack.length === 0) | ||
throw new Error('Cannot end without a stack item.'); | ||
const start = this.stack.pop(); | ||
@@ -173,3 +172,3 @@ const end = this.offset; | ||
readU8() { | ||
this.assert(this.offset + 1 <= this.data.length); | ||
this.check(1); | ||
const ret = this.data[this.offset]; | ||
@@ -186,3 +185,3 @@ this.offset += 1; | ||
readU16() { | ||
this.assert(this.offset + 2 <= this.data.length); | ||
this.check(2); | ||
const ret = encoding.readU16(this.data, this.offset); | ||
@@ -199,3 +198,3 @@ this.offset += 2; | ||
readU16BE() { | ||
this.assert(this.offset + 2 <= this.data.length); | ||
this.check(2); | ||
const ret = encoding.readU16BE(this.data, this.offset); | ||
@@ -207,2 +206,26 @@ this.offset += 2; | ||
/** | ||
* Read uint24le. | ||
* @returns {Number} | ||
*/ | ||
readU24() { | ||
this.check(3); | ||
const ret = encoding.readU24(this.data, this.offset); | ||
this.offset += 3; | ||
return ret; | ||
} | ||
/** | ||
* Read uint24be. | ||
* @returns {Number} | ||
*/ | ||
readU24BE() { | ||
this.check(3); | ||
const ret = encoding.readU24BE(this.data, this.offset); | ||
this.offset += 3; | ||
return ret; | ||
} | ||
/** | ||
* Read uint32le. | ||
@@ -213,3 +236,3 @@ * @returns {Number} | ||
readU32() { | ||
this.assert(this.offset + 4 <= this.data.length); | ||
this.check(4); | ||
const ret = encoding.readU32(this.data, this.offset); | ||
@@ -226,3 +249,3 @@ this.offset += 4; | ||
readU32BE() { | ||
this.assert(this.offset + 4 <= this.data.length); | ||
this.check(4); | ||
const ret = encoding.readU32BE(this.data, this.offset); | ||
@@ -234,2 +257,74 @@ this.offset += 4; | ||
/** | ||
* Read uint40le. | ||
* @returns {Number} | ||
*/ | ||
readU40() { | ||
this.check(5); | ||
const ret = encoding.readU40(this.data, this.offset); | ||
this.offset += 5; | ||
return ret; | ||
} | ||
/** | ||
* Read uint40be. | ||
* @returns {Number} | ||
*/ | ||
readU40BE() { | ||
this.check(5); | ||
const ret = encoding.readU40BE(this.data, this.offset); | ||
this.offset += 5; | ||
return ret; | ||
} | ||
/** | ||
* Read uint48le. | ||
* @returns {Number} | ||
*/ | ||
readU48() { | ||
this.check(6); | ||
const ret = encoding.readU48(this.data, this.offset); | ||
this.offset += 6; | ||
return ret; | ||
} | ||
/** | ||
* Read uint48be. | ||
* @returns {Number} | ||
*/ | ||
readU48BE() { | ||
this.check(6); | ||
const ret = encoding.readU48BE(this.data, this.offset); | ||
this.offset += 6; | ||
return ret; | ||
} | ||
/** | ||
* Read uint56le. | ||
* @returns {Number} | ||
*/ | ||
readU56() { | ||
this.check(7); | ||
const ret = encoding.readU56(this.data, this.offset); | ||
this.offset += 7; | ||
return ret; | ||
} | ||
/** | ||
* Read uint56be. | ||
* @returns {Number} | ||
*/ | ||
readU56BE() { | ||
this.check(7); | ||
const ret = encoding.readU56BE(this.data, this.offset); | ||
this.offset += 7; | ||
return ret; | ||
} | ||
/** | ||
* Read uint64le as a js number. | ||
@@ -241,3 +336,3 @@ * @returns {Number} | ||
readU64() { | ||
this.assert(this.offset + 8 <= this.data.length); | ||
this.check(8); | ||
const ret = encoding.readU64(this.data, this.offset); | ||
@@ -255,3 +350,3 @@ this.offset += 8; | ||
readU64BE() { | ||
this.assert(this.offset + 8 <= this.data.length); | ||
this.check(8); | ||
const ret = encoding.readU64BE(this.data, this.offset); | ||
@@ -268,3 +363,3 @@ this.offset += 8; | ||
readI8() { | ||
this.assert(this.offset + 1 <= this.data.length); | ||
this.check(1); | ||
const ret = encoding.readI8(this.data, this.offset); | ||
@@ -281,3 +376,3 @@ this.offset += 1; | ||
readI16() { | ||
this.assert(this.offset + 2 <= this.data.length); | ||
this.check(2); | ||
const ret = encoding.readI16(this.data, this.offset); | ||
@@ -294,3 +389,3 @@ this.offset += 2; | ||
readI16BE() { | ||
this.assert(this.offset + 2 <= this.data.length); | ||
this.check(2); | ||
const ret = encoding.readI16BE(this.data, this.offset); | ||
@@ -302,2 +397,26 @@ this.offset += 2; | ||
/** | ||
* Read int24le. | ||
* @returns {Number} | ||
*/ | ||
readI24() { | ||
this.check(3); | ||
const ret = encoding.readI24(this.data, this.offset); | ||
this.offset += 3; | ||
return ret; | ||
} | ||
/** | ||
* Read int24be. | ||
* @returns {Number} | ||
*/ | ||
readI24BE() { | ||
this.check(3); | ||
const ret = encoding.readI24BE(this.data, this.offset); | ||
this.offset += 3; | ||
return ret; | ||
} | ||
/** | ||
* Read int32le. | ||
@@ -308,3 +427,3 @@ * @returns {Number} | ||
readI32() { | ||
this.assert(this.offset + 4 <= this.data.length); | ||
this.check(4); | ||
const ret = encoding.readI32(this.data, this.offset); | ||
@@ -321,3 +440,3 @@ this.offset += 4; | ||
readI32BE() { | ||
this.assert(this.offset + 4 <= this.data.length); | ||
this.check(4); | ||
const ret = encoding.readI32BE(this.data, this.offset); | ||
@@ -329,2 +448,74 @@ this.offset += 4; | ||
/** | ||
* Read int40le. | ||
* @returns {Number} | ||
*/ | ||
readI40() { | ||
this.check(5); | ||
const ret = encoding.readI40(this.data, this.offset); | ||
this.offset += 5; | ||
return ret; | ||
} | ||
/** | ||
* Read int40be. | ||
* @returns {Number} | ||
*/ | ||
readI40BE() { | ||
this.check(5); | ||
const ret = encoding.readI40BE(this.data, this.offset); | ||
this.offset += 5; | ||
return ret; | ||
} | ||
/** | ||
* Read int48le. | ||
* @returns {Number} | ||
*/ | ||
readI48() { | ||
this.check(6); | ||
const ret = encoding.readI48(this.data, this.offset); | ||
this.offset += 6; | ||
return ret; | ||
} | ||
/** | ||
* Read int48be. | ||
* @returns {Number} | ||
*/ | ||
readI48BE() { | ||
this.check(6); | ||
const ret = encoding.readI48BE(this.data, this.offset); | ||
this.offset += 6; | ||
return ret; | ||
} | ||
/** | ||
* Read int56le. | ||
* @returns {Number} | ||
*/ | ||
readI56() { | ||
this.check(7); | ||
const ret = encoding.readI56(this.data, this.offset); | ||
this.offset += 7; | ||
return ret; | ||
} | ||
/** | ||
* Read int56be. | ||
* @returns {Number} | ||
*/ | ||
readI56BE() { | ||
this.check(7); | ||
const ret = encoding.readI56BE(this.data, this.offset); | ||
this.offset += 7; | ||
return ret; | ||
} | ||
/** | ||
* Read int64le as a js number. | ||
@@ -336,3 +527,3 @@ * @returns {Number} | ||
readI64() { | ||
this.assert(this.offset + 8 <= this.data.length); | ||
this.check(8); | ||
const ret = encoding.readI64(this.data, this.offset); | ||
@@ -350,3 +541,3 @@ this.offset += 8; | ||
readI64BE() { | ||
this.assert(this.offset + 8 <= this.data.length); | ||
this.check(8); | ||
const ret = encoding.readI64BE(this.data, this.offset); | ||
@@ -363,3 +554,3 @@ this.offset += 8; | ||
readFloat() { | ||
this.assert(this.offset + 4 <= this.data.length); | ||
this.check(4); | ||
const ret = encoding.readFloat(this.data, this.offset); | ||
@@ -376,3 +567,3 @@ this.offset += 4; | ||
readFloatBE() { | ||
this.assert(this.offset + 4 <= this.data.length); | ||
this.check(4); | ||
const ret = encoding.readFloatBE(this.data, this.offset); | ||
@@ -389,3 +580,3 @@ this.offset += 4; | ||
readDouble() { | ||
this.assert(this.offset + 8 <= this.data.length); | ||
this.check(8); | ||
const ret = encoding.readDouble(this.data, this.offset); | ||
@@ -402,3 +593,3 @@ this.offset += 8; | ||
readDoubleBE() { | ||
this.assert(this.offset + 8 <= this.data.length); | ||
this.check(8); | ||
const ret = encoding.readDoubleBE(this.data, this.offset); | ||
@@ -440,6 +631,8 @@ this.offset += 8; | ||
readBytes(size, zeroCopy) { | ||
assert(size >= 0); | ||
this.assert(this.offset + size <= this.data.length); | ||
readBytes(size, zeroCopy = false) { | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
enforce(typeof zeroCopy === 'boolean', 'zeroCopy', 'boolean'); | ||
this.check(size); | ||
let ret; | ||
@@ -466,3 +659,3 @@ if (this.zeroCopy || zeroCopy) { | ||
readVarBytes(zeroCopy) { | ||
readVarBytes(zeroCopy = false) { | ||
return this.readBytes(this.readVarint(), zeroCopy); | ||
@@ -478,5 +671,6 @@ } | ||
readChild(size) { | ||
assert(size >= 0); | ||
this.assert(this.offset + size <= this.data.length); | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
this.check(size); | ||
const data = this.data.slice(0, this.offset + size); | ||
@@ -494,12 +688,20 @@ | ||
* Read a string. | ||
* @param {Number} size | ||
* @param {String} enc - Any buffer-supported encoding. | ||
* @param {Number} size | ||
* @returns {String} | ||
*/ | ||
readString(enc, size) { | ||
assert(size >= 0); | ||
this.assert(this.offset + size <= this.data.length); | ||
readString(size, enc) { | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
this.check(size); | ||
const ret = this.data.toString(enc, this.offset, this.offset + size); | ||
this.offset += size; | ||
return ret; | ||
@@ -516,3 +718,3 @@ } | ||
if (enc) | ||
return this.readString(enc, 32); | ||
return this.readString(32, enc); | ||
return this.readBytes(32); | ||
@@ -528,6 +730,15 @@ } | ||
readVarString(enc, limit) { | ||
readVarString(enc, limit = 0) { | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
enforce((limit >>> 0) === limit, 'limit', 'integer'); | ||
const size = this.readVarint(); | ||
this.enforce(!limit || size <= limit, 'String exceeds limit.'); | ||
return this.readString(enc, size); | ||
if (limit !== 0 && size > limit) | ||
throw new EncodingError(this.offset, 'String exceeds limit'); | ||
return this.readString(size, enc); | ||
} | ||
@@ -542,5 +753,9 @@ | ||
readNullString(enc) { | ||
this.assert(this.offset + 1 <= this.data.length); | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
let i = this.offset; | ||
for (; i < this.data.length; i++) { | ||
@@ -551,5 +766,6 @@ if (this.data[i] === 0) | ||
this.assert(i !== this.data.length); | ||
if (i === this.data.length) | ||
throw new EncodingError(this.offset, 'No NUL terminator'); | ||
const ret = this.readString(enc, i - this.offset); | ||
const ret = this.readString(i - this.offset, enc); | ||
@@ -568,2 +784,4 @@ this.offset = i + 1; | ||
createChecksum(hash) { | ||
enforce(typeof hash === 'function', 'hash', 'function'); | ||
let start = 0; | ||
@@ -587,5 +805,8 @@ | ||
verifyChecksum(hash) { | ||
const chk = this.createChecksum(hash); | ||
const checksum = this.readU32(); | ||
this.enforce(chk === checksum, 'Checksum mismatch.'); | ||
const checksum = this.createChecksum(hash); | ||
const expect = this.readU32(); | ||
if (checksum !== expect) | ||
throw new EncodingError(this.offset, 'Checksum mismatch'); | ||
return checksum; | ||
@@ -592,0 +813,0 @@ } |
@@ -9,3 +9,3 @@ /*! | ||
const assert = require('assert'); | ||
const enforce = require('./enforce'); | ||
const encoding = require('./encoding'); | ||
@@ -19,3 +19,3 @@ const EncodingError = require('./error'); | ||
const EMPTY = Buffer.alloc(0); | ||
const POOLSIZE = 100 << 10; | ||
const POOL_SIZE = 100 << 10; | ||
@@ -44,2 +44,12 @@ let POOL = null; | ||
/** | ||
* Assertion. | ||
* @param {Number} size | ||
*/ | ||
check(size) { | ||
if (this.offset + size > this.data.length) | ||
throw new EncodingError(this.offset, 'Out of bounds write', this.check); | ||
} | ||
/** | ||
* Initialize options. | ||
@@ -56,3 +66,3 @@ * @param {Object} options | ||
assert((options >>> 0) === options); | ||
enforce((options >>> 0) === options, 'size', 'integer'); | ||
@@ -72,5 +82,7 @@ this.data = Buffer.allocUnsafe(options); | ||
static pool(size) { | ||
if (size <= POOLSIZE) { | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
if (size <= POOL_SIZE) { | ||
if (!POOL) | ||
POOL = Buffer.allocUnsafeSlow(POOLSIZE); | ||
POOL = Buffer.allocUnsafe(POOL_SIZE); | ||
@@ -128,7 +140,14 @@ const bw = new StaticWriter(); | ||
* Seek to relative offset. | ||
* @param {Number} offset | ||
* @param {Number} off | ||
*/ | ||
seek(offset) { | ||
this.offset += offset; | ||
seek(off) { | ||
enforce(Number.isSafeInteger(off), 'off', 'integer'); | ||
if (this.offset + off < 0) | ||
throw new EncodingError(this.offset, 'Out of bounds write'); | ||
this.check(off); | ||
this.offset += off; | ||
return this; | ||
@@ -153,2 +172,3 @@ } | ||
writeU8(value) { | ||
this.check(1); | ||
this.offset = encoding.writeU8(this.data, value, this.offset); | ||
@@ -164,2 +184,3 @@ return this; | ||
writeU16(value) { | ||
this.check(2); | ||
this.offset = encoding.writeU16(this.data, value, this.offset); | ||
@@ -175,2 +196,3 @@ return this; | ||
writeU16BE(value) { | ||
this.check(2); | ||
this.offset = encoding.writeU16BE(this.data, value, this.offset); | ||
@@ -181,2 +203,24 @@ return this; | ||
/** | ||
* Write uint24le. | ||
* @param {Number} value | ||
*/ | ||
writeU24(value) { | ||
this.check(3); | ||
this.offset = encoding.writeU24(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint24be. | ||
* @param {Number} value | ||
*/ | ||
writeU24BE(value) { | ||
this.check(3); | ||
this.offset = encoding.writeU24BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint32le. | ||
@@ -187,2 +231,3 @@ * @param {Number} value | ||
writeU32(value) { | ||
this.check(4); | ||
this.offset = encoding.writeU32(this.data, value, this.offset); | ||
@@ -198,2 +243,3 @@ return this; | ||
writeU32BE(value) { | ||
this.check(4); | ||
this.offset = encoding.writeU32BE(this.data, value, this.offset); | ||
@@ -204,2 +250,68 @@ return this; | ||
/** | ||
* Write uint40le. | ||
* @param {Number} value | ||
*/ | ||
writeU40(value) { | ||
this.check(5); | ||
this.offset = encoding.writeU40(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint40be. | ||
* @param {Number} value | ||
*/ | ||
writeU40BE(value) { | ||
this.check(5); | ||
this.offset = encoding.writeU40BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint48le. | ||
* @param {Number} value | ||
*/ | ||
writeU48(value) { | ||
this.check(6); | ||
this.offset = encoding.writeU48(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint48be. | ||
* @param {Number} value | ||
*/ | ||
writeU48BE(value) { | ||
this.check(6); | ||
this.offset = encoding.writeU48BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint56le. | ||
* @param {Number} value | ||
*/ | ||
writeU56(value) { | ||
this.check(7); | ||
this.offset = encoding.writeU56(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint56be. | ||
* @param {Number} value | ||
*/ | ||
writeU56BE(value) { | ||
this.check(7); | ||
this.offset = encoding.writeU56BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write uint64le. | ||
@@ -210,2 +322,3 @@ * @param {Number} value | ||
writeU64(value) { | ||
this.check(8); | ||
this.offset = encoding.writeU64(this.data, value, this.offset); | ||
@@ -221,2 +334,3 @@ return this; | ||
writeU64BE(value) { | ||
this.check(8); | ||
this.offset = encoding.writeU64BE(this.data, value, this.offset); | ||
@@ -232,2 +346,3 @@ return this; | ||
writeI8(value) { | ||
this.check(1); | ||
this.offset = encoding.writeI8(this.data, value, this.offset); | ||
@@ -243,2 +358,3 @@ return this; | ||
writeI16(value) { | ||
this.check(2); | ||
this.offset = encoding.writeI16(this.data, value, this.offset); | ||
@@ -254,2 +370,3 @@ return this; | ||
writeI16BE(value) { | ||
this.check(2); | ||
this.offset = encoding.writeI16BE(this.data, value, this.offset); | ||
@@ -260,2 +377,24 @@ return this; | ||
/** | ||
* Write int24le. | ||
* @param {Number} value | ||
*/ | ||
writeI24(value) { | ||
this.check(3); | ||
this.offset = encoding.writeI24(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int24be. | ||
* @param {Number} value | ||
*/ | ||
writeI24BE(value) { | ||
this.check(3); | ||
this.offset = encoding.writeI24BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int32le. | ||
@@ -266,2 +405,3 @@ * @param {Number} value | ||
writeI32(value) { | ||
this.check(4); | ||
this.offset = encoding.writeI32(this.data, value, this.offset); | ||
@@ -277,2 +417,3 @@ return this; | ||
writeI32BE(value) { | ||
this.check(4); | ||
this.offset = encoding.writeI32BE(this.data, value, this.offset); | ||
@@ -283,2 +424,68 @@ return this; | ||
/** | ||
* Write int40le. | ||
* @param {Number} value | ||
*/ | ||
writeI40(value) { | ||
this.check(5); | ||
this.offset = encoding.writeI40(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int40be. | ||
* @param {Number} value | ||
*/ | ||
writeI40BE(value) { | ||
this.check(5); | ||
this.offset = encoding.writeI40BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int48le. | ||
* @param {Number} value | ||
*/ | ||
writeI48(value) { | ||
this.check(6); | ||
this.offset = encoding.writeI48(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int48be. | ||
* @param {Number} value | ||
*/ | ||
writeI48BE(value) { | ||
this.check(6); | ||
this.offset = encoding.writeI48BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int56le. | ||
* @param {Number} value | ||
*/ | ||
writeI56(value) { | ||
this.check(7); | ||
this.offset = encoding.writeI56(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int56be. | ||
* @param {Number} value | ||
*/ | ||
writeI56BE(value) { | ||
this.check(7); | ||
this.offset = encoding.writeI56BE(this.data, value, this.offset); | ||
return this; | ||
} | ||
/** | ||
* Write int64le. | ||
@@ -289,2 +496,3 @@ * @param {Number} value | ||
writeI64(value) { | ||
this.check(8); | ||
this.offset = encoding.writeI64(this.data, value, this.offset); | ||
@@ -300,2 +508,3 @@ return this; | ||
writeI64BE(value) { | ||
this.check(8); | ||
this.offset = encoding.writeI64BE(this.data, value, this.offset); | ||
@@ -311,2 +520,3 @@ return this; | ||
writeFloat(value) { | ||
this.check(4); | ||
this.offset = encoding.writeFloat(this.data, value, this.offset); | ||
@@ -322,2 +532,3 @@ return this; | ||
writeFloatBE(value) { | ||
this.check(4); | ||
this.offset = encoding.writeFloatBE(this.data, value, this.offset); | ||
@@ -333,2 +544,3 @@ return this; | ||
writeDouble(value) { | ||
this.check(8); | ||
this.offset = encoding.writeDouble(this.data, value, this.offset); | ||
@@ -344,2 +556,3 @@ return this; | ||
writeDoubleBE(value) { | ||
this.check(8); | ||
this.offset = encoding.writeDoubleBE(this.data, value, this.offset); | ||
@@ -375,8 +588,5 @@ return this; | ||
writeBytes(value) { | ||
if (value.length === 0) | ||
return this; | ||
value.copy(this.data, this.offset); | ||
this.offset += value.length; | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
this.check(value.length); | ||
this.offset += value.copy(this.data, this.offset); | ||
return this; | ||
@@ -391,2 +601,3 @@ } | ||
writeVarBytes(value) { | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
this.writeVarint(value.length); | ||
@@ -405,10 +616,10 @@ this.writeBytes(value); | ||
copy(value, start, end) { | ||
const len = end - start; | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
enforce((start >>> 0) === start, 'start', 'integer'); | ||
enforce((end >>> 0) === end, 'end', 'integer'); | ||
enforce(end >= start, 'start', 'integer'); | ||
if (len === 0) | ||
return this; | ||
this.check(end - start); | ||
this.offset += value.copy(this.data, this.offset, start, end); | ||
value.copy(this.data, this.offset, start, end); | ||
this.offset += len; | ||
return this; | ||
@@ -424,2 +635,8 @@ } | ||
writeString(value, enc) { | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(typeof value === 'string', 'value', 'string'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
if (value.length === 0) | ||
@@ -429,7 +646,6 @@ return this; | ||
const size = Buffer.byteLength(value, enc); | ||
this.check(size); | ||
this.data.write(value, this.offset, enc); | ||
this.offset += this.data.write(value, this.offset, enc); | ||
this.offset += size; | ||
return this; | ||
@@ -445,9 +661,10 @@ } | ||
if (typeof value !== 'string') { | ||
assert(value.length === 32); | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
enforce(value.length === 32, 'value', '32-byte hash'); | ||
this.writeBytes(value); | ||
return this; | ||
} | ||
assert(value.length === 64); | ||
this.data.write(value, this.offset, 'hex'); | ||
this.offset += 32; | ||
enforce(value.length === 64, 'value', '32-byte hash'); | ||
this.check(32); | ||
this.offset += this.data.write(value, this.offset, 'hex'); | ||
return this; | ||
@@ -463,2 +680,8 @@ } | ||
writeVarString(value, enc) { | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(typeof value === 'string', 'value', 'string'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
if (value.length === 0) { | ||
@@ -472,6 +695,5 @@ this.writeVarint(0); | ||
this.writeVarint(size); | ||
this.data.write(value, this.offset, enc); | ||
this.check(size); | ||
this.offset += this.data.write(value, this.offset, enc); | ||
this.offset += size; | ||
return this; | ||
@@ -498,5 +720,12 @@ } | ||
writeChecksum(hash) { | ||
enforce(typeof hash === 'function', 'hash', 'function'); | ||
this.check(4); | ||
const data = this.data.slice(0, this.offset); | ||
hash(data).copy(this.data, this.offset, 0, 4); | ||
this.offset += 4; | ||
return this; | ||
@@ -512,6 +741,6 @@ } | ||
fill(value, size) { | ||
assert(size >= 0); | ||
enforce((value & 0xff) === value, 'value', 'byte'); | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
if (size === 0) | ||
return this; | ||
this.check(size); | ||
@@ -518,0 +747,0 @@ this.data.fill(value, this.offset, this.offset + size); |
@@ -9,6 +9,7 @@ /*! | ||
const assert = require('assert'); | ||
const enforce = require('./enforce'); | ||
const BufferReader = require('./reader'); | ||
const BufferWriter = require('./writer'); | ||
const StaticWriter = require('./staticwriter'); | ||
const {custom} = require('./custom'); | ||
@@ -23,3 +24,3 @@ /** | ||
inject(obj) { | ||
assert(obj instanceof this.constructor); | ||
enforce(obj instanceof this.constructor, 'obj', 'struct'); | ||
return this.decode(obj.encode()); | ||
@@ -101,3 +102,3 @@ } | ||
fromHex(str, extra) { | ||
assert(typeof str === 'string'); | ||
enforce(typeof str === 'string', 'str', 'string'); | ||
@@ -118,8 +119,7 @@ const size = str.length >>> 1; | ||
fromBase64(str, extra) { | ||
assert(typeof str === 'string'); | ||
enforce(typeof str === 'string', 'str', 'string'); | ||
const min = (((str.length - 3) & ~3) * 3) / 4 | 0; | ||
const data = Buffer.from(str, 'base64'); | ||
if (data.length < min) | ||
if (str.length > size64(data.length)) | ||
throw new Error('Invalid base64 string.'); | ||
@@ -134,3 +134,3 @@ | ||
inspect() { | ||
[custom]() { | ||
return this.format(); | ||
@@ -209,2 +209,11 @@ } | ||
/* | ||
* Helpers | ||
*/ | ||
function size64(size) { | ||
const expect = ((4 * size / 3) + 3) & ~3; | ||
return expect >>> 0; | ||
} | ||
/* | ||
* Expose | ||
@@ -211,0 +220,0 @@ */ |
@@ -10,3 +10,3 @@ /*! | ||
const assert = require('assert'); | ||
const enforce = require('./enforce'); | ||
const encoding = require('./encoding'); | ||
@@ -23,23 +23,39 @@ const EncodingError = require('./error'); | ||
const U16BE = 3; | ||
const U32 = 4; | ||
const U32BE = 5; | ||
const U64 = 6; | ||
const U64BE = 7; | ||
const I8 = 8; | ||
const I16 = 9; | ||
const I16BE = 10; | ||
const I32 = 11; | ||
const I32BE = 12; | ||
const I64 = 13; | ||
const I64BE = 14; | ||
const FL = 15; | ||
const FLBE = 16; | ||
const DBL = 17; | ||
const DBLBE = 18; | ||
const VARINT = 19; | ||
const VARINT2 = 20; | ||
const BYTES = 21; | ||
const STR = 22; | ||
const CHECKSUM = 23; | ||
const FILL = 24; | ||
const U24 = 4; | ||
const U24BE = 5; | ||
const U32 = 6; | ||
const U32BE = 7; | ||
const U40 = 8; | ||
const U40BE = 9; | ||
const U48 = 10; | ||
const U48BE = 11; | ||
const U56 = 12; | ||
const U56BE = 13; | ||
const U64 = 14; | ||
const U64BE = 15; | ||
const I8 = 16; | ||
const I16 = 17; | ||
const I16BE = 18; | ||
const I24 = 19; | ||
const I24BE = 20; | ||
const I32 = 21; | ||
const I32BE = 22; | ||
const I40 = 23; | ||
const I40BE = 24; | ||
const I48 = 25; | ||
const I48BE = 26; | ||
const I56 = 27; | ||
const I56BE = 28; | ||
const I64 = 29; | ||
const I64BE = 30; | ||
const FL = 31; | ||
const FLBE = 32; | ||
const DBL = 33; | ||
const DBLBE = 34; | ||
const VARINT = 35; | ||
const VARINT2 = 36; | ||
const BYTES = 37; | ||
const STR = 38; | ||
const CHECKSUM = 39; | ||
const FILL = 40; | ||
@@ -85,2 +101,8 @@ /** | ||
break; | ||
case U24: | ||
off = encoding.writeU24(data, op.value, off); | ||
break; | ||
case U24BE: | ||
off = encoding.writeU24BE(data, op.value, off); | ||
break; | ||
case U32: | ||
@@ -92,2 +114,20 @@ off = encoding.writeU32(data, op.value, off); | ||
break; | ||
case U40: | ||
off = encoding.writeU40(data, op.value, off); | ||
break; | ||
case U40BE: | ||
off = encoding.writeU40BE(data, op.value, off); | ||
break; | ||
case U48: | ||
off = encoding.writeU48(data, op.value, off); | ||
break; | ||
case U48BE: | ||
off = encoding.writeU48BE(data, op.value, off); | ||
break; | ||
case U56: | ||
off = encoding.writeU56(data, op.value, off); | ||
break; | ||
case U56BE: | ||
off = encoding.writeU56BE(data, op.value, off); | ||
break; | ||
case U64: | ||
@@ -108,2 +148,8 @@ off = encoding.writeU64(data, op.value, off); | ||
break; | ||
case I24: | ||
off = encoding.writeI24(data, op.value, off); | ||
break; | ||
case I24BE: | ||
off = encoding.writeI24BE(data, op.value, off); | ||
break; | ||
case I32: | ||
@@ -115,2 +161,20 @@ off = encoding.writeI32(data, op.value, off); | ||
break; | ||
case I40: | ||
off = encoding.writeI40(data, op.value, off); | ||
break; | ||
case I40BE: | ||
off = encoding.writeI40BE(data, op.value, off); | ||
break; | ||
case I48: | ||
off = encoding.writeI48(data, op.value, off); | ||
break; | ||
case I48BE: | ||
off = encoding.writeI48BE(data, op.value, off); | ||
break; | ||
case I56: | ||
off = encoding.writeI56(data, op.value, off); | ||
break; | ||
case I56BE: | ||
off = encoding.writeI56BE(data, op.value, off); | ||
break; | ||
case I64: | ||
@@ -154,4 +218,3 @@ off = encoding.writeI64(data, op.value, off); | ||
default: | ||
assert(false, 'Bad type.'); | ||
break; | ||
throw new Error('Invalid type.'); | ||
} | ||
@@ -182,5 +245,11 @@ } | ||
seek(offset) { | ||
this.offset += offset; | ||
this.ops.push(new NumberOp(SEEK, offset)); | ||
seek(off) { | ||
enforce(Number.isSafeInteger(off), 'off', 'integer'); | ||
if (this.offset + off < 0) | ||
throw new EncodingError(this.offset, 'Out of bounds write'); | ||
this.offset += off; | ||
this.ops.push(new NumberOp(SEEK, off)); | ||
return this; | ||
@@ -233,2 +302,24 @@ } | ||
/** | ||
* Write uint24le. | ||
* @param {Number} value | ||
*/ | ||
writeU24(value) { | ||
this.offset += 3; | ||
this.ops.push(new NumberOp(U24, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint24be. | ||
* @param {Number} value | ||
*/ | ||
writeU24BE(value) { | ||
this.offset += 3; | ||
this.ops.push(new NumberOp(U24BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint32le. | ||
@@ -256,2 +347,68 @@ * @param {Number} value | ||
/** | ||
* Write uint40le. | ||
* @param {Number} value | ||
*/ | ||
writeU40(value) { | ||
this.offset += 5; | ||
this.ops.push(new NumberOp(U40, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint40be. | ||
* @param {Number} value | ||
*/ | ||
writeU40BE(value) { | ||
this.offset += 5; | ||
this.ops.push(new NumberOp(U40BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint48le. | ||
* @param {Number} value | ||
*/ | ||
writeU48(value) { | ||
this.offset += 6; | ||
this.ops.push(new NumberOp(U48, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint48be. | ||
* @param {Number} value | ||
*/ | ||
writeU48BE(value) { | ||
this.offset += 6; | ||
this.ops.push(new NumberOp(U48BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint56le. | ||
* @param {Number} value | ||
*/ | ||
writeU56(value) { | ||
this.offset += 7; | ||
this.ops.push(new NumberOp(U56, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint56be. | ||
* @param {Number} value | ||
*/ | ||
writeU56BE(value) { | ||
this.offset += 7; | ||
this.ops.push(new NumberOp(U56BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write uint64le. | ||
@@ -312,2 +469,24 @@ * @param {Number} value | ||
/** | ||
* Write int24le. | ||
* @param {Number} value | ||
*/ | ||
writeI24(value) { | ||
this.offset += 3; | ||
this.ops.push(new NumberOp(I24, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int24be. | ||
* @param {Number} value | ||
*/ | ||
writeI24BE(value) { | ||
this.offset += 3; | ||
this.ops.push(new NumberOp(I24BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int32le. | ||
@@ -335,2 +514,68 @@ * @param {Number} value | ||
/** | ||
* Write int40le. | ||
* @param {Number} value | ||
*/ | ||
writeI40(value) { | ||
this.offset += 5; | ||
this.ops.push(new NumberOp(I40, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int40be. | ||
* @param {Number} value | ||
*/ | ||
writeI40BE(value) { | ||
this.offset += 5; | ||
this.ops.push(new NumberOp(I40BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int48le. | ||
* @param {Number} value | ||
*/ | ||
writeI48(value) { | ||
this.offset += 6; | ||
this.ops.push(new NumberOp(I48, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int48be. | ||
* @param {Number} value | ||
*/ | ||
writeI48BE(value) { | ||
this.offset += 6; | ||
this.ops.push(new NumberOp(I48BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int56le. | ||
* @param {Number} value | ||
*/ | ||
writeI56(value) { | ||
this.offset += 7; | ||
this.ops.push(new NumberOp(I56, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int56be. | ||
* @param {Number} value | ||
*/ | ||
writeI56BE(value) { | ||
this.offset += 7; | ||
this.ops.push(new NumberOp(I56BE, value)); | ||
return this; | ||
} | ||
/** | ||
* Write int64le. | ||
@@ -429,2 +674,4 @@ * @param {Number} value | ||
writeBytes(value) { | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
if (value.length === 0) | ||
@@ -445,2 +692,4 @@ return this; | ||
writeVarBytes(value) { | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
this.offset += encoding.sizeVarint(value.length); | ||
@@ -466,5 +715,11 @@ this.ops.push(new NumberOp(VARINT, value.length)); | ||
copy(value, start, end) { | ||
assert(end >= start); | ||
value = value.slice(start, end); | ||
this.writeBytes(value); | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
enforce((start >>> 0) === start, 'start', 'integer'); | ||
enforce((end >>> 0) === end, 'end', 'integer'); | ||
enforce(end >= start, 'start', 'integer'); | ||
const buf = value.slice(start, end); | ||
this.writeBytes(buf); | ||
return this; | ||
@@ -480,2 +735,8 @@ } | ||
writeString(value, enc) { | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(typeof value === 'string', 'value', 'string'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
if (value.length === 0) | ||
@@ -497,7 +758,8 @@ return this; | ||
if (typeof value !== 'string') { | ||
assert(value.length === 32); | ||
enforce(Buffer.isBuffer(value), 'value', 'buffer'); | ||
enforce(value.length === 32, 'value', '32-byte hash'); | ||
this.writeBytes(value); | ||
return this; | ||
} | ||
assert(value.length === 64); | ||
enforce(value.length === 64, 'value', '32-byte hash'); | ||
this.writeString(value, 'hex'); | ||
@@ -514,2 +776,8 @@ return this; | ||
writeVarString(value, enc) { | ||
if (enc == null) | ||
enc = 'binary'; | ||
enforce(typeof value === 'string', 'value', 'string'); | ||
enforce(typeof enc === 'string', 'enc', 'string'); | ||
if (value.length === 0) { | ||
@@ -549,2 +817,3 @@ this.ops.push(new NumberOp(VARINT, 0)); | ||
writeChecksum(hash) { | ||
enforce(typeof hash === 'function', 'hash', 'function'); | ||
this.offset += 4; | ||
@@ -562,3 +831,4 @@ this.ops.push(new FunctionOp(CHECKSUM, hash)); | ||
fill(value, size) { | ||
assert(size >= 0); | ||
enforce((value & 0xff) === value, 'value', 'byte'); | ||
enforce((size >>> 0) === size, 'size', 'integer'); | ||
@@ -565,0 +835,0 @@ if (size === 0) |
{ | ||
"name": "bufio", | ||
"version": "0.2.0", | ||
"version": "1.0.0", | ||
"description": "Buffer and serialization utilities for javascript", | ||
@@ -18,21 +18,9 @@ "keywords": [ | ||
"scripts": { | ||
"browserify": "browserify -s bufio lib/bufio.js | uglifyjs -c > bufio.js", | ||
"clean": "rm -f bufio.js", | ||
"lint": "eslint lib/ test/ || exit 0", | ||
"test": "mocha --reporter spec test/*-test.js", | ||
"webpack": "webpack --mode production --config webpack.config.js" | ||
"test": "mocha --reporter spec test/*-test.js" | ||
}, | ||
"devDependencies": { | ||
"babelify": "^8.0.0", | ||
"babel-core": "^6.26.3", | ||
"babel-loader": "^7.1.4", | ||
"babel-preset-env": "^1.7.0", | ||
"browserify": "^16.2.2", | ||
"eslint": "^4.19.1", | ||
"eslint": "^5.1.0", | ||
"mocha": "^5.2.0", | ||
"n64": "~0.2.0", | ||
"uglifyjs-webpack-plugin": "^1.2.5", | ||
"uglify-es": "^3.3.9", | ||
"webpack": "^4.11.1", | ||
"webpack-cli": "^3.0.3" | ||
"n64": "~0.2.0" | ||
}, | ||
@@ -42,7 +30,5 @@ "engines": { | ||
}, | ||
"browserify": { | ||
"transform": [ | ||
"babelify" | ||
] | ||
"browser": { | ||
"./lib/custom": "./lib/custom-browser.js" | ||
} | ||
} |
@@ -13,3 +13,3 @@ # bufio | ||
bw.writeU64(100); | ||
bw.writeString('foo', 'ascii'); | ||
bw.writeString('foo'); | ||
const data = bw.render(); | ||
@@ -19,3 +19,3 @@ | ||
assert(br.readU64() === 100); | ||
assert(br.readString('ascii') === 'foo'); | ||
assert(br.readString(3) === 'foo'); | ||
``` | ||
@@ -22,0 +22,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
90075
3
0
3454