Fix: estimates geo v2

This commit is contained in:
Arsen
2026-02-04 00:11:19 +05:00
commit 3f0086f88e
22567 changed files with 4348823 additions and 0 deletions

21
backend/node_modules/restructure/LICENSE generated vendored Executable 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.

306
backend/node_modules/restructure/README.md generated vendored Executable file
View File

@@ -0,0 +1,306 @@
# 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
var r = require('restructure');
var Person = new r.Struct({
name: new r.String(r.uint8, 'utf8'),
age: r.uint8
});
// decode a person from a buffer
var stream = new r.DecodeStream(buffer);
Person.decode(stream); // returns an object with the fields defined above
// encode a person from an object
// pipe the stream to a destination, such as a file
var stream = new r.EncodeStream();
stream.pipe(fs.createWriteStream('out.bin'));
Person.encode(stream, {
name: 'Devon',
age: 21
});
stream.end();
```
## API
All of the following types support three standard methods:
* `decode(stream)` - decodes an instance of the type from the given DecodeStream
* `size(value)` - returns the amount of space the value would take if encoded
* `encode(stream, value)` - encodes the given value into the given EncodeStream
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 Node `Buffer`. 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 can be a constant, taken
from a previous field in the parent structure, or encoded using a number type immediately before the string.
Supported encodings include `'ascii'`, `'utf8'`, `'ucs2'`, `'utf16le'`, `'utf16be'`, and if you also install
[iconv-lite](https://github.com/ashtuchkin/iconv-lite), many other legacy codecs.
```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

19
backend/node_modules/restructure/index.js generated vendored Executable file
View File

@@ -0,0 +1,19 @@
exports.EncodeStream = require('./src/EncodeStream');
exports.DecodeStream = require('./src/DecodeStream');
exports.Array = require('./src/Array');
exports.LazyArray = require('./src/LazyArray');
exports.Bitfield = require('./src/Bitfield');
exports.Boolean = require('./src/Boolean');
exports.Buffer = require('./src/Buffer');
exports.Enum = require('./src/Enum');
exports.Optional = require('./src/Optional');
exports.Reserved = require('./src/Reserved');
exports.String = require('./src/String');
exports.Struct = require('./src/Struct');
exports.VersionedStruct = require('./src/VersionedStruct');
const utils = require('./src/utils');
const NumberT = require('./src/Number');
const Pointer = require('./src/Pointer');
Object.assign(exports, utils, NumberT, Pointer);

35
backend/node_modules/restructure/package.json generated vendored Executable file
View File

@@ -0,0 +1,35 @@
{
"name": "restructure",
"version": "2.0.1",
"description": "Declaratively encode and decode binary data",
"main": "index.js",
"devDependencies": {
"chai": "~4.2.0",
"concat-stream": "~2.0.0",
"coveralls": "^3.0.11",
"iconv-lite": "^0.5.1",
"mocha": "~7.1.1",
"nyc": "^15.0.1"
},
"scripts": {
"test": "mocha --reporter spec",
"cover": "nyc --reporter=html --reporter=text mocha",
"coveralls": "nyc report --reporter=text-lcov | coveralls"
},
"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"
}

101
backend/node_modules/restructure/src/Array.js generated vendored Executable file
View File

@@ -0,0 +1,101 @@
const {Number:NumberT} = require('./Number');
const utils = require('./utils');
class ArrayT {
constructor(type, length, lengthType = 'count') {
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) {
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};
}
for (let item of array) {
size += this.type.size(item, ctx);
}
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);
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);
}
}
}
}
module.exports = ArrayT;

37
backend/node_modules/restructure/src/Bitfield.js generated vendored Executable file
View File

@@ -0,0 +1,37 @@
class Bitfield {
constructor(type, flags = []) {
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);
}
}
module.exports = Bitfield;

19
backend/node_modules/restructure/src/Boolean.js generated vendored Executable file
View File

@@ -0,0 +1,19 @@
class BooleanT {
constructor(type) {
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);
}
}
module.exports = BooleanT;

30
backend/node_modules/restructure/src/Buffer.js generated vendored Executable file
View File

@@ -0,0 +1,30 @@
const utils = require('./utils');
const {Number:NumberT} = require('./Number');
class BufferT {
constructor(length) {
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);
}
return val.length;
}
encode(stream, buf, parent) {
if (this.length instanceof NumberT) {
this.length.encode(stream, buf.length);
}
return stream.writeBuffer(buf);
}
}
module.exports = BufferT;

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

@@ -0,0 +1,85 @@
let iconv;
try { iconv = require('iconv-lite'); } catch (error) {}
class DecodeStream {
constructor(buffer) {
this.buffer = buffer;
this.pos = 0;
this.length = this.buffer.length;
}
readString(length, encoding = 'ascii') {
switch (encoding) {
case 'utf16le': case 'ucs2': case 'utf8': case 'ascii':
return this.buffer.toString(encoding, this.pos, (this.pos += length));
case 'utf16be':
var buf = Buffer.from(this.readBuffer(length));
// swap the bytes
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;
}
return buf.toString('utf16le');
default:
buf = this.readBuffer(length);
if (iconv) {
try {
return iconv.decode(buf, encoding);
} catch (error1) {}
}
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 in Buffer.prototype) {
if (key.slice(0, 4) === 'read') {
const bytes = DecodeStream.TYPES[key.replace(/read|[BL]E/g, '')];
DecodeStream.prototype[key] = function() {
const ret = this.buffer[key](this.pos);
this.pos += bytes;
return ret;
};
}
}
module.exports = DecodeStream;

125
backend/node_modules/restructure/src/EncodeStream.js generated vendored Executable file
View File

@@ -0,0 +1,125 @@
let iconv;
const stream = require('stream');
const DecodeStream = require('./DecodeStream');
try { iconv = require('iconv-lite'); } catch (error) {}
class EncodeStream extends stream.Readable {
constructor(bufferSize = 65536) {
super(...arguments);
this.buffer = Buffer.alloc(bufferSize);
this.bufferOffset = 0;
this.pos = 0;
}
// do nothing, required by node
_read() {}
ensure(bytes) {
if ((this.bufferOffset + bytes) > this.buffer.length) {
return this.flush();
}
}
flush() {
if (this.bufferOffset > 0) {
this.push(Buffer.from(this.buffer.slice(0, this.bufferOffset)));
return this.bufferOffset = 0;
}
}
writeBuffer(buffer) {
this.flush();
this.push(buffer);
return this.pos += buffer.length;
}
writeString(string, encoding = 'ascii') {
switch (encoding) {
case 'utf16le': case 'ucs2': case 'utf8': case 'ascii':
return this.writeBuffer(Buffer.from(string, encoding));
case 'utf16be':
var buf = Buffer.from(string, 'utf16le');
// swap the bytes
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;
}
return this.writeBuffer(buf);
default:
if (iconv) {
return this.writeBuffer(iconv.encode(string, encoding));
} else {
throw new Error('Install iconv-lite to enable additional string encodings.');
}
}
}
writeUInt24BE(val) {
this.ensure(3);
this.buffer[this.bufferOffset++] = (val >>> 16) & 0xff;
this.buffer[this.bufferOffset++] = (val >>> 8) & 0xff;
this.buffer[this.bufferOffset++] = val & 0xff;
return this.pos += 3;
}
writeUInt24LE(val) {
this.ensure(3);
this.buffer[this.bufferOffset++] = val & 0xff;
this.buffer[this.bufferOffset++] = (val >>> 8) & 0xff;
this.buffer[this.bufferOffset++] = (val >>> 16) & 0xff;
return this.pos += 3;
}
writeInt24BE(val) {
if (val >= 0) {
return this.writeUInt24BE(val);
} else {
return this.writeUInt24BE(val + 0xffffff + 1);
}
}
writeInt24LE(val) {
if (val >= 0) {
return this.writeUInt24LE(val);
} else {
return this.writeUInt24LE(val + 0xffffff + 1);
}
}
fill(val, length) {
if (length < this.buffer.length) {
this.ensure(length);
this.buffer.fill(val, this.bufferOffset, this.bufferOffset + length);
this.bufferOffset += length;
return this.pos += length;
} else {
const buf = Buffer.alloc(length);
buf.fill(val);
return this.writeBuffer(buf);
}
}
end() {
this.flush();
return this.push(null);
}
}
for (let key in Buffer.prototype) {
if (key.slice(0, 5) === 'write') {
const bytes = +DecodeStream.TYPES[key.replace(/write|[BL]E/g, '')];
EncodeStream.prototype[key] = function(value) {
this.ensure(bytes);
this.buffer[key](value, this.bufferOffset);
this.bufferOffset += bytes;
return this.pos += bytes;
};
}
}
module.exports = EncodeStream;

25
backend/node_modules/restructure/src/Enum.js generated vendored Executable file
View File

@@ -0,0 +1,25 @@
class Enum {
constructor(type, options = []) {
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);
}
}
module.exports = Enum;

81
backend/node_modules/restructure/src/LazyArray.js generated vendored Executable file
View File

@@ -0,0 +1,81 @@
const ArrayT = require('./Array');
const {Number:NumberT} = require('./Number');
const utils = require('./utils');
const {inspect} = require('util');
class LazyArrayT 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 LazyArray(this.type, length, stream, parent);
stream.pos += length * this.type.size(null, parent);
return res;
}
size(val, ctx) {
if (val instanceof LazyArray) {
val = val.toArray();
}
return super.size(val, ctx);
}
encode(stream, val, ctx) {
if (val instanceof LazyArray) {
val = val.toArray();
}
return super.encode(stream, val, ctx);
}
}
class LazyArray {
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;
}
inspect() {
return inspect(this.toArray());
}
}
module.exports = LazyArrayT;

65
backend/node_modules/restructure/src/Number.js generated vendored Executable file
View File

@@ -0,0 +1,65 @@
const DecodeStream = require('./DecodeStream');
class NumberT {
constructor(type, endian = 'BE') {
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);
}
}
exports.Number = NumberT;
exports.uint8 = new NumberT('UInt8');
exports.uint16be = (exports.uint16 = new NumberT('UInt16', 'BE'));
exports.uint16le = new NumberT('UInt16', 'LE');
exports.uint24be = (exports.uint24 = new NumberT('UInt24', 'BE'));
exports.uint24le = new NumberT('UInt24', 'LE');
exports.uint32be = (exports.uint32 = new NumberT('UInt32', 'BE'));
exports.uint32le = new NumberT('UInt32', 'LE');
exports.int8 = new NumberT('Int8');
exports.int16be = (exports.int16 = new NumberT('Int16', 'BE'));
exports.int16le = new NumberT('Int16', 'LE');
exports.int24be = (exports.int24 = new NumberT('Int24', 'BE'));
exports.int24le = new NumberT('Int24', 'LE');
exports.int32be = (exports.int32 = new NumberT('Int32', 'BE'));
exports.int32le = new NumberT('Int32', 'LE');
exports.floatbe = (exports.float = new NumberT('Float', 'BE'));
exports.floatle = new NumberT('Float', 'LE');
exports.doublebe = (exports.double = new NumberT('Double', 'BE'));
exports.doublele = new NumberT('Double', 'LE');
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);
}
}
exports.Fixed = Fixed;
exports.fixed16be = (exports.fixed16 = new Fixed(16, 'BE'));
exports.fixed16le = new Fixed(16, 'LE');
exports.fixed32be = (exports.fixed32 =new Fixed(32, 'BE'));
exports.fixed32le = new Fixed(32, 'LE');

43
backend/node_modules/restructure/src/Optional.js generated vendored Executable file
View File

@@ -0,0 +1,43 @@
class Optional {
constructor(type, condition = true) {
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);
}
}
}
module.exports = Optional;

166
backend/node_modules/restructure/src/Pointer.js generated vendored Executable file
View File

@@ -0,0 +1,166 @@
const utils = require('./utils');
class Pointer {
constructor(offsetType, type, options = {}) {
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) {
ctx.pointerSize += type.size(val, parent);
}
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
class VoidPointer {
constructor(type, value) {
this.type = type;
this.value = value;
}
}
exports.Pointer = Pointer;
exports.VoidPointer = VoidPointer;

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

@@ -0,0 +1,23 @@
const utils = require('./utils');
class Reserved {
constructor(type, count = 1) {
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));
}
}
module.exports = Reserved;

85
backend/node_modules/restructure/src/String.js generated vendored Executable file
View File

@@ -0,0 +1,85 @@
const {Number:NumberT} = require('./Number');
const utils = require('./utils');
class StringT {
constructor(length, encoding = 'ascii') {
this.length = length;
this.encoding = encoding;
}
decode(stream, parent) {
let length, pos;
if (this.length != null) {
length = utils.resolveLength(this.length, stream, parent);
} else {
let buffer;
({buffer, length, pos} = stream);
while ((pos < length) && (buffer[pos] !== 0x00)) {
++pos;
}
length = pos - stream.pos;
}
let { encoding } = this;
if (typeof encoding === 'function') {
encoding = encoding.call(parent, parent) || 'ascii';
}
const string = stream.readString(length, encoding);
if ((this.length == null) && (stream.pos < stream.length)) {
stream.pos++;
}
return string;
}
size(val, parent) {
// Use the defined value if no value was given
if (!val) {
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 = Buffer.byteLength(val, encoding);
if (this.length instanceof NumberT) {
size += this.length.size();
}
if ((this.length == null)) {
size++;
}
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, Buffer.byteLength(val, encoding));
}
stream.writeString(val, encoding);
if ((this.length == null)) {
return stream.writeUInt8(0x00);
}
}
}
module.exports = StringT;

111
backend/node_modules/restructure/src/Struct.js generated vendored Executable file
View File

@@ -0,0 +1,111 @@
const utils = require('./utils');
class Struct {
constructor(fields = {}) {
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) {
if (val == null) { val = {}; }
if (includePointers == null) { includePointers = true; }
const ctx = {
parent,
val,
pointerSize: 0
};
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);
}
}
}
module.exports = Struct;

138
backend/node_modules/restructure/src/VersionedStruct.js generated vendored Executable file
View File

@@ -0,0 +1,138 @@
const Struct = require('./Struct');
const getPath = (object, pathArray) => {
return pathArray.reduce((prevObj, key) => prevObj && prevObj[key], object);
};
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');
}
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);
}
}
}
module.exports = VersionedStruct;

37
backend/node_modules/restructure/src/utils.js generated vendored Executable file
View File

@@ -0,0 +1,37 @@
const {Number:NumberT} = require('./Number');
exports.resolveLength = function(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;
};
class PropertyDescriptor {
constructor(opts = {}) {
this.enumerable = true;
this.configurable = true;
for (let key in opts) {
const val = opts[key];
this[key] = val;
}
}
}
exports.PropertyDescriptor = PropertyDescriptor;

125
backend/node_modules/restructure/test/Array.js generated vendored Executable file
View File

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

35
backend/node_modules/restructure/test/Bitfield.js generated vendored Executable file
View File

@@ -0,0 +1,35 @@
const {Bitfield, uint8, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
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', () => bitfield.size().should.equal(1));
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([JACK | MACK | PACK | NACK | QUACK]));
return bitfield.decode(stream).should.deep.equal({
Jack: true, Kack: false, Lack: false, Mack: true, Nack: true, Oack: false, Pack: true, Quack: true});
});
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([JACK | MACK | PACK | NACK | QUACK]));
return done();
})
);
bitfield.encode(stream, {Jack: true, Kack: false, Lack: false, Mack: true, Nack: true, Oack: false, Pack: true, Quack: true});
return stream.end();
});
});

55
backend/node_modules/restructure/test/Boolean.js generated vendored Executable file
View File

@@ -0,0 +1,55 @@
const {Boolean, uint8, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('Boolean', function() {
describe('decode', function() {
it('should decode 0 as false', function() {
const stream = new DecodeStream(Buffer.from([0]));
const boolean = new Boolean(uint8);
return boolean.decode(stream).should.equal(false);
});
return it('should decode 1 as true', function() {
const stream = new DecodeStream(Buffer.from([1]));
const boolean = new Boolean(uint8);
return boolean.decode(stream).should.equal(true);
});
});
describe('size', () =>
it('should return given type size', function() {
const stream = new DecodeStream(Buffer.from([0]));
const boolean = new Boolean(uint8);
return boolean.size().should.equal(1);
})
);
return describe('encode', function() {
it('should encode false as 0', function(done) {
const stream = new EncodeStream;
const boolean = new Boolean(uint8);
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0]));
return done();
})
);
boolean.encode(stream, false);
return stream.end();
});
return it('should encode true as 1', function(done) {
const stream = new EncodeStream;
const boolean = new Boolean(uint8);
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([1]));
return done();
})
);
boolean.encode(stream, true);
return stream.end();
});
});
});

62
backend/node_modules/restructure/test/Buffer.js generated vendored Executable file
View File

@@ -0,0 +1,62 @@
const {Buffer:BufferT, DecodeStream, EncodeStream, uint8} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('Buffer', function() {
describe('decode', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xab, 0xff, 0x1f, 0xb6]));
const buf = new BufferT(2);
buf.decode(stream).should.deep.equal(Buffer.from([0xab, 0xff]));
return buf.decode(stream).should.deep.equal(Buffer.from([0x1f, 0xb6]));
});
return it('should decode with parent key length', function() {
const stream = new DecodeStream(Buffer.from([0xab, 0xff, 0x1f, 0xb6]));
const buf = new BufferT('len');
buf.decode(stream, {len: 3}).should.deep.equal(Buffer.from([0xab, 0xff, 0x1f]));
return buf.decode(stream, {len: 1}).should.deep.equal(Buffer.from([0xb6]));
});
});
describe('size', function() {
it('should return size', function() {
const buf = new BufferT(2);
return buf.size(Buffer.from([0xab, 0xff])).should.equal(2);
});
return it('should use defined length if no value given', function() {
const array = new BufferT(10);
return array.size().should.equal(10);
});
});
return describe('encode', function() {
it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xab, 0xff, 0x1f, 0xb6]));
return done();
})
);
const buf = new BufferT(2);
buf.encode(stream, Buffer.from([0xab, 0xff]));
buf.encode(stream, Buffer.from([0x1f, 0xb6]));
return stream.end();
});
return it('should encode length before buffer', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([2, 0xab, 0xff]));
return done();
})
);
const buf = new BufferT(uint8);
buf.encode(stream, Buffer.from([0xab, 0xff]));
return stream.end();
});
});
});

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

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

197
backend/node_modules/restructure/test/EncodeStream.js generated vendored Executable file
View File

@@ -0,0 +1,197 @@
const {EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('EncodeStream', function() {
it('should write a buffer', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([1,2,3]));
return done();
})
);
stream.writeBuffer(Buffer.from([1,2,3]));
return stream.end();
});
it('should writeUInt16BE', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xab, 0xcd]));
return done();
})
);
stream.writeUInt16BE(0xabcd);
return stream.end();
});
it('should writeUInt16LE', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xab, 0xcd]));
return done();
})
);
stream.writeUInt16LE(0xcdab);
return stream.end();
});
it('should writeUInt24BE', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xab, 0xcd, 0xef]));
return done();
})
);
stream.writeUInt24BE(0xabcdef);
return stream.end();
});
it('should writeUInt24LE', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xef, 0xcd, 0xab]));
return done();
})
);
stream.writeUInt24LE(0xabcdef);
return stream.end();
});
it('should writeInt24BE', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xff, 0xab, 0x24, 0xab, 0xcd, 0xef]));
return done();
})
);
stream.writeInt24BE(-21724);
stream.writeInt24BE(0xabcdef);
return stream.end();
});
it('should writeInt24LE', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x24, 0xab, 0xff, 0xef, 0xcd, 0xab]));
return done();
})
);
stream.writeInt24LE(-21724);
stream.writeInt24LE(0xabcdef);
return stream.end();
});
it('should fill', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([10, 10, 10, 10, 10]));
return done();
})
);
stream.fill(10, 5);
return stream.end();
});
return describe('writeString', function() {
it('should encode ascii by default', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('some text', 'ascii'));
return done();
})
);
stream.writeString('some text');
return stream.end();
});
it('should encode ascii', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('some text', 'ascii'));
return done();
})
);
stream.writeString('some text');
return stream.end();
});
it('should encode utf8', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('unicode! 👍', 'utf8'));
return done();
})
);
stream.writeString('unicode! 👍', 'utf8');
return stream.end();
});
it('should encode utf16le', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('unicode! 👍', 'utf16le'));
return done();
})
);
stream.writeString('unicode! 👍', 'utf16le');
return stream.end();
});
it('should encode ucs2', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('unicode! 👍', 'ucs2'));
return done();
})
);
stream.writeString('unicode! 👍', 'ucs2');
return stream.end();
});
it('should encode utf16be', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(out) {
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;
}
out.should.deep.equal(buf);
return done();
})
);
stream.writeString('unicode! 👍', 'utf16be');
return stream.end();
});
return it('should encode macroman', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(out) {
const buf = Buffer.from([0x8a, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x63, 0x68, 0x87, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73]);
out.should.deep.equal(buf);
return done();
})
);
stream.writeString('äccented cháracters', 'mac');
return stream.end();
});
});
});

34
backend/node_modules/restructure/test/Enum.js generated vendored Executable file
View File

@@ -0,0 +1,34 @@
const {Enum, uint8, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('Enum', function() {
const e = new Enum(uint8, ['foo', 'bar', 'baz']);
it('should have the right size', () => e.size().should.equal(1));
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([1, 2, 0]));
e.decode(stream).should.equal('bar');
e.decode(stream).should.equal('baz');
return e.decode(stream).should.equal('foo');
});
it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([1, 2, 0]));
return done();
})
);
e.encode(stream, 'bar');
e.encode(stream, 'baz');
e.encode(stream, 'foo');
return stream.end();
});
return it('should throw on unknown option', function() {
const stream = new EncodeStream;
return should.throw(() => e.encode(stream, 'unknown'));
});
});

77
backend/node_modules/restructure/test/LazyArray.js generated vendored Executable file
View File

@@ -0,0 +1,77 @@
const {LazyArray, Pointer, uint8, uint16, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('LazyArray', function() {
describe('decode', function() {
it('should decode items lazily', function() {
const stream = new DecodeStream(Buffer.from([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
arr.should.not.be.an.instanceof(Array);
arr.should.have.length(4);
stream.pos.should.equal(4);
arr.get(0).should.equal(1);
arr.get(1).should.equal(2);
arr.get(2).should.equal(3);
arr.get(3).should.equal(4);
should.not.exist(arr.get(-1));
return should.not.exist(arr.get(5));
});
it('should be able to convert to an array', function() {
const stream = new DecodeStream(Buffer.from([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
return arr.toArray().should.deep.equal([1, 2, 3, 4]);
});
it('should have an inspect method', function() {
const stream = new DecodeStream(Buffer.from([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
return arr.inspect().should.equal('[ 1, 2, 3, 4 ]');
});
return it('should decode length as number before array', function() {
const stream = new DecodeStream(Buffer.from([4, 1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, uint8);
const arr = array.decode(stream);
return arr.toArray().should.deep.equal([1, 2, 3, 4]);
});
});
describe('size', () =>
it('should work with LazyArrays', function() {
const stream = new DecodeStream(Buffer.from([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
return array.size(arr).should.equal(4);
})
);
return describe('encode', () =>
it('should work with LazyArrays', function(done) {
const stream = new DecodeStream(Buffer.from([1, 2, 3, 4, 5]));
const array = new LazyArray(uint8, 4);
const arr = array.decode(stream);
const enc = new EncodeStream;
enc.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([1, 2, 3, 4]));
return done();
})
);
array.encode(enc, arr);
return enc.end();
})
);
});

525
backend/node_modules/restructure/test/Number.js generated vendored Executable file
View File

@@ -0,0 +1,525 @@
const {
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
} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('Number', function() {
describe('uint8', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xab, 0xff]));
uint8.decode(stream).should.equal(0xab);
return uint8.decode(stream).should.equal(0xff);
});
it('should have a size', () => uint8.size().should.equal(1));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xab, 0xff]));
return done();
})
);
uint8.encode(stream, 0xab);
uint8.encode(stream, 0xff);
return stream.end();
});
});
describe('uint16', () =>
it('is an alias for uint16be', () => uint16.should.equal(uint16be))
);
describe('uint16be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xab, 0xff]));
return uint16be.decode(stream).should.equal(0xabff);
});
it('should have a size', () => uint16be.size().should.equal(2));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xab, 0xff]));
return done();
})
);
uint16be.encode(stream, 0xabff);
return stream.end();
});
});
describe('uint16le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xff, 0xab]));
return uint16le.decode(stream).should.equal(0xabff);
});
it('should have a size', () => uint16le.size().should.equal(2));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xff, 0xab]));
return done();
})
);
uint16le.encode(stream, 0xabff);
return stream.end();
});
});
describe('uint24', () =>
it('is an alias for uint24be', () => uint24.should.equal(uint24be))
);
describe('uint24be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xff, 0xab, 0x24]));
return uint24be.decode(stream).should.equal(0xffab24);
});
it('should have a size', () => uint24be.size().should.equal(3));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xff, 0xab, 0x24]));
return done();
})
);
uint24be.encode(stream, 0xffab24);
return stream.end();
});
});
describe('uint24le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x24, 0xab, 0xff]));
return uint24le.decode(stream).should.equal(0xffab24);
});
it('should have a size', () => uint24le.size().should.equal(3));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x24, 0xab, 0xff]));
return done();
})
);
uint24le.encode(stream, 0xffab24);
return stream.end();
});
});
describe('uint32', () =>
it('is an alias for uint32be', () => uint32.should.equal(uint32be))
);
describe('uint32be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xff, 0xab, 0x24, 0xbf]));
return uint32be.decode(stream).should.equal(0xffab24bf);
});
it('should have a size', () => uint32be.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xff, 0xab, 0x24, 0xbf]));
return done();
})
);
uint32be.encode(stream, 0xffab24bf);
return stream.end();
});
});
describe('uint32le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xbf, 0x24, 0xab, 0xff]));
return uint32le.decode(stream).should.equal(0xffab24bf);
});
it('should have a size', () => uint32le.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xbf, 0x24, 0xab, 0xff]));
return done();
})
);
uint32le.encode(stream, 0xffab24bf);
return stream.end();
});
});
describe('int8', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x7f, 0xff]));
int8.decode(stream).should.equal(127);
return int8.decode(stream).should.equal(-1);
});
it('should have a size', () => int8.size().should.equal(1));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x7f, 0xff]));
return done();
})
);
int8.encode(stream, 127);
int8.encode(stream, -1);
return stream.end();
});
});
describe('int16', () =>
it('is an alias for int16be', () => int16.should.equal(int16be))
);
describe('int16be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xff, 0xab]));
return int16be.decode(stream).should.equal(-85);
});
it('should have a size', () => int16be.size().should.equal(2));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xff, 0xab]));
return done();
})
);
int16be.encode(stream, -85);
return stream.end();
});
});
describe('int16le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xab, 0xff]));
return int16le.decode(stream).should.equal(-85);
});
it('should have a size', () => int16le.size().should.equal(2));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xab, 0xff]));
return done();
})
);
int16le.encode(stream, -85);
return stream.end();
});
});
describe('int24', () =>
it('is an alias for int24be', () => int24.should.equal(int24be))
);
describe('int24be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xff, 0xab, 0x24]));
return int24be.decode(stream).should.equal(-21724);
});
it('should have a size', () => int24be.size().should.equal(3));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xff, 0xab, 0x24]));
return done();
})
);
int24be.encode(stream, -21724);
return stream.end();
});
});
describe('int24le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x24, 0xab, 0xff]));
return int24le.decode(stream).should.equal(-21724);
});
it('should have a size', () => int24le.size().should.equal(3));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x24, 0xab, 0xff]));
return done();
})
);
int24le.encode(stream, -21724);
return stream.end();
});
});
describe('int32', () =>
it('is an alias for int32be', () => int32.should.equal(int32be))
);
describe('int32be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xff, 0xab, 0x24, 0xbf]));
return int32be.decode(stream).should.equal(-5561153);
});
it('should have a size', () => int32be.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xff, 0xab, 0x24, 0xbf]));
return done();
})
);
int32be.encode(stream, -5561153);
return stream.end();
});
});
describe('int32le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xbf, 0x24, 0xab, 0xff]));
return int32le.decode(stream).should.equal(-5561153);
});
it('should have a size', () => int32le.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xbf, 0x24, 0xab, 0xff]));
return done();
})
);
int32le.encode(stream, -5561153);
return stream.end();
});
});
describe('float', () =>
it('is an alias for floatbe', () => float.should.equal(floatbe))
);
describe('floatbe', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x43, 0x7a, 0x8c, 0xcd]));
return floatbe.decode(stream).should.be.closeTo(250.55, 0.005);
});
it('should have a size', () => floatbe.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x43, 0x7a, 0x8c, 0xcd]));
return done();
})
);
floatbe.encode(stream, 250.55);
return stream.end();
});
});
describe('floatle', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xcd, 0x8c, 0x7a, 0x43]));
return floatle.decode(stream).should.be.closeTo(250.55, 0.005);
});
it('should have a size', () => floatle.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xcd, 0x8c, 0x7a, 0x43]));
return done();
})
);
floatle.encode(stream, 250.55);
return stream.end();
});
});
describe('double', () =>
it('is an alias for doublebe', () => double.should.equal(doublebe))
);
describe('doublebe', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x40, 0x93, 0x4a, 0x3d, 0x70, 0xa3, 0xd7, 0x0a]));
return doublebe.decode(stream).should.be.equal(1234.56);
});
it('should have a size', () => doublebe.size().should.equal(8));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x40, 0x93, 0x4a, 0x3d, 0x70, 0xa3, 0xd7, 0x0a]));
return done();
})
);
doublebe.encode(stream, 1234.56);
return stream.end();
});
});
describe('doublele', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x0a, 0xd7, 0xa3, 0x70, 0x3d, 0x4a, 0x93, 0x40]));
return doublele.decode(stream).should.be.equal(1234.56);
});
it('should have a size', () => doublele.size().should.equal(8));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x0a, 0xd7, 0xa3, 0x70, 0x3d, 0x4a, 0x93, 0x40]));
return done();
})
);
doublele.encode(stream, 1234.56);
return stream.end();
});
});
describe('fixed16', () =>
it('is an alias for fixed16be', () => fixed16.should.equal(fixed16be))
);
describe('fixed16be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x19, 0x57]));
return fixed16be.decode(stream).should.be.closeTo(25.34, 0.005);
});
it('should have a size', () => fixed16be.size().should.equal(2));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x19, 0x57]));
return done();
})
);
fixed16be.encode(stream, 25.34);
return stream.end();
});
});
describe('fixed16le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x57, 0x19]));
return fixed16le.decode(stream).should.be.closeTo(25.34, 0.005);
});
it('should have a size', () => fixed16le.size().should.equal(2));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x57, 0x19]));
return done();
})
);
fixed16le.encode(stream, 25.34);
return stream.end();
});
});
describe('fixed32', () =>
it('is an alias for fixed32be', () => fixed32.should.equal(fixed32be))
);
describe('fixed32be', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0x00, 0xfa, 0x8c, 0xcc]));
return fixed32be.decode(stream).should.be.closeTo(250.55, 0.005);
});
it('should have a size', () => fixed32be.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0x00, 0xfa, 0x8c, 0xcc]));
return done();
})
);
fixed32be.encode(stream, 250.55);
return stream.end();
});
});
return describe('fixed32le', function() {
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0xcc, 0x8c, 0xfa, 0x00]));
return fixed32le.decode(stream).should.be.closeTo(250.55, 0.005);
});
it('should have a size', () => fixed32le.size().should.equal(4));
return it('should encode', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0xcc, 0x8c, 0xfa, 0x00]));
return done();
})
);
fixed32le.encode(stream, 250.55);
return stream.end();
});
});
});

141
backend/node_modules/restructure/test/Optional.js generated vendored Executable file
View File

@@ -0,0 +1,141 @@
const {Optional, uint8, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('Optional', function() {
describe('decode', function() {
it('should not decode when condition is falsy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, false);
should.not.exist(optional.decode(stream));
return stream.pos.should.equal(0);
});
it('should not decode when condition is a function and falsy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, function() { return false; });
should.not.exist(optional.decode(stream));
return stream.pos.should.equal(0);
});
it('should decode when condition is omitted', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8);
should.exist(optional.decode(stream));
return stream.pos.should.equal(1);
});
it('should decode when condition is truthy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, true);
should.exist(optional.decode(stream));
return stream.pos.should.equal(1);
});
return it('should decode when condition is a function and truthy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, function() { return true; });
should.exist(optional.decode(stream));
return stream.pos.should.equal(1);
});
});
describe('size', function() {
it('should return 0 when condition is falsy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, false);
return optional.size().should.equal(0);
});
it('should return 0 when condition is a function and falsy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, function() { return false; });
return optional.size().should.equal(0);
});
it('should return given type size when condition is omitted', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8);
return optional.size().should.equal(1);
});
it('should return given type size when condition is truthy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, true);
return optional.size().should.equal(1);
});
return it('should return given type size when condition is a function and truthy', function() {
const stream = new DecodeStream(Buffer.from([0]));
const optional = new Optional(uint8, function() { return true; });
return optional.size().should.equal(1);
});
});
return describe('encode', function() {
it('should not encode when condition is falsy', function(done) {
const stream = new EncodeStream;
const optional = new Optional(uint8, false);
stream.pipe(concat(function(buf) {
buf.should.deep.equal([]);
return done();
})
);
optional.encode(stream, 128);
return stream.end();
});
it('should not encode when condition is a function and falsy', function(done) {
const stream = new EncodeStream;
const optional = new Optional(uint8, function() { return false; });
stream.pipe(concat(function(buf) {
buf.should.deep.equal([]);
return done();
})
);
optional.encode(stream, 128);
return stream.end();
});
it('should encode when condition is omitted', function(done) {
const stream = new EncodeStream;
const optional = new Optional(uint8);
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([128]));
return done();
})
);
optional.encode(stream, 128);
return stream.end();
});
it('should encode when condition is truthy', function(done) {
const stream = new EncodeStream;
const optional = new Optional(uint8, true);
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([128]));
return done();
})
);
optional.encode(stream, 128);
return stream.end();
});
return it('should encode when condition is a function and truthy', function(done) {
const stream = new EncodeStream;
const optional = new Optional(uint8, function() { return true; });
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([128]));
return done();
})
);
optional.encode(stream, 128);
return stream.end();
});
});
});

337
backend/node_modules/restructure/test/Pointer.js generated vendored Executable file
View File

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

35
backend/node_modules/restructure/test/Reserved.js generated vendored Executable file
View File

@@ -0,0 +1,35 @@
const {Reserved, uint8, uint16, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('Reserved', function() {
it('should have a default count of 1', function() {
const reserved = new Reserved(uint8);
return reserved.size().should.equal(1);
});
it('should allow custom counts and types', function() {
const reserved = new Reserved(uint16, 10);
return reserved.size().should.equal(20);
});
it('should decode', function() {
const stream = new DecodeStream(Buffer.from([0, 0]));
const reserved = new Reserved(uint16);
should.not.exist(reserved.decode(stream));
return stream.pos.should.equal(2);
});
return it('should encode', function(done) {
const stream = new EncodeStream;
const reserved = new Reserved(uint16);
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from([0, 0]));
return done();
})
);
reserved.encode(stream);
return stream.end();
});
});

167
backend/node_modules/restructure/test/String.js generated vendored Executable file
View File

@@ -0,0 +1,167 @@
const {String:StringT, uint8, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('String', function() {
describe('decode', function() {
it('should decode fixed length', function() {
const stream = new DecodeStream(Buffer.from('testing'));
const string = new StringT(7);
return string.decode(stream).should.equal('testing');
});
it('should decode length from parent key', function() {
const stream = new DecodeStream(Buffer.from('testing'));
const string = new StringT('len');
return string.decode(stream, {len: 7}).should.equal('testing');
});
it('should decode length as number before string', function() {
const stream = new DecodeStream(Buffer.from('\x07testing'));
const string = new StringT(uint8);
return string.decode(stream).should.equal('testing');
});
it('should decode utf8', function() {
const stream = new DecodeStream(Buffer.from('🍻'));
const string = new StringT(4, 'utf8');
return string.decode(stream).should.equal('🍻');
});
it('should decode encoding computed from function', function() {
const stream = new DecodeStream(Buffer.from('🍻'));
const string = new StringT(4, function() { return 'utf8'; });
return string.decode(stream).should.equal('🍻');
});
it('should decode null-terminated string and read past terminator', function() {
const stream = new DecodeStream(Buffer.from('🍻\x00'));
const string = new StringT(null, 'utf8');
string.decode(stream).should.equal('🍻');
return stream.pos.should.equal(5);
});
return it('should decode remainder of buffer when null-byte missing', function() {
const stream = new DecodeStream(Buffer.from('🍻'));
const string = new StringT(null, 'utf8');
return string.decode(stream).should.equal('🍻');
});
});
describe('size', function() {
it('should use string length', function() {
const string = new StringT(7);
return string.size('testing').should.equal(7);
});
it('should use correct encoding', function() {
const string = new StringT(10, 'utf8');
return string.size('🍻').should.equal(4);
});
it('should use encoding from function', function() {
const string = new StringT(10, function() { return 'utf8'; });
return string.size('🍻').should.equal(4);
});
it('should add size of length field before string', function() {
const string = new StringT(uint8, 'utf8');
return string.size('🍻').should.equal(5);
});
it('should work with utf16be encoding', function() {
const string = new StringT(10, 'utf16be');
return string.size('🍻').should.equal(4);
});
it('should take null-byte into account', function() {
const string = new StringT(null, 'utf8');
return string.size('🍻').should.equal(5);
});
return it('should use defined length if no value given', function() {
const array = new StringT(10);
return array.size().should.equal(10);
});
});
return describe('encode', function() {
it('should encode using string length', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('testing'));
return done();
})
);
const string = new StringT(7);
string.encode(stream, 'testing');
return stream.end();
});
it('should encode length as number before string', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x07testing'));
return done();
})
);
const string = new StringT(uint8);
string.encode(stream, 'testing');
return stream.end();
});
it('should encode length as number before string utf8', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x0ctesting 😜', 'utf8'));
return done();
})
);
const string = new StringT(uint8, 'utf8');
string.encode(stream, 'testing 😜');
return stream.end();
});
it('should encode utf8', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('🍻'));
return done();
})
);
const string = new StringT(4, 'utf8');
string.encode(stream, '🍻');
return stream.end();
});
it('should encode encoding computed from function', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('🍻'));
return done();
})
);
const string = new StringT(4, function() { return 'utf8'; });
string.encode(stream, '🍻');
return stream.end();
});
return it('should encode null-terminated string', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('🍻\x00'));
return done();
})
);
const string = new StringT(null, 'utf8');
string.encode(stream, '🍻');
return stream.end();
});
});
});

175
backend/node_modules/restructure/test/Struct.js generated vendored Executable file
View File

@@ -0,0 +1,175 @@
const {Struct, String:StringT, Pointer, uint8, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
describe('Struct', function() {
describe('decode', function() {
it('should decode into an object', function() {
const stream = new DecodeStream(Buffer.from('\x05devon\x15'));
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
return struct.decode(stream).should.deep.equal({
name: 'devon',
age: 21
});
});
it('should support process hook', function() {
const stream = new DecodeStream(Buffer.from('\x05devon\x20'));
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
struct.process = function() {
return this.canDrink = this.age >= 21;
};
return struct.decode(stream).should.deep.equal({
name: 'devon',
age: 32,
canDrink: true
});
});
return it('should support function keys', function() {
const stream = new DecodeStream(Buffer.from('\x05devon\x20'));
const struct = new Struct({
name: new StringT(uint8),
age: uint8,
canDrink() { return this.age >= 21; }
});
return struct.decode(stream).should.deep.equal({
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
});
return struct.size({name: 'devon', age: 21}).should.equal(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'
});
return size.should.equal(14);
});
it('should get the correct size when no value is given', function() {
const struct = new Struct({
name: new StringT(4),
age: uint8
});
return struct.size().should.equal(5);
});
return 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
});
return should.throw(() => struct.size()
, /not a fixed size/i);
});
});
return describe('encode', function() {
it('should encode objects to buffers', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x05devon\x15'));
return done();
})
);
const struct = new Struct({
name: new StringT(uint8),
age: uint8
});
struct.encode(stream, {
name: 'devon',
age: 21
}
);
return stream.end();
});
it('should support preEncode hook', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x05devon\x15'));
return done();
})
);
const struct = new Struct({
nameLength: uint8,
name: new StringT('nameLength'),
age: uint8
});
struct.preEncode = function() {
return this.nameLength = this.name.length;
};
struct.encode(stream, {
name: 'devon',
age: 21
}
);
return stream.end();
});
return it('should encode pointer data after structure', function(done) {
const stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x05devon\x15\x08\x05hello'));
return done();
})
);
const struct = new Struct({
name: new StringT(uint8),
age: uint8,
ptr: new Pointer(uint8, new StringT(uint8))
});
struct.encode(stream, {
name: 'devon',
age: 21,
ptr: 'hello'
}
);
return stream.end();
});
});
});

533
backend/node_modules/restructure/test/VersionedStruct.js generated vendored Executable file
View File

@@ -0,0 +1,533 @@
const {VersionedStruct, String:StringT, Pointer, uint8, DecodeStream, EncodeStream} = require('../');
const should = require('chai').should();
const concat = require('concat-stream');
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'));
struct.decode(stream).should.deep.equal({
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x01\x0adevon 👍\x15\x00', 'utf8'));
return struct.decode(stream).should.deep.equal({
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 should.throw(() => 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'));
struct.decode(stream).should.deep.equal({
version: 0,
age: 21,
alive: 1,
name: 'devon'
});
stream = new DecodeStream(Buffer.from('\x01\x15\x01\x0adevon 👍\x00', 'utf8'));
return struct.decode(stream).should.deep.equal({
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'));
struct.decode(stream, {version: 0}).should.deep.equal({
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x0adevon 👍\x15\x00', 'utf8'));
return struct.decode(stream, {version: 1}).should.deep.equal({
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'));
struct.decode(stream, {obj: {version: 0}}).should.deep.equal({
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x0adevon 👍\x15\x00', 'utf8'));
return struct.decode(stream, {obj: {version: 1}}).should.deep.equal({
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'));
struct.decode(stream, {version: 0}).should.deep.equal({
version: 0,
name: 'devon',
age: 21
});
stream = new DecodeStream(Buffer.from('\x01\x00\x05pasta'));
struct.decode(stream, {version: 0}).should.deep.equal({
version: 0,
name: 'pasta'
});
stream = new DecodeStream(Buffer.from('\x01\x01\x09ice cream\x01'));
return struct.decode(stream, {version: 0}).should.deep.equal({
version: 1,
name: 'ice cream',
isDesert: 1
});
});
return 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'));
return struct.decode(stream).should.deep.equal({
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
});
size.should.equal(8);
size = struct.size({
version: 1,
name: 'devon 👍',
age: 21,
gender: 0
});
return size.should.equal(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
}
}
);
return should.throw(() =>
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'
});
size.should.equal(9);
size = struct.size({
version: 1,
age: 21,
alive: 1,
name: 'devon 👍',
gender: 0
});
return size.should.equal(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'
});
return size.should.equal(15);
});
return 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
}
}
);
return should.throw(() => struct.size()
, /not a fixed size/i);
});
});
return describe('encode', function() {
it('should encode objects to buffers', function(done) {
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 EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x00\x05devon\x15\x01\x0adevon 👍\x15\x00', 'utf8'));
return done();
})
);
struct.encode(stream, {
version: 0,
name: 'devon',
age: 21
}
);
struct.encode(stream, {
version: 1,
name: 'devon 👍',
age: 21,
gender: 0
}
);
return stream.end();
});
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 EncodeStream;
return should.throw(() =>
struct.encode(stream, {
version: 5,
name: 'devon',
age: 21
}
)
);
});
it('should support common header block', function(done) {
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 stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x00\x15\x01\x05devon\x01\x15\x01\x0adevon 👍\x00', 'utf8'));
return done();
})
);
struct.encode(stream, {
version: 0,
age: 21,
alive: 1,
name: 'devon'
}
);
struct.encode(stream, {
version: 1,
age: 21,
alive: 1,
name: 'devon 👍',
gender: 0
}
);
return stream.end();
});
it('should encode pointer data after structure', function(done) {
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 stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x01\x05devon\x15\x09\x05hello', 'utf8'));
return done();
})
);
struct.encode(stream, {
version: 1,
name: 'devon',
age: 21,
ptr: 'hello'
}
);
return stream.end();
});
return it('should support preEncode hook', function(done) {
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 stream = new EncodeStream;
stream.pipe(concat(function(buf) {
buf.should.deep.equal(Buffer.from('\x00\x05devon\x15\x01\x0adevon 👍\x15\x00', 'utf8'));
return done();
})
);
struct.encode(stream, {
name: 'devon',
age: 21
}
);
struct.encode(stream, {
name: 'devon 👍',
age: 21,
gender: 0
}
);
return stream.end();
});
});
});