binary-data
Declarative binary data encoder / decoder. This module works almost like as binary
or restructure
but provided modern and clean api. It inspired by abstract-encoding interface.
Support
Usage
decode
const { decode, createDecode, types: { uint8, array, string } } = require('binary-data')
const protocol = {
type: uint8,
value: array(string(null), uint8)
}
const message = Buffer.from([1, 2, 3, 4, 5, 6, 0]);
const packet = decode(message, protocol)
const net = require('net');
const socket = net.createConnection({ port: 8124 });
const istream = createDecode(protocol);
socket.pipe(istream).on('data', packet => {
console.log(packet.type, packet.value);
});
encode
const { encode, createEncode, types: { uint8, string } } = require('binary-data')
const protocol = {
type: uint8,
value: string(uint8)
}
const hello = {
type: 12,
value: 'my random data'
}
const ostream = encode(hello, protocol);
const packet = ostream.slice();
const net = require('net');
const ostream = createEncode(protocol);
const socket = net.createConnection({ port: 8124 }, () => {
ostream.write(hello);
});
ostream.pipe(socket);
const ostream = createEncode();
encode(obj1, ostream, protocol1);
encode(obj2, ostream, protocol2);
encode(obj3, ostream, protocol3);
const packet = ostream.slice();
See stun or dtls module for complete example.
Perfomance
Decoding DTLS ClientHello packet, nodejs 10.14.1 / Ubuntu 16.04 x64
name | time |
---|
binary data | 637.900ms |
binary | 2229.218ms |
API
encode(obj: any, [target: BinaryStream], type: Object): BinaryStream
decode(source: BinaryStream|Buffer, type: Object): any
encodingLength(item: any, type: Object): Number
createEncodeStream([type: Object]): BinaryStream
createDecodeStream([type: Object|Buffer]): BinaryStream
createEncode([type: Object]): BinaryStream
createDecode([type: Object|Buffer]): BinaryStream
- Types
(u)int(8, 16, 24, 32, 40, 48)(be, le)
(double, float)(be, le)
array(type: Object, length: number|Object|Function, lengthType: string)
string(length)
bool(type: any)
buffer(length)
reserved(type, count)
when(fn: function(context): boolean, type)
decode(source: BinaryStream|Buffer, type: Object): any
Reads any data from stream rstream
using data type type
. See examples above.
encode(obj: any, [target: BinaryStream], type: Object): BinaryStream
Writes any data obj
to stream target
using data type type
. See examples above.
encodingLength(item: any, type: Object): Number
Return the amount of bytes needed to encode item
using type
.
createEncodeStream([type: Object]): BinaryStream
createEncode([type: Object]): BinaryStream
Create instance of BinaryStream.
createDecodeStream([type: Object|Buffer]): BinaryStream
createDecode([type: Object|Buffer]): BinaryStream
Create instance of BinaryStream.
types: Object
Contains all primitive data types.
Types
(u)int(8, 16, 24, 32, 40, 48)(be, le)
Low-level integer types.
const schema = {
type: int8
}
const int64 = buffer(8)
(double, float)(be, le)
Low-level floating-point types.
const schema = {
size: doublele
}
array(type: Object, length: number|Object|Function, lengthType: string)
Array of low-level or user defined types. Argument type
should be primitive type or user defined scheme. Argument length
should be a number, number type or function. Argument lengthType
should be bytes
or count
(default).
array(uint8, 3)
const schema = {
length: uint8,
type: uint32be,
items: array(uint16, ({node}) => node.length, 'bytes')
}
array(uint16, uint8)
array(uint16, uint8, 'bytes')
string(length)
Low-level string type. Argument length
can be number, null for C - strings, type for size-prefixed data or function.
bool(type: any)
Convert provided type to / from boolean. Argument type
should be an number type.
const schema = bool(uint8)
const rstream = createDecodeStream(buf)
decode(rstream, schema)
decode(rstream, schema)
buffer(length: Object|null|number)
Low-level buffer type. Argument length
can be number, number type for size-prefixed data, function or null.
buffer(5)
buffer(uint8)
const packet = {
header: {
length: uint16be
},
data: buffer(({node}) => node.header.length % 2)
}
reserved(type, count)
Special type to skip any data. Argument count
should be a number, number type or function.
const packet = {
type: uint8,
_padding: reserved(uint8, 3)
}
decode(rstream, packet)
when(fn: function(context): boolean, type)
Special type for conditions. Argument fn
should be a function and should return boolean value. The type
argument will be evaluated when the first one returns positive value.
const schema = {
type: uint8,
bytes: when(({ node }) => node.type === 1, string(uint16be)),
list: when(({ node }) => node.type === 2, array(uint32be, uint8))
}
select(when, ..., defaultType)
The second type for conditions. The same as switch
operator in js. Argument defaultType
may be any known
type excluding user schemas.
const schema = {
id: uint8,
payload: select(when(({ node }) => node.id === 1, string(uint16be)), buffer(uint16be))
}
License
MIT, 2017 (c) Dmitriy Tsvettsikh