Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

binary-data

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

binary-data - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

.jest-cache/jest-transform-cache-dd6e47c96cc7abb829b1ea2d20d98747-c099605dca12849ddceb005d2f7f7eb6/1d/index_1dcb2fbcacad25107a100991c04d0cf5

38

benchmark/decode.js
'use strict';
const { types, decode } = require('..');
const binary = require('binary'); // eslint-disable-line node/no-unpublished-require

@@ -62,4 +63,41 @@ /* eslint-disable no-useless-concat */

function testBinary(i) {
while (--i > 0) {
parseBinary();
}
}
function parseBinary() {
// Incomplete ClientHello packet
const record = binary
.parse(packet)
.word8u('contentType')
.word16bu('version')
.word16bu('epoch')
.buffer('sequenceNumber', 6)
.word16bu('length')
.buffer('body', 'length').vars;
const handshake = binary
.parse(record.body)
.word8u('type')
.buffer('length', 3)
.word16bu('messageSeq')
.buffer('fragment_offset', 3)
.buffer('fragment_length', 3)
.word16bu('clientVersion')
.word32bu('gmtunixtime')
.buffer('randomBytes', 28)
.word8u('sessionId_length')
.buffer('sessionId', 'sessionId_length')
.word8u('cookie_length')
.buffer('cookie', 'cookie_length').vars;
return [record, handshake];
}
console.time('binary data');
test(count);
console.timeEnd('binary data');
console.time('binary');
testBinary(count);
console.timeEnd('binary');

9

package.json
{
"name": "binary-data",
"version": "0.5.0",
"description": "Declarative encoder/decoder of various binary data.",
"version": "0.6.0",
"description": "Declarative binary data encoder / decoder.",
"main": "src/index.js",

@@ -25,3 +25,4 @@ "scripts": {

"bin-protocol",
"restructure"
"restructure",
"varstruct"
],

@@ -43,2 +44,4 @@ "author": "Dmitry Tsvettsikh <me@reklatsmasters.com>",

"@nodertc/eslint-config": "0.2.1",
"binary": "^0.3.0",
"bl": "^2.1.2",
"eslint": "^5.6.1",

@@ -45,0 +48,0 @@ "jest": "^23.6.0",

@@ -10,4 +10,8 @@ # binary-data

Declarative encoder/decoder of various binary data. This module works almost like as [`binary`](https://www.npmjs.com/package/binary) or [`restructure`](https://www.npmjs.com/package/restructure) but provided modern and clean api.
Declarative binary data encoder / decoder. This module works almost like as [`binary`](https://www.npmjs.com/package/binary) or [`restructure`](https://www.npmjs.com/package/restructure) but provided modern and clean api. It inspired by [abstract-encoding](https://github.com/mafintosh/abstract-encoding) interface.
### Support
[![Buy Me A Coffee](https://www.buymeacoffee.com/assets/img/custom_images/purple_img.png)](https://www.buymeacoffee.com/reklatsmasters)
## Usage

@@ -18,5 +22,5 @@

```js
const { decode, createDecodeStream, types: { uint8, array, string } } = require('binary-data')
const { decode, createDecode, types: { uint8, array, string } } = require('binary-data')
// 1.1 define your own schema as plain object
// 1. Define your own schema as plain object
const protocol = {

@@ -27,17 +31,16 @@ type: uint8,

socket.on('message', (message) => {
// 1.2 decode message
const packet = decode(message, protocol)
})
const message = Buffer.from([1, 2, 3, 4, 5, 6, 0]);
// 2.1 also you may decode messages from streams
const unicast = require('unicast')
// Just decode message
const packet = decode(message, protocol)
const socket = unicast.createSocket({ /* options */ })
// 2 Also you may decode messages from streams
const net = require('net');
// 2.2 create stream
const input = createDecodeStream(protocol)
const socket = net.createConnection({ port: 8124 });
const istream = createDecode(protocol);
// 2.3 connect streams
socket.pipe(input).on('data', packet => { /* do stuff */ })
socket.pipe(istream).on('data', packet => {
console.log(packet.type, packet.value);
});
```

@@ -48,30 +51,37 @@

```js
const { encode, createEncodeStream, types: { uint8, buffer } } = require('binary-data')
const { encode, createEncode, types: { uint8, string } } = require('binary-data')
// 1. define schema
const protocol = {
type: uint8,
data: buffer(uint8)
value: string(uint8)
}
// 2. create data object (string, array - what you want)
const hello = {
type: 12,
data: Buffer.from('my random data')
value: 'my random data'
}
// 3. create encode stream
const wstream = createEncodeStream(protocol)
// Just encode message
const ostream = encode(hello, protocol);
const packet = ostream.slice();
// 4. connect streams
wstream.pipe(socket)
// Or you may encode messages into a stream
const net = require('net');
// 5.1. encode all your data
wstream.write(hello)
const ostream = createEncode(protocol);
const socket = net.createConnection({ port: 8124 }, () => {
ostream.write(hello);
});
// 5.2 or use another schema
encode(anotherPacket, wstream, anotherSchema)
ostream.pipe(socket);
// 5.3 or convert to a buffer
const buf = wstream.slice()
// You may combine multiple schemes into one stream
const ostream = createEncode();
encode(obj1, ostream, protocol1);
encode(obj2, ostream, protocol2);
encode(obj3, ostream, protocol3);
const packet = ostream.slice();
```

@@ -81,9 +91,20 @@

## Perfomance
Decoding DTLS ClientHello packet, *nodejs 10.14.1 / Ubuntu 16.04 x64*
|name|time|
|---|---|
|binary data|637.900ms|
|binary|2229.218ms|
## API
* [`decode(rstream: DecodeStream|Buffer, type: PrimitiveType|Object): any`](#decode)
* [`encode(item: any, wstream: EncodeStream, type: PrimitiveType|Object): void`](#encode)
* [`encodingLength(item: any, type: PrimitiveType|Object): Number`](#encoding-length)
* [`createEncodeStream(): EncodeStream`](#create-encode-stream)
* [`createDecodeStream([buf: Buffer]): DecodeStream`](#create-decode-stream)
* [`encode(obj: any, [target: BinaryStream], type: Object): BinaryStream`](#encode)
* [`decode(source: BinaryStream|Buffer, type: Object): any`](#decode)
* [`encodingLength(item: any, type: Object): Number`](#encoding-length)
* [`createEncodeStream([type: Object]): BinaryStream`](#create-encode-stream)
* [`createDecodeStream([type: Object|Buffer]): BinaryStream`](#create-decode-stream)
* [`createEncode([type: Object]): BinaryStream`](#create-encode-stream)
* [`createDecode([type: Object|Buffer]): BinaryStream`](#create-decode-stream)
* [Types](#types)

@@ -101,3 +122,3 @@ * [`(u)int(8, 16, 24, 32, 40, 48)(be, le)`](#types-int)

#### `decode(rstream: DecodeStream|Buffer, type: PrimitiveType|Object): any`
#### `decode(source: BinaryStream|Buffer, type: Object): any`

@@ -108,9 +129,9 @@ Reads any data from stream `rstream` using data type `type`. See examples above.

#### `encode(item: any, wstream: EncodeStream, type: PrimitiveType|Object): void`
#### `encode(obj: any, [target: BinaryStream], type: Object): BinaryStream`
Writes any data `item` to stream `wstream` using data type `type`. See examples above.
Writes any data `obj` to stream `target` using data type `type`. See examples above.
<a name='encoding-length' />
#### `encodingLength(item: any, type: PrimitiveType|Object): Number`
#### `encodingLength(item: any, type: Object): Number`

@@ -121,11 +142,13 @@ Return the amount of bytes needed to encode `item` using `type`.

#### `createEncodeStream(): EncodeStream`
#### `createEncodeStream([type: Object]): BinaryStream`
#### `createEncode([type: Object]): BinaryStream`
Create instance of EncodeStream.
Create instance of BinaryStream.
<a name='create-decode-stream' />
#### `createDecodeStream([buf: Buffer]): DecodeStream`
#### `createDecodeStream([type: Object|Buffer]): BinaryStream`
#### `createDecode([type: Object|Buffer]): BinaryStream`
Create instance of DecodeStream using buffer `buf`.
Create instance of BinaryStream.

@@ -217,5 +240,5 @@ <a name='types' />

#### `buffer(length)`
#### `buffer(length: Object|null|number)`
Low-level buffer type. Argument `length` can be _number_, number _type_ for size-prefixed data or _function_.
Low-level buffer type. Argument `length` can be _number_, number _type_ for size-prefixed data, _function_ or _null_.

@@ -222,0 +245,0 @@ ```js

'use strict';
const EncodeStream = require('streams/encode');
const DecodeStream = require('streams/decode');
const BinaryStream = require('lib/binary-stream');
const array = require('types/array');

@@ -33,2 +32,4 @@ const buffer = require('types/buffer');

const kschema = Symbol('schema');
/**

@@ -40,6 +41,10 @@ * Create transform stream to encode objects into Buffer.

function createEncodeStream(schema) {
return new EncodeStream({
schema,
const stream = new BinaryStream({
readableObjectMode: false,
writableObjectMode: true,
transform: transformEncode,
});
stream[kschema] = schema;
return stream;
}

@@ -60,7 +65,10 @@

const stream = new DecodeStream({
schema,
const stream = new BinaryStream({
transform: transformDecode,
readableObjectMode: true,
writableObjectMode: false,
});
stream[kschema] = schema;
if (isBuffer) {

@@ -81,3 +89,3 @@ stream.append(bufOrSchema);

try {
encode(chunk, this, this.schema);
encode(chunk, this[kschema], this);

@@ -105,3 +113,3 @@ const buf = this.slice();

const transaction = new Transaction(this);
const data = decode(transaction, this.schema);
const data = decode(transaction, this[kschema]);

@@ -130,2 +138,6 @@ transaction.commit();

/* aliases */
createEncode: createEncodeStream,
createDecode: createDecodeStream,
/* Data types */

@@ -135,5 +147,4 @@ types,

/* Re-export utils */
EncodeStream,
DecodeStream,
BinaryStream,
NotEnoughDataError,
};

@@ -28,3 +28,3 @@ 'use strict';

* Adds an additional buffer or BufferList to the internal list.
* @param {Buffer|Buffer[]} buf
* @param {Buffer|Buffer[]|BufferList|BufferList[]} buf
*/

@@ -45,2 +45,23 @@ append(buf) {

}
} else if (buf instanceof BufferList) {
if (this.offset > 0) {
const head = this.queue.shift();
this.queue.unshift(head.slice(this.offset));
this.offset = 0;
}
if (buf.offset > 0) {
const head = buf.queue.shift();
buf.queue.unshift(head.slice(buf.offset));
buf.offset = 0;
}
let leaf = buf.queue.head;
while (leaf) {
this.queue.push(leaf.buffer);
leaf = leaf.next;
}
}

@@ -122,11 +143,13 @@ }

const bufs = new Array(subset.count);
let leaf = subset.head;
const target = Buffer.allocUnsafe(subset.length);
let offset = 0;
for (let i = 0; i < bufs.length; i += 1) {
bufs[i] = leaf.buffer;
for (let i = 0; i < subset.count; i += 1) {
target.set(leaf.buffer, offset);
offset += leaf.buffer.length;
leaf = leaf.next;
}
return Buffer.concat(bufs, subset.length);
return target;
/* eslint-enable no-param-reassign */

@@ -167,2 +190,76 @@ }

}
/**
* Returns the first (least) index of an element
* within the list equal to the specified value,
* or -1 if none is found.
* @param {number} byte
* @param {number} [offset]
* @returns {number}
*/
indexOf(byte, offset = 0) {
/* eslint-disable no-param-reassign */
if (!Number.isInteger(byte)) {
throw new TypeError('Invalid argument 1');
}
if (byte < 0 || byte > 0xff) {
throw new Error('Invalid argument 1');
}
if (!Number.isInteger(offset)) {
offset = 0;
}
while (offset >= this.length) {
offset -= this.length;
}
while (offset < 0) {
offset += this.length;
}
let leaf = this.queue.head;
let bias = 0;
const next = () => {
bias += leaf.buffer.length;
leaf = leaf.next;
};
while (leaf) {
let byteOffset = 0;
if (leaf === this.queue.head) {
byteOffset += this.offset;
}
// `offset` is point to next chunk
if (offset >= leaf.buffer.length - byteOffset) {
offset -= leaf.buffer.length - byteOffset;
next();
continue; // eslint-disable-line no-continue
}
// `offset` is point to current chunk
if (offset < leaf.buffer.length) {
byteOffset += offset;
}
const index = leaf.buffer.indexOf(byte, byteOffset);
if (index > -1) {
return index + bias - this.offset;
}
next();
if (byteOffset > this.offset) {
offset = 0;
}
}
return -1;
/* eslint-enable no-param-reassign */
}
}

@@ -169,0 +266,0 @@

'use strict';
const { isType, isUserType, isDecodeType } = require('lib/util');
const DecodeStream = require('streams/decode');
const BinaryStream = require('lib/binary-stream');
const symbols = require('internal/symbols');

@@ -15,3 +15,3 @@ const Metadata = require('internal/meta');

* Decode any data from provided stream using schema.
* @param {DecodeStream} rstream Read stream to decode.
* @param {BinaryStream} rstream Read stream to decode.
* @param {Object} typeOrSchema Builtin data type or schema.

@@ -24,3 +24,4 @@ * @returns {*}

if (Buffer.isBuffer(rstream)) {
decodeStream = new DecodeStream(rstream);
decodeStream = new BinaryStream();
decodeStream.append(rstream);
}

@@ -39,3 +40,3 @@

* @private
* @param {DecodeStream|Buffer} rstream
* @param {BinaryStream|Buffer} rstream
* @param {Object} typeOrSchema

@@ -57,3 +58,3 @@ * @param {Metadata} meta

* @private
* @param {DecodeStream} rstream
* @param {BinaryStream} rstream
* @param {Object} schema

@@ -60,0 +61,0 @@ * @param {Metadata} meta

@@ -6,2 +6,3 @@ 'use strict';

const Metadata = require('internal/meta');
const BinaryStream = require('lib/binary-stream');

@@ -14,13 +15,27 @@ module.exports = {

/**
* @param {any} object
* @param {EncodeStream} wstream
* @param {any} typeOrSchema
* @param {any} obj
* @param {any} type
* @param {BinaryStream} [target]
* @returns {BinaryStream}
*/
function encode(object, wstream, typeOrSchema) {
function encode(obj, type, target) {
const meta = new Metadata();
encodeCommon(object, wstream, typeOrSchema, meta);
// Check for legacy interface.
if (type instanceof BinaryStream) {
const tmp = target;
target = type; // eslint-disable-line no-param-reassign
type = tmp; // eslint-disable-line no-param-reassign
}
if (!(target instanceof BinaryStream)) {
target = new BinaryStream(); // eslint-disable-line no-param-reassign
}
encodeCommon(obj, target, type, meta);
encode.bytes = meta.bytes;
Metadata.clean(meta);
return target;
}

@@ -27,0 +42,0 @@

@@ -82,2 +82,11 @@ 'use strict';

}
/**
* @param {number} byte
* @param {number} [offset]
* @returns {number}
*/
indexOf(byte, offset = 0) {
return this.stream.indexOf(byte, this.index + offset) - this.index;
}
}

@@ -84,0 +93,0 @@

'use strict';
const { isType, isFunction } = require('lib/util');
const NotEnoughDataError = require('lib/not-enough-data-error');
const BinaryStream = require('lib/binary-stream');

@@ -16,4 +18,5 @@ module.exports = buffer;

const isfunc = isFunction(length);
const isNull = length === null;
if (!isnum && !istype && !isfunc) {
if (!isnum && !istype && !isfunc && !isNull) {
throw new TypeError('Unknown type of argument #1.');

@@ -56,4 +59,9 @@ }

wstream.writeBuffer(buf);
wstream.writeBuffer(Buffer.isBuffer(buf) ? buf : buf.buffer);
encode.bytes += buf.length;
if (isNull) {
wstream.writeUInt8(0);
encode.bytes += 1;
}
}

@@ -83,2 +91,8 @@

checkLengthType(size);
} else if (isNull) {
size = rstream.indexOf(0);
if (size === -1) {
throw new NotEnoughDataError(rstream.length + 1, rstream.length);
}
}

@@ -89,2 +103,7 @@

if (isNull) {
decode.bytes += 1;
rstream.consume(1);
}
return buf;

@@ -106,4 +125,6 @@ }

if (istype) {
size += length.encodingLength(buf.length);
if (isNull) {
size = 1;
} else if (istype) {
size = length.encodingLength(buf.length);
}

@@ -121,4 +142,4 @@

function checkBuffer(buf) {
if (!Buffer.isBuffer(buf)) {
throw new TypeError('Argument 1 should be a Buffer.');
if (!Buffer.isBuffer(buf) && !(buf instanceof BinaryStream)) {
throw new TypeError('Argument 1 should be a Buffer or a BinaryStream.');
}

@@ -125,0 +146,0 @@ }

@@ -93,10 +93,6 @@ 'use strict';

return function decode(rstream) {
let bytes = 0;
const bytes = rstream.indexOf(0);
while (rstream.get(bytes) !== 0) {
bytes += 1;
if (bytes >= rstream.length) {
throw new NotEnoughDataError(bytes, rstream.length);
}
if (bytes === -1) {
throw new NotEnoughDataError(rstream.length + 1, rstream.length);
}

@@ -103,0 +99,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc