full site update

This commit is contained in:
2025-07-24 18:46:24 +02:00
parent bfe2b90d8d
commit 37a6e0ab31
6912 changed files with 540482 additions and 361712 deletions

21
node_modules/restructure/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2015-present Devon Govett
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

300
node_modules/restructure/README.md generated vendored Normal file
View File

@@ -0,0 +1,300 @@
# Restructure
[![Build Status](https://travis-ci.org/devongovett/restructure.svg?branch=master)](https://travis-ci.org/devongovett/restructure)
[![Coverage Status](https://coveralls.io/repos/devongovett/restructure/badge.png?branch=master)](https://coveralls.io/r/devongovett/restructure?branch=master)
Restructure allows you to declaratively encode and decode binary data.
It supports a wide variety of types to enable you to express a multitude
of binary formats without writing any parsing code.
Some of the supported features are C-like structures, versioned structures,
pointers, arrays of any type, strings of a large number of encodings, enums,
bitfields, and more. See the documentation below for more details.
## Example
This is just a small example of what Restructure can do. Check out the API documentation
below for more information.
```javascript
import * as r from 'restructure';
let Person = new r.Struct({
name: new r.String(r.uint8, 'utf8'),
age: r.uint8
});
// decode a person from a buffer
let value = Person.fromBuffer(new Uint8Array([/* ... */])); // returns an object with the fields defined above
// encode a person from an object
let buffer = Person.toBuffer({
name: 'Devon',
age: 21
});
```
## API
All of the following types support three standard methods:
* `fromBuffer(buffer)` - decodes an instance of the type from the given Uint8Array
* `size(value)` - returns the amount of space the value would take if encoded
* `toBuffer(value)` - encodes the given value into a Uint8Array
Restructure supports a wide variety of types, but if you need to write your own for
some custom use that cannot be represented by them, you can do so by just implementing
the above methods. Then you can use your type just as you would any other type, in structures
and whatnot.
### Number Types
The following built-in number types are available:
```javascript
uint8, uint16, uint24, uint32, int8, int16, int24, int32, float, double, fixed16, fixed32
```
Numbers are big-endian (network order) by default, but little-endian is supported, too:
```javascript
uint16le, uint24le, uint32le, int16le, int24le, int32le, floatle, doublele, fixed16le, fixed32le
```
To avoid ambiguity, big-endian may be used explicitly:
```javascript
uint16be, uint24be, uint32be, int16be, int24be, int32be, floatbe, doublebe, fixed16be, fixed32be
```
### Boolean
Booleans are encoded as `0` or `1` using one of the above number types.
```javascript
var bool = new r.Boolean(r.uint32);
```
### Reserved
The `Reserved` type simply skips data in a structure, where there are reserved fields.
Encoding produces zeros.
```javascript
// 10 reserved uint8s (default is 1)
var reserved = new r.Reserved(r.uint8, 10);
```
### Optional
The `Optional` type only encodes or decodes when given condition is truthy.
```javascript
// includes field
var optional = new r.Optional(r.uint8, true);
// excludes field
var optional = new r.Optional(r.uint8, false);
// determine whether field is to be included at runtime with a function
var optional = new r.Optional(r.uint8, function() {
return this.flags & 0x50;
});
```
### Enum
The `Enum` type maps a number to the value at that index in an array.
```javascript
var color = new r.Enum(r.uint8, ['red', 'orange', 'yellow', 'green', 'blue', 'purple']);
```
### Bitfield
The `Bitfield` type maps a number to an object with boolean keys mapping to each bit in that number,
as defined in an array.
```javascript
var bitfield = new r.Bitfield(r.uint8, ['Jack', 'Kack', 'Lack', 'Mack', 'Nack', 'Oack', 'Pack', 'Quack']);
bitfield.decode(stream);
var result = {
Jack: true,
Kack: false,
Lack: false,
Mack: true,
Nack: true,
Oack: false,
Pack: true,
Quack: true
};
bitfield.encode(stream, result);
```
### Buffer
Extracts a slice of the buffer to a `Uint8Array`. The length can be a constant, or taken from
a previous field in the parent structure.
```javascript
// fixed length
var buf = new r.Buffer(2);
// length from parent structure
var struct = new r.Struct({
bufLen: r.uint8,
buf: new r.Buffer('bufLen')
});
```
### String
A `String` maps a JavaScript string to and from binary encodings. The length, in bytes, can be a constant,
taken from a previous field in the parent structure, encoded using a number type immediately before the
string.
Fully supported encodings include `'ascii'`, `'utf8'`, `'ucs2'`, `'utf16le'`, `'utf16be'`. Decoding is also possible
with any encoding supported by [TextDecoder](https://developer.mozilla.org/en-US/docs/Web/API/Encoding_API/Encodings),
however encoding these is not supported.
```javascript
// fixed length, ascii encoding by default
var str = new r.String(2);
// length encoded as number before the string, utf8 encoding
var str = new r.String(r.uint8, 'utf8');
// length from parent structure
var struct = new r.Struct({
len: r.uint8,
str: new r.String('len', 'utf16be')
});
// null-terminated string (also known as C string)
var str = new r.String(null, 'utf8');
```
### Array
An `Array` maps to and from a JavaScript array containing instances of a sub-type. The length can be a constant,
taken from a previous field in the parent structure, encoded using a number type immediately
before the string, or computed by a function.
```javascript
// fixed length, containing numbers
var arr = new r.Array(r.uint16, 2);
// length encoded as number before the array containing strings
var arr = new r.Array(new r.String(10), r.uint8);
// length computed by a function
var arr = new r.Array(r.uint8, function() { return 5 });
// length from parent structure
var struct = new r.Struct({
len: r.uint8,
arr: new r.Array(r.uint8, 'len')
});
// treat as amount of bytes instead (may be used in all the above scenarios)
var arr = new r.Array(r.uint16, 6, 'bytes');
```
### LazyArray
The `LazyArray` type extends from the `Array` type, and is useful for large arrays that you do not need to access sequentially.
It avoids decoding the entire array upfront, and instead only decodes and caches individual items as needed. It only works when
the elements inside the array have a fixed size.
Instead of returning a JavaScript array, the `LazyArray` type returns a custom object that can be used to access the elements.
```javascript
var arr = new r.LazyArray(r.uint16, 2048);
var res = arr.decode(stream);
// get a single element
var el = res.get(2);
// convert to a normal array (decode all elements)
var array = res.toArray();
```
### Struct
A `Struct` maps to and from JavaScript objects, containing keys of various previously discussed types. Sub structures,
arrays of structures, and pointers to other types (discussed below) are supported.
```javascript
var Person = new r.Struct({
name: new r.String(r.uint8, 'utf8'),
age: r.uint8
});
```
### VersionedStruct
A `VersionedStruct` is a `Struct` that has multiple versions. The version is typically encoded at
the beginning of the structure, or as a field in a parent structure. There is an optional `header`
common to all versions, and separate fields listed for each version number.
```javascript
// the version is read as a uint8 in this example
// you could also get the version from a key on the parent struct
var Person = new r.VersionedStruct(r.uint8, {
// optional header common to all versions
header: {
name: new r.String(r.uint8, 'utf8')
},
0: {
age: r.uint8
},
1: {
hairColor: r.Enum(r.uint8, ['black', 'brown', 'blonde'])
}
});
```
### Pointer
Pointers map an address or offset encoded as a number, to a value encoded elsewhere in the buffer.
There are a few options you can use: `type`, `relativeTo`, `allowNull`, and `nullValue`.
The `type` option has these possible values:
* `local` (default) - the encoded offset is relative to the start of the containing structure
* `immediate` - the encoded offset is relative to the position of the pointer itself
* `parent` - the encoded offset is relative to the parent structure of the immediate container
* `global` - the encoded offset is global to the start of the file
The `relativeTo` option accepts a function callback that should return the field on the containing structure which the encoded offset is relative to. The callback is called with the context as parameter.
By default, pointers are relative to the start of the containing structure (`local`).
The `allowNull` option lets you specify whether zero offsets are allowed or should produce `null`. This is
set to `true` by default. The `nullValue` option is related, and lets you override the encoded value that
represents `null`. By default, the `nullValue` is zero.
The `lazy` option allows lazy decoding of the pointer's value by defining a getter on the parent object.
This only works when the pointer is contained within a Struct, but can be used to speed up decoding
quite a bit when not all of the data is needed right away.
```javascript
var Address = new r.Struct({
street: new r.String(r.uint8),
zip: new r.String(5)
});
var Person = new r.Struct({
name: new r.String(r.uint8, 'utf8'),
age: r.uint8,
ptrStart: r.uint8,
address: new r.Pointer(r.uint8, Address)
});
```
If the type of a pointer is set to 'void', it is not decoded and the computed address in the buffer
is simply returned. To encode a void pointer, create a `new r.VoidPointer(type, value)`.
## License
MIT

1019
node_modules/restructure/dist/main.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

1
node_modules/restructure/dist/main.cjs.map generated vendored Normal file

File diff suppressed because one or more lines are too long

17
node_modules/restructure/index.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
export {EncodeStream} from './src/EncodeStream.js';
export {DecodeStream} from './src/DecodeStream.js';
export {Array} from './src/Array.js';
export {LazyArray} from './src/LazyArray.js';
export {Bitfield} from './src/Bitfield.js';
export {Boolean} from './src/Boolean.js';
export {Buffer} from './src/Buffer.js';
export {Enum} from './src/Enum.js';
export {Optional} from './src/Optional.js';
export {Reserved} from './src/Reserved.js';
export {String} from './src/String.js';
export {Struct} from './src/Struct.js';
export {VersionedStruct} from './src/VersionedStruct.js';
export * from './src/utils.js';
export * from './src/Number.js';
export * from './src/Pointer.js';

41
node_modules/restructure/package.json generated vendored Normal file
View File

@@ -0,0 +1,41 @@
{
"name": "restructure",
"version": "3.0.2",
"description": "Declaratively encode and decode binary data",
"type": "module",
"main": "./dist/main.cjs",
"module": "./index.js",
"source": "./index.js",
"exports": {
"import": "./index.js",
"require": "./dist/main.cjs"
},
"targets": {
"module": false
},
"devDependencies": {
"mocha": "^10.0.0",
"parcel": "^2.6.1"
},
"scripts": {
"test": "mocha",
"build": "parcel build",
"prepublishOnly": "parcel build"
},
"repository": {
"type": "git",
"url": "git://github.com/devongovett/restructure.git"
},
"keywords": [
"binary",
"struct",
"encode",
"decode"
],
"author": "Devon Govett <devongovett@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/devongovett/restructure/issues"
},
"homepage": "https://github.com/devongovett/restructure"
}

106
node_modules/restructure/src/Array.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
import {Base} from './Base.js';
import {Number as NumberT} from './Number.js';
import * as utils from './utils.js';
class ArrayT extends Base {
constructor(type, length, lengthType = 'count') {
super();
this.type = type;
this.length = length;
this.lengthType = lengthType;
}
decode(stream, parent) {
let length;
const { pos } = stream;
const res = [];
let ctx = parent;
if (this.length != null) {
length = utils.resolveLength(this.length, stream, parent);
}
if (this.length instanceof NumberT) {
// define hidden properties
Object.defineProperties(res, {
parent: { value: parent },
_startOffset: { value: pos },
_currentOffset: { value: 0, writable: true },
_length: { value: length }
});
ctx = res;
}
if ((length == null) || (this.lengthType === 'bytes')) {
const target = (length != null) ?
stream.pos + length
: (parent != null ? parent._length : undefined) ?
parent._startOffset + parent._length
:
stream.length;
while (stream.pos < target) {
res.push(this.type.decode(stream, ctx));
}
} else {
for (let i = 0, end = length; i < end; i++) {
res.push(this.type.decode(stream, ctx));
}
}
return res;
}
size(array, ctx, includePointers = true) {
if (!array) {
return this.type.size(null, ctx) * utils.resolveLength(this.length, null, ctx);
}
let size = 0;
if (this.length instanceof NumberT) {
size += this.length.size();
ctx = {parent: ctx, pointerSize: 0};
}
for (let item of array) {
size += this.type.size(item, ctx);
}
if (ctx && includePointers && this.length instanceof NumberT) {
size += ctx.pointerSize;
}
return size;
}
encode(stream, array, parent) {
let ctx = parent;
if (this.length instanceof NumberT) {
ctx = {
pointers: [],
startOffset: stream.pos,
parent
};
ctx.pointerOffset = stream.pos + this.size(array, ctx, false);
this.length.encode(stream, array.length);
}
for (let item of array) {
this.type.encode(stream, item, ctx);
}
if (this.length instanceof NumberT) {
let i = 0;
while (i < ctx.pointers.length) {
const ptr = ctx.pointers[i++];
ptr.type.encode(stream, ptr.val, ptr.parent);
}
}
}
}
export {ArrayT as Array};

17
node_modules/restructure/src/Base.js generated vendored Normal file
View File

@@ -0,0 +1,17 @@
import {DecodeStream} from './DecodeStream.js';
import {EncodeStream} from './EncodeStream.js';
export class Base {
fromBuffer(buffer) {
let stream = new DecodeStream(buffer);
return this.decode(stream);
}
toBuffer(value) {
let size = this.size(value);
let buffer = new Uint8Array(size);
let stream = new EncodeStream(buffer);
this.encode(stream, value);
return buffer;
}
}

39
node_modules/restructure/src/Bitfield.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
import {Base} from './Base.js';
export class Bitfield extends Base {
constructor(type, flags = []) {
super();
this.type = type;
this.flags = flags;
}
decode(stream) {
const val = this.type.decode(stream);
const res = {};
for (let i = 0; i < this.flags.length; i++) {
const flag = this.flags[i];
if (flag != null) {
res[flag] = !!(val & (1 << i));
}
}
return res;
}
size() {
return this.type.size();
}
encode(stream, keys) {
let val = 0;
for (let i = 0; i < this.flags.length; i++) {
const flag = this.flags[i];
if (flag != null) {
if (keys[flag]) { val |= (1 << i); }
}
}
return this.type.encode(stream, val);
}
}

22
node_modules/restructure/src/Boolean.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
import {Base} from './Base.js';
export class BooleanT extends Base {
constructor(type) {
super();
this.type = type;
}
decode(stream, parent) {
return !!this.type.decode(stream, parent);
}
size(val, parent) {
return this.type.size(val, parent);
}
encode(stream, val, parent) {
return this.type.encode(stream, +val, parent);
}
}
export {BooleanT as Boolean};

38
node_modules/restructure/src/Buffer.js generated vendored Normal file
View File

@@ -0,0 +1,38 @@
import {Base} from './Base.js';
import {Number as NumberT} from './Number.js';
import * as utils from './utils.js';
export class BufferT extends Base {
constructor(length) {
super();
this.length = length;
}
decode(stream, parent) {
const length = utils.resolveLength(this.length, stream, parent);
return stream.readBuffer(length);
}
size(val, parent) {
if (!val) {
return utils.resolveLength(this.length, null, parent);
}
let len = val.length;
if (this.length instanceof NumberT) {
len += this.length.size();
}
return len;
}
encode(stream, buf, parent) {
if (this.length instanceof NumberT) {
this.length.encode(stream, buf.length);
}
return stream.writeBuffer(buf);
}
}
export {BufferT as Buffer};

85
node_modules/restructure/src/DecodeStream.js generated vendored Normal file
View File

@@ -0,0 +1,85 @@
// Node back-compat.
const ENCODING_MAPPING = {
utf16le: 'utf-16le',
ucs2: 'utf-16le',
utf16be: 'utf-16be'
}
export class DecodeStream {
constructor(buffer) {
this.buffer = buffer;
this.view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
this.pos = 0;
this.length = this.buffer.length;
}
readString(length, encoding = 'ascii') {
encoding = ENCODING_MAPPING[encoding] || encoding;
let buf = this.readBuffer(length);
try {
let decoder = new TextDecoder(encoding);
return decoder.decode(buf);
} catch (err) {
return buf;
}
}
readBuffer(length) {
return this.buffer.slice(this.pos, (this.pos += length));
}
readUInt24BE() {
return (this.readUInt16BE() << 8) + this.readUInt8();
}
readUInt24LE() {
return this.readUInt16LE() + (this.readUInt8() << 16);
}
readInt24BE() {
return (this.readInt16BE() << 8) + this.readUInt8();
}
readInt24LE() {
return this.readUInt16LE() + (this.readInt8() << 16);
}
}
DecodeStream.TYPES = {
UInt8: 1,
UInt16: 2,
UInt24: 3,
UInt32: 4,
Int8: 1,
Int16: 2,
Int24: 3,
Int32: 4,
Float: 4,
Double: 8
};
for (let key of Object.getOwnPropertyNames(DataView.prototype)) {
if (key.slice(0, 3) === 'get') {
let type = key.slice(3).replace('Ui', 'UI');
if (type === 'Float32') {
type = 'Float';
} else if (type === 'Float64') {
type = 'Double';
}
let bytes = DecodeStream.TYPES[type];
DecodeStream.prototype['read' + type + (bytes === 1 ? '' : 'BE')] = function () {
const ret = this.view[key](this.pos, false);
this.pos += bytes;
return ret;
};
if (bytes !== 1) {
DecodeStream.prototype['read' + type + 'LE'] = function () {
const ret = this.view[key](this.pos, true);
this.pos += bytes;
return ret;
};
}
}
}

129
node_modules/restructure/src/EncodeStream.js generated vendored Normal file
View File

@@ -0,0 +1,129 @@
import {DecodeStream} from './DecodeStream.js';
const textEncoder = new TextEncoder();
const isBigEndian = new Uint8Array(new Uint16Array([0x1234]).buffer)[0] == 0x12;
export class EncodeStream {
constructor(buffer) {
this.buffer = buffer;
this.view = new DataView(this.buffer.buffer, this.buffer.byteOffset, this.buffer.byteLength);
this.pos = 0;
}
writeBuffer(buffer) {
this.buffer.set(buffer, this.pos);
this.pos += buffer.length;
}
writeString(string, encoding = 'ascii') {
let buf;
switch (encoding) {
case 'utf16le':
case 'utf16-le':
case 'ucs2': // node treats this the same as utf16.
buf = stringToUtf16(string, isBigEndian);
break;
case 'utf16be':
case 'utf16-be':
buf = stringToUtf16(string, !isBigEndian);
break;
case 'utf8':
buf = textEncoder.encode(string);
break;
case 'ascii':
buf = stringToAscii(string);
break;
default:
throw new Error(`Unsupported encoding: ${encoding}`);
}
this.writeBuffer(buf);
}
writeUInt24BE(val) {
this.buffer[this.pos++] = (val >>> 16) & 0xff;
this.buffer[this.pos++] = (val >>> 8) & 0xff;
this.buffer[this.pos++] = val & 0xff;
}
writeUInt24LE(val) {
this.buffer[this.pos++] = val & 0xff;
this.buffer[this.pos++] = (val >>> 8) & 0xff;
this.buffer[this.pos++] = (val >>> 16) & 0xff;
}
writeInt24BE(val) {
if (val >= 0) {
this.writeUInt24BE(val);
} else {
this.writeUInt24BE(val + 0xffffff + 1);
}
}
writeInt24LE(val) {
if (val >= 0) {
this.writeUInt24LE(val);
} else {
this.writeUInt24LE(val + 0xffffff + 1);
}
}
fill(val, length) {
if (length < this.buffer.length) {
this.buffer.fill(val, this.pos, this.pos + length);
this.pos += length;
} else {
const buf = new Uint8Array(length);
buf.fill(val);
this.writeBuffer(buf);
}
}
}
function stringToUtf16(string, swap) {
let buf = new Uint16Array(string.length);
for (let i = 0; i < string.length; i++) {
let code = string.charCodeAt(i);
if (swap) {
code = (code >> 8) | ((code & 0xff) << 8);
}
buf[i] = code;
}
return new Uint8Array(buf.buffer);
}
function stringToAscii(string) {
let buf = new Uint8Array(string.length);
for (let i = 0; i < string.length; i++) {
// Match node.js behavior - encoding allows 8-bit rather than 7-bit.
buf[i] = string.charCodeAt(i);
}
return buf;
}
for (let key of Object.getOwnPropertyNames(DataView.prototype)) {
if (key.slice(0, 3) === 'set') {
let type = key.slice(3).replace('Ui', 'UI');
if (type === 'Float32') {
type = 'Float';
} else if (type === 'Float64') {
type = 'Double';
}
let bytes = DecodeStream.TYPES[type];
EncodeStream.prototype['write' + type + (bytes === 1 ? '' : 'BE')] = function (value) {
this.view[key](this.pos, value, false);
this.pos += bytes;
};
if (bytes !== 1) {
EncodeStream.prototype['write' + type + 'LE'] = function (value) {
this.view[key](this.pos, value, true);
this.pos += bytes;
};
}
}
}

27
node_modules/restructure/src/Enum.js generated vendored Normal file
View File

@@ -0,0 +1,27 @@
import {Base} from './Base.js';
export class Enum extends Base {
constructor(type, options = []) {
super();
this.type = type;
this.options = options;
}
decode(stream) {
const index = this.type.decode(stream);
return this.options[index] || index;
}
size() {
return this.type.size();
}
encode(stream, val) {
const index = this.options.indexOf(val);
if (index === -1) {
throw new Error(`Unknown option in enum: ${val}`);
}
return this.type.encode(stream, index);
}
}

74
node_modules/restructure/src/LazyArray.js generated vendored Normal file
View File

@@ -0,0 +1,74 @@
import {Array as ArrayT} from './Array.js';
import {Number as NumberT} from './Number.js';
import * as utils from './utils.js';
export class LazyArray extends ArrayT {
decode(stream, parent) {
const { pos } = stream;
const length = utils.resolveLength(this.length, stream, parent);
if (this.length instanceof NumberT) {
parent = {
parent,
_startOffset: pos,
_currentOffset: 0,
_length: length
};
}
const res = new LazyArrayValue(this.type, length, stream, parent);
stream.pos += length * this.type.size(null, parent);
return res;
}
size(val, ctx) {
if (val instanceof LazyArrayValue) {
val = val.toArray();
}
return super.size(val, ctx);
}
encode(stream, val, ctx) {
if (val instanceof LazyArrayValue) {
val = val.toArray();
}
return super.encode(stream, val, ctx);
}
}
class LazyArrayValue {
constructor(type, length, stream, ctx) {
this.type = type;
this.length = length;
this.stream = stream;
this.ctx = ctx;
this.base = this.stream.pos;
this.items = [];
}
get(index) {
if ((index < 0) || (index >= this.length)) {
return undefined;
}
if (this.items[index] == null) {
const { pos } = this.stream;
this.stream.pos = this.base + (this.type.size(null, this.ctx) * index);
this.items[index] = this.type.decode(this.stream, this.ctx);
this.stream.pos = pos;
}
return this.items[index];
}
toArray() {
const result = [];
for (let i = 0, end = this.length; i < end; i++) {
result.push(this.get(i));
}
return result;
}
}

77
node_modules/restructure/src/Number.js generated vendored Normal file
View File

@@ -0,0 +1,77 @@
import {DecodeStream} from './DecodeStream.js';
import {Base} from './Base.js';
class NumberT extends Base {
constructor(type, endian = 'BE') {
super();
this.type = type;
this.endian = endian;
this.fn = this.type;
if (this.type[this.type.length - 1] !== '8') {
this.fn += this.endian;
}
}
size() {
return DecodeStream.TYPES[this.type];
}
decode(stream) {
return stream[`read${this.fn}`]();
}
encode(stream, val) {
return stream[`write${this.fn}`](val);
}
}
export {NumberT as Number};
export const uint8 = new NumberT('UInt8');
export const uint16be = new NumberT('UInt16', 'BE');
export const uint16 = uint16be;
export const uint16le = new NumberT('UInt16', 'LE');
export const uint24be = new NumberT('UInt24', 'BE');
export const uint24 = uint24be;
export const uint24le = new NumberT('UInt24', 'LE');
export const uint32be = new NumberT('UInt32', 'BE');
export const uint32 = uint32be;
export const uint32le = new NumberT('UInt32', 'LE');
export const int8 = new NumberT('Int8');
export const int16be = new NumberT('Int16', 'BE');
export const int16 = int16be;
export const int16le = new NumberT('Int16', 'LE');
export const int24be = new NumberT('Int24', 'BE');
export const int24 = int24be;
export const int24le = new NumberT('Int24', 'LE');
export const int32be = new NumberT('Int32', 'BE');
export const int32 = int32be;
export const int32le = new NumberT('Int32', 'LE');
export const floatbe = new NumberT('Float', 'BE');
export const float = floatbe;
export const floatle = new NumberT('Float', 'LE');
export const doublebe = new NumberT('Double', 'BE');
export const double = doublebe;
export const doublele = new NumberT('Double', 'LE');
export class Fixed extends NumberT {
constructor(size, endian, fracBits = size >> 1) {
super(`Int${size}`, endian);
this._point = 1 << fracBits;
}
decode(stream) {
return super.decode(stream) / this._point;
}
encode(stream, val) {
return super.encode(stream, (val * this._point) | 0);
}
}
export const fixed16be = new Fixed(16, 'BE');
export const fixed16 = fixed16be;
export const fixed16le = new Fixed(16, 'LE');
export const fixed32be = new Fixed(32, 'BE');
export const fixed32 = fixed32be;
export const fixed32le = new Fixed(32, 'LE');

44
node_modules/restructure/src/Optional.js generated vendored Normal file
View File

@@ -0,0 +1,44 @@
import {Base} from './Base.js';
export class Optional extends Base {
constructor(type, condition = true) {
super();
this.type = type;
this.condition = condition;
}
decode(stream, parent) {
let { condition } = this;
if (typeof condition === 'function') {
condition = condition.call(parent, parent);
}
if (condition) {
return this.type.decode(stream, parent);
}
}
size(val, parent) {
let { condition } = this;
if (typeof condition === 'function') {
condition = condition.call(parent, parent);
}
if (condition) {
return this.type.size(val, parent);
} else {
return 0;
}
}
encode(stream, val, parent) {
let { condition } = this;
if (typeof condition === 'function') {
condition = condition.call(parent, parent);
}
if (condition) {
return this.type.encode(stream, val, parent);
}
}
}

167
node_modules/restructure/src/Pointer.js generated vendored Normal file
View File

@@ -0,0 +1,167 @@
import * as utils from './utils.js';
import {Base} from './Base.js';
export class Pointer extends Base {
constructor(offsetType, type, options = {}) {
super();
this.offsetType = offsetType;
this.type = type;
this.options = options;
if (this.type === 'void') { this.type = null; }
if (this.options.type == null) { this.options.type = 'local'; }
if (this.options.allowNull == null) { this.options.allowNull = true; }
if (this.options.nullValue == null) { this.options.nullValue = 0; }
if (this.options.lazy == null) { this.options.lazy = false; }
if (this.options.relativeTo) {
if (typeof this.options.relativeTo !== 'function') {
throw new Error('relativeTo option must be a function');
}
this.relativeToGetter = options.relativeTo;
}
}
decode(stream, ctx) {
const offset = this.offsetType.decode(stream, ctx);
// handle NULL pointers
if ((offset === this.options.nullValue) && this.options.allowNull) {
return null;
}
let relative;
switch (this.options.type) {
case 'local': relative = ctx._startOffset; break;
case 'immediate': relative = stream.pos - this.offsetType.size(); break;
case 'parent': relative = ctx.parent._startOffset; break;
default:
var c = ctx;
while (c.parent) {
c = c.parent;
}
relative = c._startOffset || 0;
}
if (this.options.relativeTo) {
relative += this.relativeToGetter(ctx);
}
const ptr = offset + relative;
if (this.type != null) {
let val = null;
const decodeValue = () => {
if (val != null) { return val; }
const { pos } = stream;
stream.pos = ptr;
val = this.type.decode(stream, ctx);
stream.pos = pos;
return val;
};
// If this is a lazy pointer, define a getter to decode only when needed.
// This obviously only works when the pointer is contained by a Struct.
if (this.options.lazy) {
return new utils.PropertyDescriptor({
get: decodeValue});
}
return decodeValue();
} else {
return ptr;
}
}
size(val, ctx) {
const parent = ctx;
switch (this.options.type) {
case 'local': case 'immediate':
break;
case 'parent':
ctx = ctx.parent;
break;
default: // global
while (ctx.parent) {
ctx = ctx.parent;
}
}
let { type } = this;
if (type == null) {
if (!(val instanceof VoidPointer)) {
throw new Error("Must be a VoidPointer");
}
({ type } = val);
val = val.value;
}
if (val && ctx) {
// Must be written as two separate lines rather than += in case `type.size` mutates ctx.pointerSize.
let size = type.size(val, parent);
ctx.pointerSize += size;
}
return this.offsetType.size();
}
encode(stream, val, ctx) {
let relative;
const parent = ctx;
if ((val == null)) {
this.offsetType.encode(stream, this.options.nullValue);
return;
}
switch (this.options.type) {
case 'local':
relative = ctx.startOffset;
break;
case 'immediate':
relative = stream.pos + this.offsetType.size(val, parent);
break;
case 'parent':
ctx = ctx.parent;
relative = ctx.startOffset;
break;
default: // global
relative = 0;
while (ctx.parent) {
ctx = ctx.parent;
}
}
if (this.options.relativeTo) {
relative += this.relativeToGetter(parent.val);
}
this.offsetType.encode(stream, ctx.pointerOffset - relative);
let { type } = this;
if (type == null) {
if (!(val instanceof VoidPointer)) {
throw new Error("Must be a VoidPointer");
}
({ type } = val);
val = val.value;
}
ctx.pointers.push({
type,
val,
parent
});
return ctx.pointerOffset += type.size(val, parent);
}
}
// A pointer whose type is determined at decode time
export class VoidPointer {
constructor(type, value) {
this.type = type;
this.value = value;
}
}

23
node_modules/restructure/src/Reserved.js generated vendored Normal file
View File

@@ -0,0 +1,23 @@
import {Base} from './Base.js';
import * as utils from './utils.js';
export class Reserved extends Base {
constructor(type, count = 1) {
super();
this.type = type;
this.count = count;
}
decode(stream, parent) {
stream.pos += this.size(null, parent);
return undefined;
}
size(data, parent) {
const count = utils.resolveLength(this.count, null, parent);
return this.type.size() * count;
}
encode(stream, val, parent) {
return stream.fill(0, this.size(val, parent));
}
}

155
node_modules/restructure/src/String.js generated vendored Normal file
View File

@@ -0,0 +1,155 @@
import {Base} from './Base.js';
import {Number as NumberT} from './Number.js';
import * as utils from './utils.js';
class StringT extends Base {
constructor(length, encoding = 'ascii') {
super();
this.length = length;
this.encoding = encoding;
}
decode(stream, parent) {
let length, pos;
let { encoding } = this;
if (typeof encoding === 'function') {
encoding = encoding.call(parent, parent) || 'ascii';
}
let width = encodingWidth(encoding);
if (this.length != null) {
length = utils.resolveLength(this.length, stream, parent);
} else {
let buffer;
({buffer, length, pos} = stream);
while ((pos < length - width + 1) &&
(buffer[pos] !== 0x00 ||
(width === 2 && buffer[pos+1] !== 0x00)
)) {
pos += width;
}
length = pos - stream.pos;
}
const string = stream.readString(length, encoding);
if ((this.length == null) && (stream.pos < stream.length)) {
stream.pos+=width;
}
return string;
}
size(val, parent) {
// Use the defined value if no value was given
if (val === undefined || val === null) {
return utils.resolveLength(this.length, null, parent);
}
let { encoding } = this;
if (typeof encoding === 'function') {
encoding = encoding.call(parent != null ? parent.val : undefined, parent != null ? parent.val : undefined) || 'ascii';
}
if (encoding === 'utf16be') {
encoding = 'utf16le';
}
let size = byteLength(val, encoding);
if (this.length instanceof NumberT) {
size += this.length.size();
}
if ((this.length == null)) {
size += encodingWidth(encoding);
}
return size;
}
encode(stream, val, parent) {
let { encoding } = this;
if (typeof encoding === 'function') {
encoding = encoding.call(parent != null ? parent.val : undefined, parent != null ? parent.val : undefined) || 'ascii';
}
if (this.length instanceof NumberT) {
this.length.encode(stream, byteLength(val, encoding));
}
stream.writeString(val, encoding);
if ((this.length == null)) {
return encodingWidth(encoding) == 2 ?
stream.writeUInt16LE(0x0000) :
stream.writeUInt8(0x00);
}
}
}
function encodingWidth(encoding) {
switch(encoding) {
case 'ascii':
case 'utf8': // utf8 is a byte-based encoding for zero-term string
return 1;
case 'utf16le':
case 'utf16-le':
case 'utf-16be':
case 'utf-16le':
case 'utf16be':
case 'utf16-be':
case 'ucs2':
return 2;
default:
//TODO: assume all other encodings are 1-byters
//throw new Error('Unknown encoding ' + encoding);
return 1;
}
}
function byteLength(string, encoding) {
switch (encoding) {
case 'ascii':
return string.length;
case 'utf8':
let len = 0;
for (let i = 0; i < string.length; i++) {
let c = string.charCodeAt(i);
if (c >= 0xd800 && c <= 0xdbff && i < string.length - 1) {
let c2 = string.charCodeAt(++i);
if ((c2 & 0xfc00) === 0xdc00) {
c = ((c & 0x3ff) << 10) + (c2 & 0x3ff) + 0x10000;
} else {
// unmatched surrogate.
i--;
}
}
if ((c & 0xffffff80) === 0) {
len++;
} else if ((c & 0xfffff800) === 0) {
len += 2;
} else if ((c & 0xffff0000) === 0) {
len += 3;
} else if ((c & 0xffe00000) === 0) {
len += 4;
}
}
return len;
case 'utf16le':
case 'utf16-le':
case 'utf16be':
case 'utf16-be':
case 'ucs2':
return string.length * 2;
default:
throw new Error('Unknown encoding ' + encoding);
}
}
export {StringT as String};

113
node_modules/restructure/src/Struct.js generated vendored Normal file
View File

@@ -0,0 +1,113 @@
import {Base} from './Base.js';
import * as utils from './utils.js';
export class Struct extends Base {
constructor(fields = {}) {
super();
this.fields = fields;
}
decode(stream, parent, length = 0) {
const res = this._setup(stream, parent, length);
this._parseFields(stream, res, this.fields);
if (this.process != null) {
this.process.call(res, stream);
}
return res;
}
_setup(stream, parent, length) {
const res = {};
// define hidden properties
Object.defineProperties(res, {
parent: { value: parent },
_startOffset: { value: stream.pos },
_currentOffset: { value: 0, writable: true },
_length: { value: length }
});
return res;
}
_parseFields(stream, res, fields) {
for (let key in fields) {
var val;
const type = fields[key];
if (typeof type === 'function') {
val = type.call(res, res);
} else {
val = type.decode(stream, res);
}
if (val !== undefined) {
if (val instanceof utils.PropertyDescriptor) {
Object.defineProperty(res, key, val);
} else {
res[key] = val;
}
}
res._currentOffset = stream.pos - res._startOffset;
}
}
size(val, parent, includePointers = true) {
if (val == null) { val = {}; }
const ctx = {
parent,
val,
pointerSize: 0
};
if (this.preEncode != null) {
this.preEncode.call(val);
}
let size = 0;
for (let key in this.fields) {
const type = this.fields[key];
if (type.size != null) {
size += type.size(val[key], ctx);
}
}
if (includePointers) {
size += ctx.pointerSize;
}
return size;
}
encode(stream, val, parent) {
let type;
if (this.preEncode != null) {
this.preEncode.call(val, stream);
}
const ctx = {
pointers: [],
startOffset: stream.pos,
parent,
val,
pointerSize: 0
};
ctx.pointerOffset = stream.pos + this.size(val, ctx, false);
for (let key in this.fields) {
type = this.fields[key];
if (type.encode != null) {
type.encode(stream, val[key], ctx);
}
}
let i = 0;
while (i < ctx.pointers.length) {
const ptr = ctx.pointers[i++];
ptr.type.encode(stream, ptr.val, ptr.parent);
}
}
}

139
node_modules/restructure/src/VersionedStruct.js generated vendored Normal file
View File

@@ -0,0 +1,139 @@
import {Struct} from './Struct.js';
const getPath = (object, pathArray) => {
return pathArray.reduce((prevObj, key) => prevObj && prevObj[key], object);
};
export class VersionedStruct extends Struct {
constructor(type, versions = {}) {
super();
this.type = type;
this.versions = versions;
if (typeof type === 'string') {
this.versionPath = type.split('.');
}
}
decode(stream, parent, length = 0) {
const res = this._setup(stream, parent, length);
if (typeof this.type === 'string') {
res.version = getPath(parent, this.versionPath);
} else {
res.version = this.type.decode(stream);
}
if (this.versions.header) {
this._parseFields(stream, res, this.versions.header);
}
const fields = this.versions[res.version];
if ((fields == null)) {
throw new Error(`Unknown version ${res.version}`);
}
if (fields instanceof VersionedStruct) {
return fields.decode(stream, parent);
}
this._parseFields(stream, res, fields);
if (this.process != null) {
this.process.call(res, stream);
}
return res;
}
size(val, parent, includePointers = true) {
let key, type;
if (!val) {
throw new Error('Not a fixed size');
}
if (this.preEncode != null) {
this.preEncode.call(val);
}
const ctx = {
parent,
val,
pointerSize: 0
};
let size = 0;
if (typeof this.type !== 'string') {
size += this.type.size(val.version, ctx);
}
if (this.versions.header) {
for (key in this.versions.header) {
type = this.versions.header[key];
if (type.size != null) {
size += type.size(val[key], ctx);
}
}
}
const fields = this.versions[val.version];
if ((fields == null)) {
throw new Error(`Unknown version ${val.version}`);
}
for (key in fields) {
type = fields[key];
if (type.size != null) {
size += type.size(val[key], ctx);
}
}
if (includePointers) {
size += ctx.pointerSize;
}
return size;
}
encode(stream, val, parent) {
let key, type;
if (this.preEncode != null) {
this.preEncode.call(val, stream);
}
const ctx = {
pointers: [],
startOffset: stream.pos,
parent,
val,
pointerSize: 0
};
ctx.pointerOffset = stream.pos + this.size(val, ctx, false);
if (typeof this.type !== 'string') {
this.type.encode(stream, val.version);
}
if (this.versions.header) {
for (key in this.versions.header) {
type = this.versions.header[key];
if (type.encode != null) {
type.encode(stream, val[key], ctx);
}
}
}
const fields = this.versions[val.version];
for (key in fields) {
type = fields[key];
if (type.encode != null) {
type.encode(stream, val[key], ctx);
}
}
let i = 0;
while (i < ctx.pointers.length) {
const ptr = ctx.pointers[i++];
ptr.type.encode(stream, ptr.val, ptr.parent);
}
}
}

35
node_modules/restructure/src/utils.js generated vendored Normal file
View File

@@ -0,0 +1,35 @@
import {Number as NumberT} from './Number.js';
export function resolveLength(length, stream, parent) {
let res;
if (typeof length === 'number') {
res = length;
} else if (typeof length === 'function') {
res = length.call(parent, parent);
} else if (parent && (typeof length === 'string')) {
res = parent[length];
} else if (stream && length instanceof NumberT) {
res = length.decode(stream);
}
if (isNaN(res)) {
throw new Error('Not a fixed size');
}
return res;
};
export class PropertyDescriptor {
constructor(opts = {}) {
this.enumerable = true;
this.configurable = true;
for (let key in opts) {
const val = opts[key];
this[key] = val;
}
}
}

103
node_modules/restructure/test/Array.js generated vendored Normal file
View File

@@ -0,0 +1,103 @@
import assert from 'assert';
import {Array as ArrayT, Pointer, uint8, uint16, DecodeStream, EncodeStream} from 'restructure';
describe('Array', function() {
describe('decode', function() {
it('should decode fixed length', function() {
const buffer = new Uint8Array([1, 2, 3, 4, 5]);
const array = new ArrayT(uint8, 4);
assert.deepEqual(array.fromBuffer(buffer), [1, 2, 3, 4]);
});
it('should decode fixed amount of bytes', function() {
const buffer = new Uint8Array([1, 2, 3, 4, 5]);
const array = new ArrayT(uint16, 4, 'bytes');
assert.deepEqual(array.fromBuffer(buffer), [258, 772]);
});
it('should decode length from parent key', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 3, 4, 5]));
const array = new ArrayT(uint8, 'len');
assert.deepEqual(array.decode(stream, {len: 4}), [1, 2, 3, 4]);
});
it('should decode amount of bytes from parent key', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 3, 4, 5]));
const array = new ArrayT(uint16, 'len', 'bytes');
assert.deepEqual(array.decode(stream, {len: 4}), [258, 772]);
});
it('should decode length as number before array', function() {
const buffer = new Uint8Array([4, 1, 2, 3, 4, 5]);
const array = new ArrayT(uint8, uint8);
assert.deepEqual(array.fromBuffer(buffer), [1, 2, 3, 4]);
});
it('should decode amount of bytes as number before array', function() {
const buffer = new Uint8Array([4, 1, 2, 3, 4, 5]);
const array = new ArrayT(uint16, uint8, 'bytes');
assert.deepEqual(array.fromBuffer(buffer), [258, 772]);
});
it('should decode length from function', function() {
const buffer = new Uint8Array([1, 2, 3, 4, 5]);
const array = new ArrayT(uint8, function() { return 4; });
assert.deepEqual(array.fromBuffer(buffer), [1, 2, 3, 4]);
});
it('should decode amount of bytes from function', function() {
const buffer = new Uint8Array([1, 2, 3, 4, 5]);
const array = new ArrayT(uint16, (function() { return 4; }), 'bytes');
assert.deepEqual(array.fromBuffer(buffer), [258, 772]);
});
it('should decode to the end of the parent if no length is given', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 3, 4, 5]));
const array = new ArrayT(uint8);
assert.deepEqual(array.decode(stream, {_length: 4, _startOffset: 0}), [1, 2, 3, 4]);
});
it('should decode to the end of the stream if no parent and length is given', function() {
const buffer = new Uint8Array([1, 2, 3, 4]);
const array = new ArrayT(uint8);
assert.deepEqual(array.fromBuffer(buffer), [1, 2, 3, 4]);
});
});
describe('size', function() {
it('should use array length', function() {
const array = new ArrayT(uint8, 10);
assert.equal(array.size([1, 2, 3, 4]), 4);
});
it('should add size of length field before string', function() {
const array = new ArrayT(uint8, uint8);
assert.equal(array.size([1, 2, 3, 4]), 5);
});
it('should use defined length if no value given', function() {
const array = new ArrayT(uint8, 10);
assert.equal(array.size(), 10);
});
});
describe('encode', function() {
it('should encode using array length', function() {
const array = new ArrayT(uint8, 10);
const buffer = array.toBuffer([1, 2, 3, 4]);
assert.deepEqual(buffer, new Uint8Array([1, 2, 3, 4]));
});
it('should encode length as number before array', function() {
const array = new ArrayT(uint8, uint8);
const buffer = array.toBuffer([1, 2, 3, 4]);
assert.deepEqual(buffer, new Uint8Array([4, 1, 2, 3, 4]));
});
it('should add pointers after array if length is encoded at start', function() {
const array = new ArrayT(new Pointer(uint8, uint8), uint8);
const buffer = array.toBuffer([1, 2, 3, 4]);
assert.deepEqual(buffer, new Uint8Array([4, 5, 6, 7, 8, 1, 2, 3, 4]));
});
});
});

29
node_modules/restructure/test/Bitfield.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
import assert from 'assert';
import {Bitfield, uint8, DecodeStream, EncodeStream} from 'restructure';
describe('Bitfield', function() {
const bitfield = new Bitfield(uint8, ['Jack', 'Kack', 'Lack', 'Mack', 'Nack', 'Oack', 'Pack', 'Quack']);
const JACK = 1 << 0;
const KACK = 1 << 1;
const LACK = 1 << 2;
const MACK = 1 << 3;
const NACK = 1 << 4;
const OACK = 1 << 5;
const PACK = 1 << 6;
const QUACK = 1 << 7;
it('should have the right size', () => assert.equal(bitfield.size(), 1));
it('should decode', function() {
const buffer = new Uint8Array([JACK | MACK | PACK | NACK | QUACK]);
assert.deepEqual(
bitfield.fromBuffer(buffer),
{Jack: true, Kack: false, Lack: false, Mack: true, Nack: true, Oack: false, Pack: true, Quack: true}
);
});
it('should encode', function() {
let buffer = bitfield.toBuffer({Jack: true, Kack: false, Lack: false, Mack: true, Nack: true, Oack: false, Pack: true, Quack: true});
assert.deepEqual(buffer, Buffer.from([JACK | MACK | PACK | NACK | QUACK]));
});
});

39
node_modules/restructure/test/Boolean.js generated vendored Normal file
View File

@@ -0,0 +1,39 @@
import assert from 'assert';
import {Boolean, uint8, DecodeStream, EncodeStream} from 'restructure';
describe('Boolean', function() {
describe('decode', function() {
it('should decode 0 as false', function() {
const buffer = new Uint8Array([0]);
const boolean = new Boolean(uint8);
assert.deepEqual(boolean.fromBuffer(buffer), false);
});
it('should decode 1 as true', function() {
const buffer = new Uint8Array([1]);
const boolean = new Boolean(uint8);
assert.deepEqual(boolean.fromBuffer(buffer), true);
});
});
describe('size', () =>
it('should return given type size', function() {
const boolean = new Boolean(uint8);
assert.deepEqual(boolean.size(), 1);
})
);
describe('encode', function() {
it('should encode false as 0', function() {
const boolean = new Boolean(uint8);
const buffer = boolean.toBuffer(false);
assert.deepEqual(buffer, Buffer.from([0]));
});
it('should encode true as 1', function() {
const boolean = new Boolean(uint8);
const buffer = boolean.toBuffer(true);
assert.deepEqual(buffer, Buffer.from([1]));
});
});
});

45
node_modules/restructure/test/Buffer.js generated vendored Normal file
View File

@@ -0,0 +1,45 @@
import assert from 'assert';
import {Buffer as BufferT, uint8, DecodeStream, EncodeStream} from 'restructure';
describe('Buffer', function() {
describe('decode', function() {
it('should decode', function() {
const buffer = new Uint8Array([0xab, 0xff]);
const buf = new BufferT(2);
assert.deepEqual(buf.fromBuffer(buffer), new Uint8Array([0xab, 0xff]));
});
it('should decode with parent key length', function() {
const stream = new DecodeStream(new Uint8Array([0xab, 0xff, 0x1f, 0xb6]));
const buf = new BufferT('len');
assert.deepEqual(buf.decode(stream, {len: 3}), new Uint8Array([0xab, 0xff, 0x1f]));
assert.deepEqual(buf.decode(stream, {len: 1}), new Uint8Array([0xb6]));
});
});
describe('size', function() {
it('should return size', function() {
const buf = new BufferT(2);
assert.equal(buf.size(new Uint8Array([0xab, 0xff])), 2);
});
it('should use defined length if no value given', function() {
const array = new BufferT(10);
assert.equal(array.size(), 10);
});
});
describe('encode', function() {
it('should encode', function() {
const buf = new BufferT(2);
const buffer = buf.toBuffer(new Uint8Array([0xab, 0xff]));
assert.deepEqual(buffer, new Uint8Array([0xab, 0xff]));
});
it('should encode length before buffer', function() {
const buf = new BufferT(uint8);
const buffer = buf.toBuffer(new Uint8Array([0xab, 0xff]));
assert.deepEqual(buffer, new Uint8Array([2, 0xab, 0xff]));
});
});
});

101
node_modules/restructure/test/DecodeStream.js generated vendored Normal file
View File

@@ -0,0 +1,101 @@
import {DecodeStream} from 'restructure';
import assert from 'assert';
describe('DecodeStream', function() {
it('should read a buffer', function() {
const buf = new Uint8Array([1,2,3]);
const stream = new DecodeStream(buf);
assert.deepEqual(stream.readBuffer(buf.length), new Uint8Array([1,2,3]));
});
it('should readUInt16BE', function() {
const buf = new Uint8Array([0xab, 0xcd]);
const stream = new DecodeStream(buf);
assert.deepEqual(stream.readUInt16BE(), 0xabcd);
});
it('should readUInt16LE', function() {
const buf = new Uint8Array([0xab, 0xcd]);
const stream = new DecodeStream(buf);
assert.deepEqual(stream.readUInt16LE(), 0xcdab);
});
it('should readUInt24BE', function() {
const buf = new Uint8Array([0xab, 0xcd, 0xef]);
const stream = new DecodeStream(buf);
assert.deepEqual(stream.readUInt24BE(), 0xabcdef);
});
it('should readUInt24LE', function() {
const buf = new Uint8Array([0xab, 0xcd, 0xef]);
const stream = new DecodeStream(buf);
assert.deepEqual(stream.readUInt24LE(), 0xefcdab);
});
it('should readInt24BE', function() {
const buf = new Uint8Array([0xff, 0xab, 0x24]);
const stream = new DecodeStream(buf);
assert.deepEqual(stream.readInt24BE(), -21724);
});
it('should readInt24LE', function() {
const buf = new Uint8Array([0x24, 0xab, 0xff]);
const stream = new DecodeStream(buf);
assert.deepEqual(stream.readInt24LE(), -21724);
});
describe('readString', function() {
it('should decode ascii by default', function() {
const buf = Buffer.from('some text', 'ascii');
const stream = new DecodeStream(buf);
assert.equal(stream.readString(buf.length), 'some text');
});
it('should decode ascii', function() {
const buf = Buffer.from('some text', 'ascii');
const stream = new DecodeStream(buf);
assert.equal(stream.readString(buf.length, 'ascii'), 'some text');
});
it('should decode utf8', function() {
const buf = Buffer.from('unicode! 👍', 'utf8');
const stream = new DecodeStream(buf);
assert.equal(stream.readString(buf.length, 'utf8'), 'unicode! 👍');
});
it('should decode utf16le', function() {
const buf = Buffer.from('unicode! 👍', 'utf16le');
const stream = new DecodeStream(buf);
assert.equal(stream.readString(buf.length, 'utf16le'), 'unicode! 👍');
});
it('should decode ucs2', function() {
const buf = Buffer.from('unicode! 👍', 'ucs2');
const stream = new DecodeStream(buf);
assert.equal(stream.readString(buf.length, 'ucs2'), 'unicode! 👍');
});
it('should decode utf16be', function() {
const buf = Buffer.from('unicode! 👍', 'utf16le');
for (let i = 0, end = buf.length - 1; i < end; i += 2) {
const byte = buf[i];
buf[i] = buf[i + 1];
buf[i + 1] = byte;
}
const stream = new DecodeStream(buf);
assert.equal(stream.readString(buf.length, 'utf16be'), 'unicode! 👍');
});
it('should decode macroman', function() {
const buf = new Uint8Array([0x8a, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x63, 0x68, 0x87, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73]);
const stream = new DecodeStream(buf);
assert.equal(stream.readString(buf.length, 'mac'), 'äccented cháracters');
});
it('should return a buffer for unsupported encodings', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 3]));
assert.deepEqual(stream.readString(3, 'unsupported'), new Uint8Array([1, 2, 3]));
});
});
});

104
node_modules/restructure/test/EncodeStream.js generated vendored Normal file
View File

@@ -0,0 +1,104 @@
import {EncodeStream} from 'restructure';
import assert from 'assert';
describe('EncodeStream', function() {
it('should write a buffer', function() {
const stream = new EncodeStream(new Uint8Array(3));
stream.writeBuffer(new Uint8Array([1,2,3]));
assert.deepEqual(stream.buffer, new Uint8Array([1,2,3]));
});
it('should writeUInt16BE', function() {
const stream = new EncodeStream(new Uint8Array(2));
stream.writeUInt16BE(0xabcd);
assert.deepEqual(stream.buffer, new Uint8Array([0xab, 0xcd]));
});
it('should writeUInt16LE', function() {
const stream = new EncodeStream(new Uint8Array(2));
stream.writeUInt16LE(0xcdab);
assert.deepEqual(stream.buffer, new Uint8Array([0xab, 0xcd]));
});
it('should writeUInt24BE', function() {
const stream = new EncodeStream(new Uint8Array(3));
stream.writeUInt24BE(0xabcdef);
assert.deepEqual(stream.buffer, new Uint8Array([0xab, 0xcd, 0xef]));
});
it('should writeUInt24LE', function() {
const stream = new EncodeStream(new Uint8Array(3));
stream.writeUInt24LE(0xabcdef);
assert.deepEqual(stream.buffer, new Uint8Array([0xef, 0xcd, 0xab]));
});
it('should writeInt24BE', function() {
const stream = new EncodeStream(new Uint8Array(6));
stream.writeInt24BE(-21724);
stream.writeInt24BE(0xabcdef);
assert.deepEqual(stream.buffer, new Uint8Array([0xff, 0xab, 0x24, 0xab, 0xcd, 0xef]));
});
it('should writeInt24LE', function() {
const stream = new EncodeStream(new Uint8Array(6));
stream.writeInt24LE(-21724);
stream.writeInt24LE(0xabcdef);
assert.deepEqual(stream.buffer, new Uint8Array([0x24, 0xab, 0xff, 0xef, 0xcd, 0xab]));
});
it('should fill', function() {
const stream = new EncodeStream(new Uint8Array(5));
stream.fill(10, 5);
assert.deepEqual(stream.buffer, new Uint8Array([10, 10, 10, 10, 10]));
});
describe('writeString', function() {
it('should encode ascii by default', function() {
const expected = Buffer.from('some text', 'ascii');
const stream = new EncodeStream(new Uint8Array(expected.length));
stream.writeString('some text');
assert.deepEqual(stream.buffer, expected);
});
it('should encode ascii', function() {
const expected = Buffer.from('some text', 'ascii');
const stream = new EncodeStream(new Uint8Array(expected.length));
stream.writeString('some text', 'ascii');
assert.deepEqual(stream.buffer, expected);
});
it('should encode utf8', function() {
const expected = Buffer.from('unicode! 👍', 'utf8');
const stream = new EncodeStream(new Uint8Array(expected.length));
stream.writeString('unicode! 👍', 'utf8');
assert.deepEqual(stream.buffer, expected);
});
it('should encode utf16le', function() {
const expected = Buffer.from('unicode! 👍', 'utf16le');
const stream = new EncodeStream(new Uint8Array(expected.length));
stream.writeString('unicode! 👍', 'utf16le');
assert.deepEqual(stream.buffer, expected);
});
it('should encode ucs2', function() {
const expected = Buffer.from('unicode! 👍', 'ucs2');
const stream = new EncodeStream(new Uint8Array(expected.length));
stream.writeString('unicode! 👍', 'ucs2');
assert.deepEqual(stream.buffer, expected);
});
it('should encode utf16be', function() {
const expected = Buffer.from('unicode! 👍', 'utf16le');
for (let i = 0, end = expected.length - 1; i < end; i += 2) {
const byte = expected[i];
expected[i] = expected[i + 1];
expected[i + 1] = byte;
}
const stream = new EncodeStream(new Uint8Array(expected.length));
stream.writeString('unicode! 👍', 'utf16be');
assert.deepEqual(stream.buffer, expected);
});
});
});

24
node_modules/restructure/test/Enum.js generated vendored Normal file
View File

@@ -0,0 +1,24 @@
import assert from 'assert';
import {Enum, uint8, DecodeStream, EncodeStream} from 'restructure';
describe('Enum', function() {
const e = new Enum(uint8, ['foo', 'bar', 'baz']);
it('should have the right size', () => assert.equal(e.size(), 1));
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 0]));
assert.equal(e.decode(stream), 'bar');
assert.equal(e.decode(stream), 'baz');
assert.equal(e.decode(stream), 'foo');
});
it('should encode', function() {
assert.deepEqual(e.toBuffer('bar'), new Uint8Array([1]));
assert.deepEqual(e.toBuffer('baz'), new Uint8Array([2]));
assert.deepEqual(e.toBuffer('foo'), new Uint8Array([0]));
});
it('should throw on unknown option', function() {
return assert.throws(() => e.toBuffer('unknown'));
});
});

59
node_modules/restructure/test/LazyArray.js generated vendored Normal file
View File

@@ -0,0 +1,59 @@
import assert from 'assert';
import {LazyArray, Pointer, uint8, uint16, DecodeStream, EncodeStream} from 'restructure';
describe('LazyArray', function() {
describe('decode', function() {
it('should decode items lazily', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
assert(!(arr instanceof Array));
assert.equal(arr.length, 4);
assert.equal(stream.pos, 4);
assert.equal(arr.get(0), 1);
assert.equal(arr.get(1), 2);
assert.equal(arr.get(2), 3);
assert.equal(arr.get(3), 4);
assert.equal(arr.get(-1), null);
assert.equal(arr.get(5), null);
});
it('should be able to convert to an array', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
assert.deepEqual(arr.toArray(), [1, 2, 3, 4]);
});
it('should decode length as number before array', function() {
const stream = new DecodeStream(new Uint8Array([4, 1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, uint8);
const arr = array.decode(stream);
assert.deepEqual(arr.toArray(), [1, 2, 3, 4]);
});
});
describe('size', () =>
it('should work with LazyArrays', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
assert.equal(array.size(arr), 4);
})
);
describe('encode', () =>
it('should work with LazyArrays', function() {
const array = new LazyArray(uint8, 4);
const arr = array.fromBuffer(new Uint8Array([1, 2, 3, 4, 5]));
const buffer = array.toBuffer(arr);
assert.deepEqual(buffer, new Uint8Array([1, 2, 3, 4]));
})
);
});

356
node_modules/restructure/test/Number.js generated vendored Normal file
View File

@@ -0,0 +1,356 @@
import {
uint8,
uint16, uint16be, uint16le,
uint24, uint24be, uint24le,
uint32, uint32be, uint32le,
int8,
int16, int16be, int16le,
int24, int24be, int24le,
int32, int32be, int32le,
float, floatbe, floatle,
double, doublebe, doublele,
fixed16, fixed16be, fixed16le,
fixed32, fixed32be, fixed32le,
DecodeStream, EncodeStream
} from 'restructure';
import assert from 'assert';
describe('Number', function() {
describe('uint8', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xab, 0xff]));
assert.equal(uint8.decode(stream), 0xab);
assert.equal(uint8.decode(stream), 0xff);
});
it('should have a size', () => assert.equal(uint8.size(), 1));
it('should encode', function() {
assert.deepEqual(uint8.toBuffer(0xab), new Uint8Array([0xab]));
assert.deepEqual(uint8.toBuffer(0xff), new Uint8Array([0xff]));
});
});
describe('uint16', () =>
it('is an alias for uint16be', () => assert.deepEqual(uint16, uint16be))
);
describe('uint16be', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xab, 0xff]));
assert.equal(uint16be.decode(stream), 0xabff);
});
it('should have a size', () => assert.equal(uint16be.size(), 2));
it('should encode', function() {
assert.deepEqual(uint16be.toBuffer(0xabff), new Uint8Array([0xab, 0xff]));
});
});
describe('uint16le', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xff, 0xab]));
assert.equal(uint16le.decode(stream), 0xabff);
});
it('should have a size', () => assert.equal(uint16le.size(), 2));
it('should encode', function() {
assert.deepEqual(uint16le.toBuffer(0xabff), new Uint8Array([0xff, 0xab]));
});
});
describe('uint24', () =>
it('is an alias for uint24be', () => assert.deepEqual(uint24, uint24be))
);
describe('uint24be', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xff, 0xab, 0x24]));
assert.equal(uint24be.decode(stream), 0xffab24);
});
it('should have a size', () => assert.equal(uint24be.size(), 3));
it('should encode', function() {
assert.deepEqual(uint24be.toBuffer(0xffab24), new Uint8Array([0xff, 0xab, 0x24]));
});
});
describe('uint24le', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0x24, 0xab, 0xff]));
assert.equal(uint24le.decode(stream), 0xffab24);
});
it('should have a size', () => assert.equal(uint24le.size(), 3));
it('should encode', function() {
assert.deepEqual(uint24le.toBuffer(0xffab24), new Uint8Array([0x24, 0xab, 0xff]));
});
});
describe('uint32', () =>
it('is an alias for uint32be', () => assert.deepEqual(uint32, uint32be))
);
describe('uint32be', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xff, 0xab, 0x24, 0xbf]));
assert.equal(uint32be.decode(stream), 0xffab24bf);
});
it('should have a size', () => assert.equal(uint32be.size(), 4));
it('should encode', function() {
assert.deepEqual(uint32be.toBuffer(0xffab24bf), new Uint8Array([0xff, 0xab, 0x24, 0xbf]));
});
});
describe('uint32le', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xbf, 0x24, 0xab, 0xff]));
assert.equal(uint32le.decode(stream), 0xffab24bf);
});
it('should have a size', () => assert.equal(uint32le.size(), 4));
it('should encode', function() {
assert.deepEqual(uint32le.toBuffer(0xffab24bf), new Uint8Array([0xbf, 0x24, 0xab, 0xff]));
});
});
describe('int8', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0x7f, 0xff]));
assert.equal(int8.decode(stream), 127);
assert.equal(int8.decode(stream), -1);
});
it('should have a size', () => assert.equal(int8.size(), 1));
it('should encode', function() {
assert.deepEqual(uint8.toBuffer(127), new Uint8Array([0x7f]));
assert.deepEqual(uint8.toBuffer(-1), new Uint8Array([0xff]));
});
});
describe('int16', () =>
it('is an alias for int16be', () => assert.deepEqual(int16, int16be))
);
describe('int16be', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xff, 0xab]));
assert.equal(int16be.decode(stream), -85);
});
it('should have a size', () => assert.equal(int16be.size(), 2));
it('should encode', function() {
assert.deepEqual(int16be.toBuffer(-85), new Uint8Array([0xff, 0xab]));
});
});
describe('int16le', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xab, 0xff]));
assert.equal(int16le.decode(stream), -85);
});
it('should have a size', () => assert.equal(int16le.size(), 2));
it('should encode', function() {
assert.deepEqual(int16le.toBuffer(-85), new Uint8Array([0xab, 0xff]));
});
});
describe('int24', () =>
it('is an alias for int24be', () => assert.deepEqual(int24, int24be))
);
describe('int24be', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xff, 0xab, 0x24]));
assert.equal(int24be.decode(stream), -21724);
});
it('should have a size', () => assert.equal(int24be.size(), 3));
it('should encode', function() {
assert.deepEqual(int24be.toBuffer(-21724), new Uint8Array([0xff, 0xab, 0x24]));
});
});
describe('int24le', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0x24, 0xab, 0xff]));
assert.equal(int24le.decode(stream), -21724);
});
it('should have a size', () => assert.equal(int24le.size(), 3));
it('should encode', function() {
assert.deepEqual(int24le.toBuffer(-21724), new Uint8Array([0x24, 0xab, 0xff]));
});
});
describe('int32', () =>
it('is an alias for int32be', () => assert.deepEqual(int32, int32be))
);
describe('int32be', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xff, 0xab, 0x24, 0xbf]));
assert.equal(int32be.decode(stream), -5561153);
});
it('should have a size', () => assert.equal(int32be.size(), 4));
it('should encode', function() {
assert.deepEqual(int32be.toBuffer(-5561153), new Uint8Array([0xff, 0xab, 0x24, 0xbf]));
});
});
describe('int32le', function() {
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0xbf, 0x24, 0xab, 0xff]));
assert.equal(int32le.decode(stream), -5561153);
});
it('should have a size', () => assert.equal(int32le.size(), 4));
it('should encode', function() {
assert.deepEqual(int32le.toBuffer(-5561153), new Uint8Array([0xbf, 0x24, 0xab, 0xff]));
});
});
describe('float', () =>
it('is an alias for floatbe', () => assert.deepEqual(float, floatbe))
);
describe('floatbe', function() {
it('should decode', function() {
const value = floatbe.fromBuffer(new Uint8Array([0x43, 0x7a, 0x8c, 0xcd]));
assert(value >= 250.55 - 0.005);
assert(value <= 250.55 + 0.005);
});
it('should have a size', () => assert.equal(floatbe.size(), 4));
it('should encode', function() {
assert.deepEqual(floatbe.toBuffer(250.55), new Uint8Array([0x43, 0x7a, 0x8c, 0xcd]));
});
});
describe('floatle', function() {
it('should decode', function() {
const value = floatle.fromBuffer(new Uint8Array([0xcd, 0x8c, 0x7a, 0x43]));
assert(value >= 250.55 - 0.005);
assert(value <= 250.55 + 0.005);
});
it('should have a size', () => assert.equal(floatle.size(), 4));
it('should encode', function() {
assert.deepEqual(floatle.toBuffer(250.55), new Uint8Array([0xcd, 0x8c, 0x7a, 0x43]));
});
});
describe('double', () =>
it('is an alias for doublebe', () => assert.deepEqual(double, doublebe))
);
describe('doublebe', function() {
it('should decode', function() {
const value = doublebe.fromBuffer(new Uint8Array([0x40, 0x93, 0x4a, 0x3d, 0x70, 0xa3, 0xd7, 0x0a]));
assert(value >= 1234.56 - 0.005);
assert(value <= 1234.56 + 0.005);
});
it('should have a size', () => assert.equal(doublebe.size(), 8));
it('should encode', function() {
assert.deepEqual(doublebe.toBuffer(1234.56), new Uint8Array([0x40, 0x93, 0x4a, 0x3d, 0x70, 0xa3, 0xd7, 0x0a]));
});
});
describe('doublele', function() {
it('should decode', function() {
const value = doublele.fromBuffer(new Uint8Array([0x0a, 0xd7, 0xa3, 0x70, 0x3d, 0x4a, 0x93, 0x40]));
assert(value >= 1234.56 - 0.005);
assert(value <= 1234.56 + 0.005);
});
it('should have a size', () => assert.equal(doublele.size(), 8));
it('should encode', function() {
assert.deepEqual(doublele.toBuffer(1234.56), new Uint8Array([0x0a, 0xd7, 0xa3, 0x70, 0x3d, 0x4a, 0x93, 0x40]));
});
});
describe('fixed16', () =>
it('is an alias for fixed16be', () => assert.deepEqual(fixed16, fixed16be))
);
describe('fixed16be', function() {
it('should decode', function() {
const value = fixed16be.fromBuffer(new Uint8Array([0x19, 0x57]));
assert(value >= 25.34 - 0.005);
assert(value <= 25.34 + 0.005);
});
it('should have a size', () => assert.equal(fixed16be.size(), 2));
it('should encode', function() {
assert.deepEqual(fixed16be.toBuffer(25.34), new Uint8Array([0x19, 0x57]));
});
});
describe('fixed16le', function() {
it('should decode', function() {
const value = fixed16le.fromBuffer(new Uint8Array([0x57, 0x19]));
assert(value >= 25.34 - 0.005);
assert(value <= 25.34 + 0.005);
});
it('should have a size', () => assert.equal(fixed16le.size(), 2));
it('should encode', function() {
assert.deepEqual(fixed16le.toBuffer(25.34), new Uint8Array([0x57, 0x19]));
});
});
describe('fixed32', () =>
it('is an alias for fixed32be', () => assert.deepEqual(fixed32, fixed32be))
);
describe('fixed32be', function() {
it('should decode', function() {
const value = fixed32be.fromBuffer(new Uint8Array([0x00, 0xfa, 0x8c, 0xcc]));
assert(value >= 250.55 - 0.005);
assert(value <= 250.55 + 0.005);
});
it('should have a size', () => assert.equal(fixed32be.size(), 4));
it('should encode', function() {
assert.deepEqual(fixed32be.toBuffer(250.55), new Uint8Array([0x00, 0xfa, 0x8c, 0xcc]));
});
});
describe('fixed32le', function() {
it('should decode', function() {
const value = fixed32le.fromBuffer(new Uint8Array([0xcc, 0x8c, 0xfa, 0x00]));
assert(value >= 250.55 - 0.005);
assert(value <= 250.55 + 0.005);
});
it('should have a size', () => assert.equal(fixed32le.size(), 4));
it('should encode', function() {
assert.deepEqual(fixed32le.toBuffer(250.55), new Uint8Array([0xcc, 0x8c, 0xfa, 0x00]));
});
});
});

100
node_modules/restructure/test/Optional.js generated vendored Normal file
View File

@@ -0,0 +1,100 @@
import assert from 'assert';
import {Optional, uint8, DecodeStream, EncodeStream} from 'restructure';
describe('Optional', function() {
describe('decode', function() {
it('should not decode when condition is falsy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, false);
assert.equal(optional.decode(stream), null);
assert.equal(stream.pos, 0);
});
it('should not decode when condition is a function and falsy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, function() { return false; });
assert.equal(optional.decode(stream), null);
assert.equal(stream.pos, 0);
});
it('should decode when condition is omitted', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8);
assert(optional.decode(stream) != null);
assert.equal(stream.pos, 1);
});
it('should decode when condition is truthy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, true);
assert(optional.decode(stream) != null);
assert.equal(stream.pos, 1);
});
it('should decode when condition is a function and truthy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, function() { return true; });
assert(optional.decode(stream) != null);
assert.equal(stream.pos, 1);
});
});
describe('size', function() {
it('should return 0 when condition is falsy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, false);
assert.equal(optional.size(), 0);
});
it('should return 0 when condition is a function and falsy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, function() { return false; });
assert.equal(optional.size(), 0);
});
it('should return given type size when condition is omitted', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8);
assert.equal(optional.size(), 1);
});
it('should return given type size when condition is truthy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, true);
assert.equal(optional.size(), 1);
});
it('should return given type size when condition is a function and truthy', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const optional = new Optional(uint8, function() { return true; });
assert.equal(optional.size(), 1);
});
});
describe('encode', function() {
it('should not encode when condition is falsy', function() {
const optional = new Optional(uint8, false);
assert.deepEqual(optional.toBuffer(128), new Uint8Array(0));
});
it('should not encode when condition is a function and falsy', function() {
const optional = new Optional(uint8, function() { return false; });
assert.deepEqual(optional.toBuffer(128), new Uint8Array(0));
});
it('should encode when condition is omitted', function() {
const optional = new Optional(uint8);
assert.deepEqual(optional.toBuffer(128), new Uint8Array([128]));
});
it('should encode when condition is truthy', function() {
const optional = new Optional(uint8, true);
assert.deepEqual(optional.toBuffer(128), new Uint8Array([128]));
});
it('should encode when condition is a function and truthy', function() {
const optional = new Optional(uint8, function() { return true; });
assert.deepEqual(optional.toBuffer(128), new Uint8Array([128]));
});
});
});

289
node_modules/restructure/test/Pointer.js generated vendored Normal file
View File

@@ -0,0 +1,289 @@
import assert from 'assert';
import {Pointer, VoidPointer, uint8, DecodeStream, EncodeStream, Struct} from 'restructure';
describe('Pointer', function() {
describe('decode', function() {
it('should handle null pointers', function() {
const stream = new DecodeStream(new Uint8Array([0]));
const pointer = new Pointer(uint8, uint8);
return assert.equal(pointer.decode(stream, {_startOffset: 50}), null);
});
it('should use local offsets from start of parent by default', function() {
const stream = new DecodeStream(new Uint8Array([1, 53]));
const pointer = new Pointer(uint8, uint8);
assert.equal(pointer.decode(stream, {_startOffset: 0}), 53);
});
it('should support immediate offsets', function() {
const stream = new DecodeStream(new Uint8Array([1, 53]));
const pointer = new Pointer(uint8, uint8, {type: 'immediate'});
assert.equal(pointer.decode(stream), 53);
});
it('should support offsets relative to the parent', function() {
const stream = new DecodeStream(new Uint8Array([0, 0, 1, 53]));
stream.pos = 2;
const pointer = new Pointer(uint8, uint8, {type: 'parent'});
assert.equal(pointer.decode(stream, {parent: {_startOffset: 2}}), 53);
});
it('should support global offsets', function() {
const stream = new DecodeStream(new Uint8Array([1, 2, 4, 0, 0, 0, 53]));
const pointer = new Pointer(uint8, uint8, {type: 'global'});
stream.pos = 2;
assert.equal(pointer.decode(stream, {parent: {parent: {_startOffset: 2}}}), 53);
});
it('should support offsets relative to a property on the parent', function() {
const stream = new DecodeStream(new Uint8Array([1, 0, 0, 0, 0, 53]));
const pointer = new Pointer(uint8, uint8, {relativeTo: ctx => ctx.parent.ptr});
assert.equal(pointer.decode(stream, {_startOffset: 0, parent: {ptr: 4}}), 53);
});
it('should throw when passing a non function relativeTo option', function() {
return assert.throws(() => new Pointer(uint8, uint8, {relativeTo: 'parent.ptr'}));
});
it('should support returning pointer if there is no decode type', function() {
const stream = new DecodeStream(new Uint8Array([4]));
const pointer = new Pointer(uint8, 'void');
assert.equal(pointer.decode(stream, {_startOffset: 0}), 4);
});
it('should support decoding pointers lazily', function() {
const stream = new DecodeStream(new Uint8Array([1, 53]));
const struct = new Struct({
ptr: new Pointer(uint8, uint8, {lazy: true})});
const res = struct.decode(stream);
assert.equal(typeof Object.getOwnPropertyDescriptor(res, 'ptr').get, 'function');
assert.equal(Object.getOwnPropertyDescriptor(res, 'ptr').enumerable, true);
assert.equal(res.ptr, 53);
});
});
describe('size', function() {
it('should add to local pointerSize', function() {
const pointer = new Pointer(uint8, uint8);
const ctx = {pointerSize: 0};
assert.equal(pointer.size(10, ctx), 1);
assert.equal(ctx.pointerSize, 1);
});
it('should add to immediate pointerSize', function() {
const pointer = new Pointer(uint8, uint8, {type: 'immediate'});
const ctx = {pointerSize: 0};
assert.equal(pointer.size(10, ctx), 1);
assert.equal(ctx.pointerSize, 1);
});
it('should add to parent pointerSize', function() {
const pointer = new Pointer(uint8, uint8, {type: 'parent'});
const ctx = {parent: {pointerSize: 0}};
assert.equal(pointer.size(10, ctx), 1);
assert.equal(ctx.parent.pointerSize, 1);
});
it('should add to global pointerSize', function() {
const pointer = new Pointer(uint8, uint8, {type: 'global'});
const ctx = {parent: {parent: {parent: {pointerSize: 0}}}};
assert.equal(pointer.size(10, ctx), 1);
assert.equal(ctx.parent.parent.parent.pointerSize, 1);
});
it('should handle void pointers', function() {
const pointer = new Pointer(uint8, 'void');
const ctx = {pointerSize: 0};
assert.equal(pointer.size(new VoidPointer(uint8, 50), ctx), 1);
assert.equal(ctx.pointerSize, 1);
});
it('should throw if no type and not a void pointer', function() {
const pointer = new Pointer(uint8, 'void');
const ctx = {pointerSize: 0};
assert.throws(() => pointer.size(30, ctx));
});
it('should return a fixed size without a value', function() {
const pointer = new Pointer(uint8, uint8);
assert.equal(pointer.size(), 1);
});
});
describe('encode', function() {
it('should handle null pointers', function() {
const ptr = new Pointer(uint8, uint8);
const ctx = {
pointerSize: 0,
startOffset: 0,
pointerOffset: 0,
pointers: []
};
const stream = new EncodeStream(new Uint8Array(ptr.size(null)));
ptr.encode(stream, null, ctx);
assert.equal(ctx.pointerSize, 0);
assert.deepEqual(stream.buffer, new Uint8Array([0]));
});
it('should handle local offsets', function() {
const ptr = new Pointer(uint8, uint8);
const ctx = {
pointerSize: 0,
startOffset: 0,
pointerOffset: 1,
pointers: []
};
const stream = new EncodeStream(new Uint8Array(ptr.size(10)));
ptr.encode(stream, 10, ctx);
assert.equal(ctx.pointerOffset, 2);
assert.deepEqual(ctx.pointers, [
{ type: uint8, val: 10, parent: ctx }
]);
assert.deepEqual(stream.buffer, new Uint8Array([1]));
});
it('should handle immediate offsets', function() {
const ptr = new Pointer(uint8, uint8, {type: 'immediate'});
const ctx = {
pointerSize: 0,
startOffset: 0,
pointerOffset: 1,
pointers: []
};
const stream = new EncodeStream(new Uint8Array(ptr.size(10)));
ptr.encode(stream, 10, ctx);
assert.equal(ctx.pointerOffset, 2);
assert.deepEqual(ctx.pointers, [
{ type: uint8, val: 10, parent: ctx }
]);
assert.deepEqual(stream.buffer, new Uint8Array([0]));
});
it('should handle immediate offsets', function() {
const ptr = new Pointer(uint8, uint8, {type: 'immediate'});
const ctx = {
pointerSize: 0,
startOffset: 0,
pointerOffset: 1,
pointers: []
};
const stream = new EncodeStream(new Uint8Array(ptr.size(10)));
ptr.encode(stream, 10, ctx);
assert.equal(ctx.pointerOffset, 2);
assert.deepEqual(ctx.pointers, [
{ type: uint8, val: 10, parent: ctx }
]);
assert.deepEqual(stream.buffer, new Uint8Array([0]));
});
it('should handle offsets relative to parent', function() {
const ptr = new Pointer(uint8, uint8, {type: 'parent'});
const ctx = {
parent: {
pointerSize: 0,
startOffset: 3,
pointerOffset: 5,
pointers: []
}
};
const stream = new EncodeStream(new Uint8Array(ptr.size(10, {parent: {...ctx.parent}})));
ptr.encode(stream, 10, ctx);
assert.equal(ctx.parent.pointerOffset, 6);
assert.deepEqual(ctx.parent.pointers, [
{ type: uint8, val: 10, parent: ctx }
]);
assert.deepEqual(stream.buffer, new Uint8Array([2]));
});
it('should handle global offsets', function() {
const ptr = new Pointer(uint8, uint8, {type: 'global'});
const ctx = {
parent: {
parent: {
parent: {
pointerSize: 0,
startOffset: 3,
pointerOffset: 5,
pointers: []
}
}
}
};
const stream = new EncodeStream(new Uint8Array(ptr.size(10, JSON.parse(JSON.stringify(ctx)))));
ptr.encode(stream, 10, ctx);
assert.equal(ctx.parent.parent.parent.pointerOffset, 6);
assert.deepEqual(ctx.parent.parent.parent.pointers, [
{ type: uint8, val: 10, parent: ctx }
]);
assert.deepEqual(stream.buffer, new Uint8Array([5]));
});
it('should support offsets relative to a property on the parent', function() {
const ptr = new Pointer(uint8, uint8, {relativeTo: ctx => ctx.ptr});
const ctx = {
pointerSize: 0,
startOffset: 0,
pointerOffset: 10,
pointers: [],
val: {
ptr: 4
}
};
const stream = new EncodeStream(new Uint8Array(ptr.size(10, {...ctx})));
ptr.encode(stream, 10, ctx);
assert.equal(ctx.pointerOffset, 11);
assert.deepEqual(ctx.pointers, [
{ type: uint8, val: 10, parent: ctx }
]);
assert.deepEqual(stream.buffer, new Uint8Array([6]));
});
it('should support void pointers', function() {
const ptr = new Pointer(uint8, 'void');
const ctx = {
pointerSize: 0,
startOffset: 0,
pointerOffset: 1,
pointers: []
};
const val = new VoidPointer(uint8, 55);
const stream = new EncodeStream(new Uint8Array(ptr.size(val, {...ctx})));
ptr.encode(stream, val, ctx);
assert.equal(ctx.pointerOffset, 2);
assert.deepEqual(ctx.pointers, [
{ type: uint8, val: 55, parent: ctx }
]);
assert.deepEqual(stream.buffer, new Uint8Array([1]));
});
it('should throw if not a void pointer instance', function() {
const ptr = new Pointer(uint8, 'void');
const ctx = {
pointerSize: 0,
startOffset: 0,
pointerOffset: 1,
pointers: []
};
const stream = new EncodeStream(new Uint8Array(0));
assert.throws(() => ptr.encode(stream, 44, ctx));
});
});
});

26
node_modules/restructure/test/Reserved.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
import assert from 'assert';
import {Reserved, uint8, uint16, DecodeStream, EncodeStream} from 'restructure';
describe('Reserved', function() {
it('should have a default count of 1', function() {
const reserved = new Reserved(uint8);
assert.equal(reserved.size(), 1);
});
it('should allow custom counts and types', function() {
const reserved = new Reserved(uint16, 10);
assert.equal(reserved.size(), 20);
});
it('should decode', function() {
const stream = new DecodeStream(new Uint8Array([0, 0]));
const reserved = new Reserved(uint16);
assert.equal(reserved.decode(stream), null);
assert.equal(stream.pos, 2);
});
it('should encode', function() {
const reserved = new Reserved(uint16);
assert.deepEqual(reserved.toBuffer(), new Uint8Array([0, 0]));
});
});

151
node_modules/restructure/test/String.js generated vendored Normal file
View File

@@ -0,0 +1,151 @@
import assert from 'assert';
import {String as StringT, uint16le, uint8, DecodeStream, Struct} from 'restructure';
describe('String', function() {
describe('decode', function() {
it('should decode fixed length', function() {
const string = new StringT(7);
assert.equal(string.fromBuffer(Buffer.from('testing')), 'testing');
});
it('should decode length from parent key', function() {
const stream = new DecodeStream(Buffer.from('testing'));
const string = new StringT('len');
assert.equal(string.decode(stream, {len: 7}), 'testing');
});
it('should decode length as number before string', function() {
const string = new StringT(uint8);
assert.equal(string.fromBuffer(Buffer.from('\x07testing')), 'testing');
});
it('should decode utf8', function() {
const string = new StringT(4, 'utf8');
assert.equal(string.fromBuffer(Buffer.from('🍻')), '🍻');
});
it('should decode encoding computed from function', function() {
const string = new StringT(4, function() { return 'utf8'; });
assert.equal(string.fromBuffer(Buffer.from('🍻')), '🍻');
});
it('should decode null-terminated string and read past terminator', function() {
const stream = new DecodeStream(Buffer.from('🍻\x00'));
const string = new StringT(null, 'utf8');
assert.equal(string.decode(stream), '🍻');
assert.equal(stream.pos, 5);
});
it('should decode remainder of buffer when null-byte missing', function() {
const string = new StringT(null, 'utf8');
assert.equal(string.fromBuffer(Buffer.from('🍻')), '🍻');
});
it('should decode two-byte null-terminated string for utf16le', function() {
const stream = new DecodeStream(Buffer.from('🍻\x00', 'utf16le'));
const string = new StringT(null, 'utf16le');
assert.equal(string.decode(stream), '🍻');
assert.equal(stream.pos, 6);
});
it('should decode remainder of buffer when null-byte missing, utf16le', function() {
const string = new StringT(null, 'utf16le');
assert.equal(string.fromBuffer(Buffer.from('🍻', 'utf16le')), '🍻');
});
it('should decode x-mac-roman', function() {
const string = new StringT(null, 'x-mac-roman');
const buf = new Uint8Array([0x8a, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x63, 0x68, 0x87, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73]);
assert.equal(string.fromBuffer(buf), 'äccented cháracters');
})
});
describe('size', function() {
it('should use string length', function() {
const string = new StringT(7);
assert.equal(string.size('testing'), 7);
});
it('should use correct encoding', function() {
const string = new StringT(10, 'utf8');
assert.equal(string.size('🍻'), 4);
});
it('should use encoding from function', function() {
const string = new StringT(10, function() { return 'utf8'; });
assert.equal(string.size('🍻'), 4);
});
it('should add size of length field before string', function() {
const string = new StringT(uint8, 'utf8');
assert.equal(string.size('🍻'), 5);
});
it('should work with utf16be encoding', function() {
const string = new StringT(10, 'utf16be');
assert.equal(string.size('🍻'), 4);
});
it('should take null-byte into account', function() {
const string = new StringT(null, 'utf8');
assert.equal(string.size('🍻'), 5);
});
it('should take null-byte into account, utf16le', function() {
const string = new StringT(null, 'utf16le');
assert.equal(string.size('🍻'), 6);
});
it('should use defined length if no value given', function() {
const array = new StringT(10);
assert.equal(array.size(), 10);
});
});
describe('encode', function() {
it('should encode using string length', function() {
const string = new StringT(7);
assert.deepEqual(string.toBuffer('testing'), Buffer.from('testing'));
});
it('should encode length as number before string', function() {
const string = new StringT(uint8);
assert.deepEqual(string.toBuffer('testing'), Buffer.from('\x07testing'));
});
it('should encode length as number before string utf8', function() {
const string = new StringT(uint8, 'utf8');
assert.deepEqual(string.toBuffer('testing 😜'), Buffer.from('\x0ctesting 😜', 'utf8'));
});
it('should encode utf8', function() {
const string = new StringT(4, 'utf8');
assert.deepEqual(string.toBuffer('🍻'), Buffer.from('🍻'));
});
it('should encode encoding computed from function', function() {
const string = new StringT(4, function() { return 'utf8'; });
assert.deepEqual(string.toBuffer('🍻'), Buffer.from('🍻'));
});
it('should encode null-terminated string', function() {
const string = new StringT(null, 'utf8');
assert.deepEqual(string.toBuffer('🍻'), Buffer.from('🍻\x00'));
});
it('should encode using string length, utf16le', function() {
const string = new StringT(16, 'utf16le');
assert.deepEqual(string.toBuffer('testing'), Buffer.from('testing', 'utf16le'));
});
it('should encode length as number before string utf16le', function() {
const string = new StringT(uint16le, 'utf16le');
assert.deepEqual(string.toBuffer('testing 😜'), Buffer.from('\u0014testing 😜', 'utf16le'));
});
it('should encode two-byte null-terminated string for UTF-16', function() {
const string = new StringT(null, 'utf16le');
assert.deepEqual(string.toBuffer('🍻'), Buffer.from('🍻\x00', 'utf16le'));
});
});
});

146
node_modules/restructure/test/Struct.js generated vendored Normal file
View File

@@ -0,0 +1,146 @@
import assert from 'assert';
import {Struct, String as StringT, Pointer, uint8, DecodeStream, EncodeStream} from 'restructure';
describe('Struct', function() {
describe('decode', function() {
it('should decode into an object', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
assert.deepEqual(struct.fromBuffer(Buffer.from('\x05devon\x15')), {
name: 'devon',
age: 21
});
});
it('should support process hook', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
struct.process = function() {
return this.canDrink = this.age >= 21;
};
assert.deepEqual(struct.fromBuffer(Buffer.from('\x05devon\x20')), {
name: 'devon',
age: 32,
canDrink: true
});
});
it('should support function keys', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8,
canDrink() { return this.age >= 21; }
});
assert.deepEqual(struct.fromBuffer(Buffer.from('\x05devon\x20')), {
name: 'devon',
age: 32,
canDrink: true
});
});
});
describe('size', function() {
it('should compute the correct size', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
assert.equal(struct.size({name: 'devon', age: 21}), 7);
});
it('should compute the correct size with pointers', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8,
ptr: new Pointer(uint8, new StringT(uint8))
});
const size = struct.size({
name: 'devon',
age: 21,
ptr: 'hello'
});
assert.equal(size, 14);
});
it('should get the correct size when no value is given', function() {
const struct = new Struct({
name: new StringT(4),
age: uint8
});
assert.equal(struct.size(), 5);
});
it('should throw when getting non-fixed length size and no value is given', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
assert.throws(() => struct.size(), /not a fixed size/i);
});
});
describe('encode', function() {
it('should encode objects to buffers', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
const buf = struct.toBuffer({
name: 'devon',
age: 21
});
assert.deepEqual(buf, Buffer.from('\x05devon\x15'));
});
it('should support preEncode hook', function() {
const struct = new Struct({
nameLength: uint8,
name: new StringT('nameLength'),
age: uint8
});
struct.preEncode = function() {
return this.nameLength = this.name.length;
};
const buf = struct.toBuffer({
name: 'devon',
age: 21
});
assert.deepEqual(buf, Buffer.from('\x05devon\x15'));
});
it('should encode pointer data after structure', function() {
const struct = new Struct({
name: new StringT(uint8),
age: uint8,
ptr: new Pointer(uint8, new StringT(uint8))
});
const buf = struct.toBuffer({
name: 'devon',
age: 21,
ptr: 'hello'
});
assert.deepEqual(buf, Buffer.from('\x05devon\x15\x08\x05hello'));
});
});
});

495
node_modules/restructure/test/VersionedStruct.js generated vendored Normal file
View File

@@ -0,0 +1,495 @@
import assert from 'assert';
import {VersionedStruct, String as StringT, Pointer, uint8, DecodeStream, EncodeStream} from 'restructure';
describe('VersionedStruct', function() {
describe('decode', function() {
it('should get version from number type', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
}
);
let stream = new DecodeStream(Buffer.from('\x00\x05devon\x15'));
assert.deepEqual(struct.decode(stream), {
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x01\x0adevon 👍\x15\x00', 'utf8'));
assert.deepEqual(struct.decode(stream), {
version: 1,
name: 'devon 👍',
age: 21,
gender: 0
});
});
it('should throw for unknown version', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
}
);
const stream = new DecodeStream(Buffer.from('\x05\x05devon\x15'));
return assert.throws(() => struct.decode(stream));
});
it('should support common header block', function() {
const struct = new VersionedStruct(uint8, {
header: {
age: uint8,
alive: uint8
},
0: {
name: new StringT(uint8, 'ascii')
},
1: {
name: new StringT(uint8, 'utf8'),
gender: uint8
}
}
);
let stream = new DecodeStream(Buffer.from('\x00\x15\x01\x05devon'));
assert.deepEqual(struct.decode(stream), {
version: 0,
age: 21,
alive: 1,
name: 'devon'
});
stream = new DecodeStream(Buffer.from('\x01\x15\x01\x0adevon 👍\x00', 'utf8'));
assert.deepEqual(struct.decode(stream), {
version: 1,
age: 21,
alive: 1,
name: 'devon 👍',
gender: 0
});
});
it('should support parent version key', function() {
const struct = new VersionedStruct('version', {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
}
);
let stream = new DecodeStream(Buffer.from('\x05devon\x15'));
assert.deepEqual(struct.decode(stream, {version: 0}), {
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x0adevon 👍\x15\x00', 'utf8'));
assert.deepEqual(struct.decode(stream, {version: 1}), {
version: 1,
name: 'devon 👍',
age: 21,
gender: 0
});
});
it('should support parent version nested key', function() {
const struct = new VersionedStruct('obj.version', {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
}
);
let stream = new DecodeStream(Buffer.from('\x05devon\x15'));
assert.deepEqual(struct.decode(stream, {obj: {version: 0}}), {
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x0adevon 👍\x15\x00', 'utf8'));
assert.deepEqual(struct.decode(stream, {obj: {version: 1}}), {
version: 1,
name: 'devon 👍',
age: 21,
gender: 0
});
});
it('should support sub versioned structs', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: new VersionedStruct(uint8, {
0: {
name: new StringT(uint8)
},
1: {
name: new StringT(uint8),
isDesert: uint8
}
}
)
}
);
let stream = new DecodeStream(Buffer.from('\x00\x05devon\x15'));
assert.deepEqual(struct.decode(stream, {version: 0}), {
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x01\x00\x05pasta'));
assert.deepEqual(struct.decode(stream, {version: 0}), {
version: 0,
name: 'pasta'
});
stream = new DecodeStream(Buffer.from('\x01\x01\x09ice cream\x01'));
assert.deepEqual(struct.decode(stream, {version: 0}), {
version: 1,
name: 'ice cream',
isDesert: 1
});
});
it('should support process hook', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
}
);
struct.process = function() {
return this.processed = true;
};
const stream = new DecodeStream(Buffer.from('\x00\x05devon\x15'));
assert.deepEqual(struct.decode(stream), {
version: 0,
name: 'devon',
age: 21,
processed: true
});
});
});
describe('size', function() {
it('should compute the correct size', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
}
);
let size = struct.size({
version: 0,
name: 'devon',
age: 21
});
assert.equal(size, 8);
size = struct.size({
version: 1,
name: 'devon 👍',
age: 21,
gender: 0
});
assert.equal(size, 14);
});
it('should throw for unknown version', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
}
);
assert.throws(() =>
struct.size({
version: 5,
name: 'devon',
age: 21
})
);
});
it('should support common header block', function() {
const struct = new VersionedStruct(uint8, {
header: {
age: uint8,
alive: uint8
},
0: {
name: new StringT(uint8, 'ascii')
},
1: {
name: new StringT(uint8, 'utf8'),
gender: uint8
}
}
);
let size = struct.size({
version: 0,
age: 21,
alive: 1,
name: 'devon'
});
assert.equal(size, 9);
size = struct.size({
version: 1,
age: 21,
alive: 1,
name: 'devon 👍',
gender: 0
});
assert.equal(size, 15);
});
it('should compute the correct size with pointers', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
ptr: new Pointer(uint8, new StringT(uint8))
}
}
);
const size = struct.size({
version: 1,
name: 'devon',
age: 21,
ptr: 'hello'
});
assert.equal(size, 15);
});
it('should throw if no value is given', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(4, 'ascii'),
age: uint8
},
1: {
name: new StringT(4, 'utf8'),
age: uint8,
gender: uint8
}
}
);
assert.throws(() => struct.size(), /not a fixed size/i);
});
});
describe('encode', function() {
it('should encode objects to buffers', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
});
const buf1 = struct.toBuffer({
version: 0,
name: 'devon',
age: 21
});
assert.deepEqual(buf1, Buffer.from('\x00\x05devon\x15', 'utf8'));
const buf2 = struct.toBuffer({
version: 1,
name: 'devon 👍',
age: 21,
gender: 0
});
assert.deepEqual(buf2, Buffer.from('\x01\x0adevon 👍\x15\x00', 'utf8'));
});
it('should throw for unknown version', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
});
assert.throws(() =>
struct.toBuffer({
version: 5,
name: 'devon',
age: 21
})
);
});
it('should support common header block', function() {
const struct = new VersionedStruct(uint8, {
header: {
age: uint8,
alive: uint8
},
0: {
name: new StringT(uint8, 'ascii')
},
1: {
name: new StringT(uint8, 'utf8'),
gender: uint8
}
});
const buf1 = struct.toBuffer({
version: 0,
age: 21,
alive: 1,
name: 'devon'
});
assert.deepEqual(buf1, Buffer.from('\x00\x15\x01\x05devon', 'utf8'));
const buf2 = struct.toBuffer({
version: 1,
age: 21,
alive: 1,
name: 'devon 👍',
gender: 0
});
assert.deepEqual(buf2, Buffer.from('\x01\x15\x01\x0adevon 👍\x00', 'utf8'));
});
it('should encode pointer data after structure', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
ptr: new Pointer(uint8, new StringT(uint8))
}
});
const buf = struct.toBuffer({
version: 1,
name: 'devon',
age: 21,
ptr: 'hello'
});
assert.deepEqual(buf, Buffer.from('\x01\x05devon\x15\x09\x05hello', 'utf8'));
});
it('should support preEncode hook', function() {
const struct = new VersionedStruct(uint8, {
0: {
name: new StringT(uint8, 'ascii'),
age: uint8
},
1: {
name: new StringT(uint8, 'utf8'),
age: uint8,
gender: uint8
}
});
struct.preEncode = function() {
return this.version = (this.gender != null) ? 1 : 0;
};
const buf1 = struct.toBuffer({
name: 'devon',
age: 21
});
assert.deepEqual(buf1, Buffer.from('\x00\x05devon\x15', 'utf8'));
const buf2 = struct.toBuffer({
name: 'devon 👍',
age: 21,
gender: 0
});
assert.deepEqual(buf2, Buffer.from('\x01\x0adevon 👍\x15\x00', 'utf8'));
});
});
});