bin-protocol
Advanced tools
Comparing version 1.1.0 to 2.0.2
211
lib/index.js
'use strict'; | ||
var Long = require('long'); | ||
var Long = require('long'); | ||
var varint = require('./protobuf/varint'); | ||
var Reader = require('./reader'); | ||
var Writer = require('./writer'); | ||
var _ = require('lodash'); | ||
var util = require('util'); | ||
@@ -22,34 +27,75 @@ var primitives = [ | ||
module.exports = (function () { | ||
[ | ||
'Reader', | ||
'Writer' | ||
].forEach(function (service) { | ||
exports[service] = require(__dirname + '/' + service.toLowerCase()); | ||
function Protocol(options) { | ||
this.options = _.defaults(options || {}, { | ||
writerBufSize: 1024, | ||
}); | ||
} | ||
return exports; | ||
})(); | ||
Protocol.Reader_ = Reader; | ||
Protocol.Writer_ = Writer; | ||
exports.define = function (name, config) { | ||
Protocol.prototype.define = function (name, config, namespace) { | ||
if (config.read) { | ||
exports.Reader.define(name, config.read); | ||
this.reader.define(name, config.read, namespace); | ||
} | ||
if (config.write) { | ||
exports.Writer.define(name, config.write); | ||
this.writer.define(name, config.write, namespace); | ||
} | ||
}; | ||
exports.read = function (buffer) { | ||
var reader = new exports.Reader(buffer); | ||
return reader; | ||
Protocol.prototype.read = function (buffer) { | ||
return this.reader.reset(buffer); | ||
}; | ||
exports.write = function (size) { | ||
var writer = new exports.Writer(size); | ||
return writer; | ||
Protocol.prototype.write = function () { | ||
return this.writer.reset(); | ||
}; | ||
function define(name, config, namespace) { | ||
Reader.define(name, config.read, namespace); | ||
Writer.define(name, config.write, namespace); | ||
} | ||
function createProtocol(_SuperProtocol, constructor) { | ||
function _Reader() { | ||
_Reader.super_.apply(this, arguments); | ||
} | ||
function _Writer() { | ||
_Writer.super_.apply(this, arguments); | ||
} | ||
function _P(options) { | ||
_P.super_.call(this, options); | ||
this.reader = new _Reader(); | ||
this.writer = new _Writer(this.options.writerBufSize); | ||
if (typeof constructor === 'function') { | ||
constructor.call(this); | ||
} | ||
} | ||
_P.Reader_ = _Reader; | ||
_P.Writer_ = _Writer; | ||
util.inherits(_P, _SuperProtocol); | ||
util.inherits(_Reader, _SuperProtocol.Reader_); | ||
util.inherits(_Writer, _SuperProtocol.Writer_); | ||
_P.define = function (name, config, namespace) { | ||
Reader.define(name, config.read, namespace, _Reader); | ||
Writer.define(name, config.write, namespace, _Writer); | ||
}; | ||
_P.createProtocol = _.partial(createProtocol, _P); | ||
return _P; | ||
} | ||
module.exports = createProtocol(Protocol); | ||
module.exports.createProtobufProtocol = require('./protobuf'); | ||
primitives.forEach(function (p) { | ||
exports.define(p[0], { | ||
define(p[0], { | ||
read: function () { | ||
@@ -70,3 +116,3 @@ var r = this.buffer['read' + p[0]](this.offset); | ||
exports.define('raw', { | ||
define('raw', { | ||
read: function (bytes) { | ||
@@ -90,3 +136,3 @@ var r; | ||
exports.define('Int64BE', { | ||
define('Int64BE', { | ||
read: function () { | ||
@@ -98,10 +144,5 @@ var l = new Long(this.buffer.readInt32BE(this.offset + 4), this.buffer.readInt32BE(this.offset)); | ||
write: function (value) { | ||
var long; | ||
if (typeof value === 'number') { | ||
long = Long.fromNumber(value); | ||
} else { | ||
long = Long.fromString(value + ''); | ||
} | ||
this.buffer.writeInt32BE(long.getHighBits(), this.offset); | ||
this.buffer.writeInt32BE(long.getLowBits(), this.offset + 4); | ||
value = Long.fromValue(value); | ||
this.buffer.writeInt32BE(value.getHighBits(), this.offset); | ||
this.buffer.writeInt32BE(value.getLowBits(), this.offset + 4); | ||
this.offset += 8; | ||
@@ -111,3 +152,3 @@ } | ||
exports.define('Int64LE', { | ||
define('Int64LE', { | ||
read: function () { | ||
@@ -119,10 +160,5 @@ var l = new Long(this.buffer.readInt32LE(this.offset), this.buffer.readInt32LE(this.offset + 4)); | ||
write: function (value) { | ||
var long; | ||
if (typeof value === 'number') { | ||
long = Long.fromNumber(value); | ||
} else { | ||
long = Long.fromString(value + ''); | ||
} | ||
this.buffer.writeInt32LE(long.getHighBits(), this.offset + 4); | ||
this.buffer.writeInt32LE(long.getLowBits(), this.offset); | ||
value = Long.fromValue(value); | ||
this.buffer.writeInt32LE(value.getHighBits(), this.offset + 4); | ||
this.buffer.writeInt32LE(value.getLowBits(), this.offset); | ||
this.offset += 8; | ||
@@ -132,3 +168,3 @@ } | ||
exports.define('UInt64BE', { | ||
define('UInt64BE', { | ||
read: function () { | ||
@@ -140,10 +176,5 @@ var l = new Long(this.buffer.readUInt32BE(this.offset + 4), this.buffer.readUInt32BE(this.offset), true); | ||
write: function (value) { | ||
var long; | ||
if (typeof value === 'number') { | ||
long = Long.fromNumber(value, true); | ||
} else { | ||
long = Long.fromString(value + '', true); | ||
} | ||
this.buffer.writeUInt32BE(long.getHighBitsUnsigned(), this.offset); | ||
this.buffer.writeUInt32BE(long.getLowBitsUnsigned(), this.offset + 4); | ||
value = Long.fromValue(value); | ||
this.buffer.writeUInt32BE(value.getHighBitsUnsigned(), this.offset); | ||
this.buffer.writeUInt32BE(value.getLowBitsUnsigned(), this.offset + 4); | ||
this.offset += 8; | ||
@@ -153,3 +184,3 @@ } | ||
exports.define('UInt64LE', { | ||
define('UInt64LE', { | ||
read: function () { | ||
@@ -161,12 +192,82 @@ var l = new Long(this.buffer.readUInt32LE(this.offset), this.buffer.readUInt32LE(this.offset + 4), true); | ||
write: function (value) { | ||
var long; | ||
if (typeof value === 'number') { | ||
long = Long.fromNumber(value, true); | ||
value = Long.fromValue(value); | ||
this.buffer.writeUInt32LE(value.getHighBitsUnsigned(), this.offset + 4); | ||
this.buffer.writeUInt32LE(value.getLowBitsUnsigned(), this.offset); | ||
this.offset += 8; | ||
} | ||
}); | ||
// unsigned varint | ||
define('UVarint', { | ||
read: function () { | ||
var v = varint.read(this.buffer, this.offset); | ||
this.offset += v.length; | ||
return v.value; | ||
}, | ||
write: function (value) { | ||
this.offset += varint.write(this.buffer, value, this.offset); | ||
} | ||
}); | ||
// normal signed varint | ||
define('Varint', { | ||
read: function () { | ||
return this.UVarint().context | 0; | ||
}, | ||
// should be 10 bytes long | ||
// https://developers.google.com/protocol-buffers/docs/encoding?hl=en#signed-integers | ||
// Quote: "If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes long – it is, | ||
// effectively, treated like a very large unsigned integer. | ||
// If you use one of the signed types, the resulting varint uses ZigZag encoding, which is much more efficient." | ||
write: function (value) { | ||
if (value < 0) { | ||
this.UVarint64(value); | ||
} else { | ||
long = Long.fromString(value + '', true); | ||
this.UVarint(value); | ||
} | ||
this.buffer.writeUInt32LE(long.getHighBitsUnsigned(), this.offset + 4); | ||
this.buffer.writeUInt32LE(long.getLowBitsUnsigned(), this.offset); | ||
this.offset += 8; | ||
} | ||
}); | ||
// zigzag encoded signed varint | ||
define('SVarint', { | ||
read: function () { | ||
return varint.dezigzag(this.UVarint().context); | ||
}, | ||
write: function (value) { | ||
this.UVarint(varint.zigzag(value)); | ||
} | ||
}); | ||
// unsigned varint 64 bit | ||
define('UVarint64', { | ||
read: function () { | ||
var v = varint.read64(this.buffer, this.offset); | ||
this.offset += v.length; | ||
return v.value; | ||
}, | ||
write: function (value) { | ||
value = Long.fromValue(value); | ||
this.offset += varint.write64(this.buffer, value, this.offset); | ||
} | ||
}); | ||
// normal signed varint 64 bit | ||
define('Varint64', { | ||
read: function () { | ||
return this.UVarint64().context.toSigned(); | ||
}, | ||
write: function (value) { | ||
this.UVarint64(value); | ||
} | ||
}); | ||
// zigzag encoded signed varint 64 | ||
define('SVarint64', { | ||
read: function () { | ||
return varint.dezigzag64(this.UVarint64().context); | ||
}, | ||
write: function (value) { | ||
value = Long.fromValue(value); | ||
this.UVarint64(varint.zigzag64(value)); | ||
} | ||
}); |
@@ -6,26 +6,12 @@ 'use strict'; | ||
function Reader(buffer) { | ||
this.buffer = buffer; | ||
this.offset = 0; | ||
this.result = {}; | ||
this.path = []; | ||
var self = this; | ||
self.reset(buffer); | ||
if (self._unbound_methods) { | ||
self._unbound_methods.forEach(function (opts) { | ||
self.define.apply(self, opts); | ||
}); | ||
} | ||
} | ||
/*function _del(obj, path) { | ||
path.reduce(function(el, p, ind, arr) { | ||
var _r; | ||
if (/(.+?)\[(\d+)\]/.exec(p)) { | ||
_r = el[RegExp.$1][RegExp.$2]; | ||
if (ind === arr.length - 1) { | ||
el[RegExp.$1].pop(); | ||
} | ||
} else { | ||
_r = el[p]; | ||
if (ind === arr.length - 1) { | ||
delete el[p]; | ||
} | ||
} | ||
return _r; | ||
}, obj); | ||
}*/ | ||
module.exports = Reader; | ||
@@ -35,2 +21,5 @@ | ||
enumerable: true, get: function () { | ||
if (this.path.length === 0) { | ||
return this.result; | ||
} | ||
return _.get(this.result, this.path.join('.')); | ||
@@ -42,32 +31,52 @@ }, set: function (v) { | ||
Reader.define = function (name, read) { | ||
Reader.prototype[name] = function (path) { | ||
var _path, r; | ||
function _read(name, read, path) { | ||
var _path, r; | ||
if (typeof path !== 'string') { path = undefined; } | ||
if (typeof path !== 'string') { path = undefined; } | ||
if (path) { | ||
this.path.push(path); | ||
} | ||
if (path) { | ||
this.path.push(path); | ||
} | ||
_path = this.path.join('.'); | ||
_path = this.path.join('.'); | ||
try { | ||
r = read.apply(this, Array.prototype.slice.call(arguments, 1)); | ||
} catch (err) { | ||
throw err; | ||
} finally { | ||
if (path) { | ||
this.path.pop(); | ||
} | ||
try { | ||
r = read.apply(this, Array.prototype.slice.call(arguments, 3)); | ||
} catch (err) { | ||
throw err; | ||
} finally { | ||
if (path) { | ||
this.path.pop(); | ||
} | ||
} | ||
if (r !== undefined) { | ||
if (r !== undefined) { | ||
if (_path) { | ||
_.set(this.result, _path, r); | ||
} else { | ||
this.result = r; | ||
} | ||
} | ||
return this; | ||
}; | ||
return this; | ||
} | ||
Reader.define = function (name, read, namespace, _proto) { | ||
var fname = namespace ? namespace + '.' + name : name; | ||
_proto = _proto || Reader; | ||
if (fname.indexOf('.') !== -1) { | ||
if (!_proto.prototype._unbound_methods) { | ||
_proto.prototype._unbound_methods = []; | ||
} | ||
_proto.prototype._unbound_methods.push([name, read, namespace]); | ||
} else { | ||
_.set(_proto.prototype, fname, _.partial(_read, name, read)); | ||
} | ||
}; | ||
Reader.prototype.define = function (name, read, namespace) { | ||
_.set(this, namespace ? namespace + '.' + name : name, _.bind(_read, this, name, read)); | ||
}; | ||
Reader.prototype.skip = function (bytes) { | ||
@@ -104,1 +113,10 @@ this.offset += bytes; | ||
}; | ||
Reader.prototype.reset = function (buffer) { | ||
this.buffer = buffer; | ||
this.offset = 0; | ||
this.result = {}; | ||
this.path = []; | ||
return this; | ||
}; |
@@ -6,4 +6,12 @@ 'use strict'; | ||
function Writer(bufferSize) { | ||
this.buffer = new Buffer(bufferSize || 1024); | ||
this.offset = 0; | ||
var self = this; | ||
self.buffer = new Buffer(bufferSize || 1024); | ||
self.offset = 0; | ||
if (self._unbound_methods) { | ||
self._unbound_methods.forEach(function (opts) { | ||
self.define.apply(self, opts); | ||
}); | ||
} | ||
} | ||
@@ -13,9 +21,25 @@ | ||
Writer.define = function (name, write) { | ||
Writer.prototype[name] = function (value) { | ||
write.apply(this, [value].concat(Array.prototype.slice.call(arguments, 1))); | ||
return this; | ||
}; | ||
function _write(name, write, value) { | ||
write.apply(this, [value].concat(Array.prototype.slice.call(arguments, 3))); | ||
return this; | ||
} | ||
Writer.define = function (name, write, namespace, _proto) { | ||
var fname = namespace ? namespace + '.' + name : name; | ||
_proto = _proto || Writer; | ||
if (fname.indexOf('.') !== -1) { | ||
if (!_proto.prototype._unbound_methods) { | ||
_proto.prototype._unbound_methods = []; | ||
} | ||
_proto.prototype._unbound_methods.push([name, write, namespace]); | ||
} else { | ||
_.set(_proto.prototype, fname, _.partial(_write, name, write)); | ||
} | ||
}; | ||
Writer.prototype.define = function (name, write, namespace) { | ||
_.set(this, namespace ? namespace + '.' + name : name, _.bind(_write, this, name, write)); | ||
}; | ||
Writer.prototype._growBuffer = function (newSize) { | ||
@@ -39,3 +63,2 @@ var _b = new Buffer(newSize); | ||
Writer.prototype.loop = function (values, fn, iterations) { | ||
@@ -64,4 +87,18 @@ var _break = false, i = 0; | ||
Writer.prototype.result = function () { | ||
return this.buffer.slice(0, this.offset); | ||
/* | ||
Writer.prototype.prepend = function (offset, fn) { | ||
var _b = new Buffer(this.offset - offset); | ||
this.buffer.copy(_b, 0, offset, this.offset); | ||
this.offset = offset; | ||
fn.apply(this, Array.prototype.slice.call(arguments, 2)); | ||
this.demand(_b.length); | ||
_b.copy(this.buffer, this.offset, 0); | ||
this.offset += _b.length; | ||
}; | ||
*/ | ||
Object.defineProperty(Writer.prototype, 'result', { | ||
enumerable: true, get: function () { | ||
return this.buffer.slice(0, this.offset); | ||
} | ||
}); |
@@ -9,3 +9,3 @@ { | ||
}, | ||
"version": "1.1.0", | ||
"version": "2.0.2", | ||
"main": "./lib/index.js", | ||
@@ -15,3 +15,4 @@ "keywords": ["buffer", "raw", "binary", "protocol", "parser", "reader", "builder"], | ||
"lodash": "~=3.10.1", | ||
"long": "~=3.0.1" | ||
"long": "~=3.0.1", | ||
"protocol-buffers-schema": "^3.0.0" | ||
}, | ||
@@ -29,3 +30,3 @@ "devDependencies": { | ||
"scripts": { | ||
"test": "make test" | ||
"test": "make" | ||
}, | ||
@@ -32,0 +33,0 @@ "repository": { |
@@ -5,3 +5,3 @@ # bin-protocol | ||
bin-protocol is a library for parsing and creating arbitrary byte buffers. It was created for [Apache Kafka client](https://github.com/oleksiyk/kafka). | ||
bin-protocol is a library for parsing and creating arbitrary byte buffers with optional protocol buffers support. | ||
@@ -34,6 +34,16 @@ You can build your own type definitions based on the following methods: | ||
Varints: | ||
* UVarint (unsigned 32 bit varint) | ||
* Varint (signed 32 bit varint) | ||
* SVarint (signed zigzag encoded 32 bit varint) | ||
* UVarint64 (unsigned 64 bit varint) | ||
* Varint64 (signed 64 bit varint) | ||
* SVarint64 (signed zigzag encoded 64 bit varint) | ||
Loops (arrays): | ||
* loop | ||
Protocol buffers support: nested messages, packed repeated fields, maps, enums, packages (namespaces), oneofs | ||
### Install | ||
@@ -49,13 +59,12 @@ ``` | ||
```javascript | ||
var protocol = require('bin-protocol'); | ||
var Protocol = require('bin-protocol'); | ||
var protocol = new Protocol(); | ||
var reader = new protocol.Reader(new Buffer([0, 1, 2, 3])); | ||
reader | ||
var result = protocol.read(new Buffer([0, 1, 2, 3])) | ||
.Int8('num1') | ||
.Int8('num2') | ||
.Int8('num3') | ||
.Int8('num4'); | ||
.Int8('num4').result; | ||
console.log(reader.result); // => { num1: 0, num2: 1, num3: 2, num4: 3 } | ||
console.log(result); // => { num1: 0, num2: 1, num3: 2, num4: 3 } | ||
``` | ||
@@ -66,3 +75,2 @@ | ||
```javascript | ||
var protocol = require('bin-protocol'); | ||
@@ -85,7 +93,5 @@ protocol.define('char', { | ||
var reader = new protocol.Reader(new Buffer([5, 97, 98, 99, 100, 101])); | ||
var result = protocol.read(new Buffer([5, 97, 98, 99, 100, 101])).array('chars').result; | ||
reader.array('chars'); | ||
console.log(reader.result); // => { chars: [ 'a', 'b', 'c', 'd', 'e' ] } | ||
console.log(result); // => { chars: [ 'a', 'b', 'c', 'd', 'e' ] } | ||
``` | ||
@@ -95,11 +101,10 @@ | ||
```javascript | ||
var writer = new protocol.Writer(); | ||
writer | ||
var buffer = protocol | ||
.write() | ||
.Int8(1) | ||
.Int8(2) | ||
.Int8(3); | ||
.Int8(3) | ||
.result | ||
var buffer = writer.result(); | ||
console.log(buffer); // => <Buffer 01 02 03> | ||
@@ -118,7 +123,5 @@ ``` | ||
var writer = new protocol.Writer(); | ||
var buffer = protocol.write().array([2, 3, 4]).result; | ||
writer.array([2, 3, 4]); | ||
console.log(writer.result()); // => <Buffer 03 02 03 04> | ||
console.log(buffer); // => <Buffer 03 02 03 04> | ||
``` | ||
@@ -130,5 +133,5 @@ | ||
protocol.define('bytes', { | ||
read: function() { | ||
read: function () { | ||
this.Int32BE('length'); | ||
if(this.context.length <= 0){ | ||
if (this.context.length <= 0) { | ||
return null; | ||
@@ -139,13 +142,12 @@ } | ||
}, | ||
write: function(value) { | ||
write: function (value) { | ||
if (value === undefined || value === null) { | ||
this.Int32BE(-1); | ||
} else { | ||
if(Buffer.isBuffer(value) || typeof value === 'string'){ | ||
this | ||
.Int32BE(value.length) | ||
.raw(value); | ||
} else { | ||
throw new Error('Kafka bytes value should be a Buffer or String'); | ||
if (!Buffer.isBuffer(value)) { | ||
value = new Buffer(_(value).toString(), 'utf8'); | ||
} | ||
this | ||
.Int32BE(value.length) | ||
.raw(value); | ||
} | ||
@@ -168,3 +170,3 @@ } | ||
for(i = 0; i<this.context.length; i++){ | ||
this.Int32BE('items[' + i + ']'); // yes, this works | ||
this.Int32BE('items[' + i + ']'); // yes, it works | ||
} | ||
@@ -209,2 +211,34 @@ | ||
### Protocol buffers support | ||
test.proto: | ||
```proto | ||
package basic; | ||
message Test { | ||
optional string string = 15; | ||
} | ||
``` | ||
```javascript | ||
var Protocol = require('bin-protocol'); | ||
var TestProtocol = Protocol.createProtobufProtocol(fs.readFileSync(path.join(__dirname, 'test.proto'))); | ||
var protocol = new TestProtocol(); | ||
// encode message | ||
var encoded = protocol.write().basic.Test({ | ||
string: 'hello' | ||
}).result; | ||
// decode message | ||
var decoded = protocol.read(encoded).basic.Test().result; | ||
decoded => { string: 'hello' } | ||
``` | ||
# License (MIT) | ||
@@ -211,0 +245,0 @@ |
55
test.js
@@ -1,40 +0,31 @@ | ||
"use strict"; | ||
'use strict'; | ||
var protocol = require('./lib/index'); | ||
// var _ = require('lodash'); | ||
var Protocol = require('./lib/index'); | ||
var _ = require('lodash'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var util = require('util'); | ||
protocol.define('char', { | ||
read: function () { | ||
this.Int8('char'); | ||
return String.fromCharCode(this.context.char); | ||
} | ||
}); | ||
var proto = fs.readFileSync('/Users/oleksiy/src/binary-protocol/test/proto/complex.proto'); | ||
protocol.define('array', { | ||
read: function(primitive) { | ||
this | ||
.Int8('length') | ||
.loop('items', this[primitive], this.context.length); | ||
return this.context.items; | ||
}, | ||
write: function(value, primitive) { | ||
if (value === null || value === undefined) { | ||
this.Int8(-1); | ||
} else { | ||
this | ||
.Int8(value.length) | ||
.loop(value, this[primitive]); | ||
} | ||
} | ||
}); | ||
var GameProtocol = Protocol.createProtobufProtocol(proto); | ||
var reader = new protocol.Reader(new Buffer([5, 97, 98, 99, 100, 101])); | ||
var protocol = new GameProtocol(); | ||
reader | ||
.array('chars', 'char'); | ||
var buffer, r; | ||
console.log(reader.result); // => { chars: [ 'a', 'b', 'c', 'd', 'e' ] } | ||
/*protocol.parseProto(fs.readFileSync('/Users/oleksiy/src/riakproto/riak_pb/src/riak.proto')); | ||
protocol.parseProto(fs.readFileSync('/Users/oleksiy/src/riakproto/riak_pb/src/riak_dt.proto')); | ||
protocol.parseProto(fs.readFileSync('/Users/oleksiy/src/riakproto/riak_pb/src/riak_kv.proto')); | ||
protocol.parseProto(fs.readFileSync('/Users/oleksiy/src/riakproto/riak_pb/src/riak_search.proto')); | ||
protocol.parseProto(fs.readFileSync('/Users/oleksiy/src/riakproto/riak_pb/src/riak_ts.proto')); | ||
protocol.parseProto(fs.readFileSync('/Users/oleksiy/src/riakproto/riak_pb/src/riak_yokozuna.proto'));*/ | ||
var writer = new protocol.Writer(); | ||
buffer = new Buffer([10, 5, 82, 117, 115, 116, 121, 18, 17, 10, 9, 73, 114, 111, 110, 32, 73, 110, 99, 46, 18, 4, 10, 2, 85, 83, 24, 2]); | ||
console.log(writer.array([1, 2, 3], 'Int8').result()); | ||
r = protocol.read(buffer).Game.Cars.Car().result; | ||
console.log(r); | ||
@@ -5,3 +5,3 @@ 'use strict'; | ||
var protocol = require('../lib/index'); | ||
var Protocol = require('../lib/index'); | ||
var Long = require('long'); | ||
@@ -30,3 +30,4 @@ | ||
it('should read ' + p[0], function () { | ||
var reader, buffer = new Buffer(2 * p[1]), num1, num2; | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer(2 * p[1]), num1, num2; | ||
if (p[0].indexOf('U') !== 0) { // signed | ||
@@ -40,4 +41,3 @@ num1 = -123; num2 = 123; | ||
reader = new protocol.Reader(buffer); | ||
reader[p[0]]('num1')[p[0]]('num2').result.should.be.eql({ | ||
protocol.read(buffer)[p[0]]('num1')[p[0]]('num2').result.should.be.eql({ | ||
num1: num1, | ||
@@ -50,6 +50,5 @@ num2: num2 | ||
it('should read raw bytes', function () { | ||
var reader, buffer = new Buffer('abcde'); | ||
reader = new protocol.Reader(buffer); | ||
reader.raw('bytes', 5).result.bytes.toString('utf8').should.be.eql('abcde'); | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer('abcde'); | ||
protocol.read(buffer).raw('bytes', 5).result.bytes.toString('utf8').should.be.eql('abcde'); | ||
}); | ||
@@ -61,2 +60,3 @@ }); | ||
it('Int64BE', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer([0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
@@ -67,2 +67,3 @@ protocol.read(buffer).Int64BE('long').result.long.toString().should.be.eql(slong.toString()); | ||
it('Int64LE', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]); | ||
@@ -73,2 +74,3 @@ protocol.read(buffer).Int64LE('long').result.long.toString().should.be.eql(slong.toString()); | ||
it('UInt64BE', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer([0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
@@ -79,2 +81,3 @@ protocol.read(buffer).UInt64BE('long').result.long.toString().should.be.eql(ulong.toString()); | ||
it('UInt64LE', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F]); | ||
@@ -86,3 +89,3 @@ protocol.read(buffer).UInt64LE('long').result.long.toString().should.be.eql(ulong.toString()); | ||
describe('nested objects and arrays', function () { | ||
var reader, buffer = new Buffer(16); | ||
var buffer = new Buffer(16); | ||
@@ -97,2 +100,3 @@ before(function () { | ||
it('should create nested result object', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('nested', { | ||
@@ -118,2 +122,3 @@ read: function () { | ||
it('should allow custom array results', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('customArray', { | ||
@@ -133,4 +138,3 @@ read: function () { | ||
reader = new protocol.Reader(buffer); | ||
reader.customArray('items').result.should.be.eql({ | ||
protocol.read(buffer).customArray('items').result.should.be.eql({ | ||
items: [2, 3, 4] | ||
@@ -141,2 +145,3 @@ }); | ||
it('should build arrays with loop() method', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('loopArray', { | ||
@@ -157,2 +162,3 @@ read: function () { | ||
it('loop() should stop when end() is called', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('loopArrayEnd', { | ||
@@ -178,7 +184,7 @@ read: function () { | ||
it('primitive method should throw RangeError when trying to read beyond buffer length', function () { | ||
var reader, buffer = new Buffer('abcde'); | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer('abcde'); | ||
reader = new protocol.Reader(buffer); | ||
expect(function () { | ||
reader.loop('chars', reader.Int8, 6); | ||
protocol.read(buffer).loop('chars', protocol.reader.Int8, 6); | ||
}).to.throw(RangeError); | ||
@@ -188,7 +194,7 @@ }); | ||
it('raw() should throw RangeError when trying to read beyond buffer length', function () { | ||
var reader, buffer = new Buffer('abcde'); | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer('abcde'); | ||
reader = new protocol.Reader(buffer); | ||
expect(function () { | ||
reader.raw('chars', 6); | ||
protocol.read(buffer).raw('chars', 6); | ||
}).to.throw(RangeError); | ||
@@ -198,3 +204,4 @@ }); | ||
it('methods should be chainable', function () { | ||
var reader, buffer = new Buffer('abcde'); | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer('abcde'); | ||
@@ -208,5 +215,98 @@ protocol.define('char', { | ||
reader = new protocol.Reader(buffer); | ||
reader.skip(1).demand(1).loop('chars', reader.char, 4).result.should.be.eql({ chars: ['b', 'c', 'd', 'e'] }); | ||
protocol.read(buffer).skip(1).demand(1).loop('chars', protocol.reader.char, 4).result.should.be.eql({ chars: ['b', 'c', 'd', 'e'] }); | ||
}); | ||
it('should be possible to create dynamic fields', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer(6); | ||
buffer.write('xname'); | ||
buffer.writeInt8(10, 5); | ||
protocol.define('dynamic', { | ||
read: function () { | ||
var r = {}; | ||
this | ||
.raw('field_name', 5) | ||
.Int8('field_value'); | ||
// create new field | ||
r[this.context.field_name.toString('utf8')] = this.context.field_value; | ||
this.context = r; | ||
} | ||
}); | ||
protocol.read(buffer).dynamic('obj').result.should.be.eql({ obj: { xname: 10 } }); | ||
}); | ||
it('should assign properties to top context when top context has no name', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer(2); | ||
buffer.writeInt8(1, 0); | ||
buffer.writeInt8(2, 1); | ||
protocol.define('_emptyname', { | ||
read: function () { | ||
this | ||
.Int8('f1') | ||
.Int8('f2'); | ||
} | ||
}); | ||
protocol.define('emptyname', { | ||
read: function () { | ||
this._emptyname(); | ||
} | ||
}); | ||
protocol.read(buffer).emptyname().result.should.be.eql({ f1: 1, f2: 2 }); | ||
}); | ||
it('should assign properties to top context when top context has no name when overwriting context', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer(2); | ||
buffer.writeInt8(1, 0); | ||
buffer.writeInt8(2, 1); | ||
protocol.define('_emptyname', { | ||
read: function () { | ||
return this.Int8().context + this.Int8().context; | ||
} | ||
}); | ||
protocol.define('emptyname', { | ||
read: function () { | ||
this._emptyname(); | ||
} | ||
}); | ||
protocol.read(buffer).emptyname().result.should.be.eql(3); | ||
}); | ||
it('should assign properties to top context when top context has no name in the loop', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer('abcde'); | ||
protocol.define('char', { | ||
read: function () { | ||
return String.fromCharCode(this.Int8().context); | ||
} | ||
}); | ||
protocol.read(buffer).loop('chars', protocol.reader.char, 5).result.should.be.eql({ chars: ['a', 'b', 'c', 'd', 'e'] }); | ||
}); | ||
it('should support namespaces', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer('a'); | ||
protocol.define('char', { | ||
read: function () { | ||
return String.fromCharCode(this.Int8().context); | ||
} | ||
}, 'org.test.types'); | ||
protocol.read(buffer).org.test.types.char('char').result.should.be.eql({ char: 'a' }); | ||
}); | ||
}); |
@@ -5,3 +5,3 @@ 'use strict'; | ||
var protocol = require('../lib/index'); | ||
var Protocol = require('../lib/index'); | ||
var Long = require('long'); | ||
@@ -30,2 +30,3 @@ | ||
it('should write ' + p[0], function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer(2 * p[1]), num1, num2; | ||
@@ -40,3 +41,3 @@ if (p[0].indexOf('U') !== 0) { // signed | ||
protocol.write()[p[0]](num1)[p[0]](num2).result().should.be.eql(buffer); | ||
protocol.write()[p[0]](num1)[p[0]](num2).result.should.be.eql(buffer); | ||
}); | ||
@@ -46,19 +47,25 @@ }); | ||
it('should write raw bytes from buffer', function () { | ||
var protocol = new Protocol(); | ||
var buffer = new Buffer([1, 2, 3, 4]); | ||
protocol.write().raw(buffer).result().should.be.eql(buffer); | ||
protocol.write().raw(buffer).result.should.be.eql(buffer); | ||
}); | ||
it('should write raw bytes from string', function () { | ||
var writer, string = 'abcde'; | ||
var protocol = new Protocol(); | ||
var string = 'abcde'; | ||
writer = new protocol.Writer(); | ||
writer.raw(string).result().toString('utf8').should.be.eql('abcde'); | ||
protocol.write().raw(string).result.toString('utf8').should.be.eql(string); | ||
}); | ||
it('should write raw bytes from utf8 string', function () { | ||
var protocol = new Protocol(); | ||
var string = '人人生而自由,在尊嚴和權利上一律平等。'; | ||
protocol.write().raw(string).result.toString('utf8').should.be.eql(string); | ||
}); | ||
it('should write raw bytes from array of octets', function () { | ||
var writer, array = [1, 2, 3, 4]; | ||
writer = new protocol.Writer(); | ||
writer.raw(array).result().should.be.eql(new Buffer(array)); | ||
var protocol = new Protocol(); | ||
var array = [1, 2, 3, 4]; | ||
protocol.write().raw(array).result.should.be.eql(new Buffer(array)); | ||
}); | ||
@@ -70,42 +77,42 @@ }); | ||
ulong = new Long(0xFFFFFFFF, 0x7FFFFFFF, true), | ||
MAX_NUM = 9007199254740991, MIN_NUM = -9007199254740991, writer; | ||
MAX_NUM = 9007199254740991, MIN_NUM = -9007199254740991; | ||
it('Int64BE', function () { | ||
writer = new protocol.Writer(); | ||
writer.Int64BE(slong).result().should.be.eql(new Buffer([0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])); | ||
var protocol = new Protocol(); | ||
protocol.write().Int64BE(slong).result.should.be.eql(new Buffer([0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])); | ||
}); | ||
it('Int64BE from number', function () { | ||
writer = new protocol.Writer(); | ||
writer.Int64BE(MIN_NUM).result().should.be.eql(new Buffer([0XFF, 0XE0, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01])); | ||
var protocol = new Protocol(); | ||
protocol.write().Int64BE(MIN_NUM).result.should.be.eql(new Buffer([0XFF, 0XE0, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01])); | ||
}); | ||
it('Int64LE', function () { | ||
writer = new protocol.Writer(); | ||
writer.Int64LE(slong).result().should.be.eql(new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F])); | ||
var protocol = new Protocol(); | ||
protocol.write().Int64LE(slong).result.should.be.eql(new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F])); | ||
}); | ||
it('Int64LE from number', function () { | ||
writer = new protocol.Writer(); | ||
writer.Int64LE(MIN_NUM).result().should.be.eql(new Buffer([0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0XE0, 0XFF])); | ||
var protocol = new Protocol(); | ||
protocol.write().Int64LE(MIN_NUM).result.should.be.eql(new Buffer([0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0XE0, 0XFF])); | ||
}); | ||
it('UInt64BE', function () { | ||
writer = new protocol.Writer(); | ||
writer.UInt64BE(ulong).result().should.be.eql(new Buffer([0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])); | ||
var protocol = new Protocol(); | ||
protocol.write().UInt64BE(ulong).result.should.be.eql(new Buffer([0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])); | ||
}); | ||
it('UInt64BE from number', function () { | ||
writer = new protocol.Writer(); | ||
writer.UInt64BE(MAX_NUM).result().should.be.eql(new Buffer([0X00, 0X1F, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF])); | ||
var protocol = new Protocol(); | ||
protocol.write().UInt64BE(MAX_NUM).result.should.be.eql(new Buffer([0X00, 0X1F, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF])); | ||
}); | ||
it('UInt64LE', function () { | ||
writer = new protocol.Writer(); | ||
writer.UInt64LE(ulong).result().should.be.eql(new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F])); | ||
var protocol = new Protocol(); | ||
protocol.write().UInt64LE(ulong).result.should.be.eql(new Buffer([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F])); | ||
}); | ||
it('UInt64LE from number', function () { | ||
writer = new protocol.Writer(); | ||
writer.UInt64LE(MAX_NUM).result().should.be.eql(new Buffer([0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X1F, 0X00])); | ||
var protocol = new Protocol(); | ||
protocol.write().UInt64LE(MAX_NUM).result.should.be.eql(new Buffer([0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X1F, 0X00])); | ||
}); | ||
@@ -115,5 +122,4 @@ }); | ||
describe('arrays (loop)', function () { | ||
var writer; | ||
it('should write custom array', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('customArray', { | ||
@@ -131,7 +137,7 @@ write: function (values) { | ||
writer = new protocol.Writer(); | ||
writer.customArray([2, 3, 4]).result().should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4])); | ||
protocol.write().customArray([2, 3, 4]).result.should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4])); | ||
}); | ||
it('should write arrays with loop() method', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('loopArray', { | ||
@@ -145,7 +151,7 @@ write: function (values) { | ||
writer = new protocol.Writer(); | ||
writer.loopArray([2, 3, 4]).result().should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4])); | ||
protocol.write().loopArray([2, 3, 4]).result.should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4])); | ||
}); | ||
it('loop should honour iterations argument', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('loopArrayIterations', { | ||
@@ -159,7 +165,7 @@ write: function (values) { | ||
writer = new protocol.Writer(); | ||
writer.loopArrayIterations([2, 3, 4]).result().should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3])); | ||
protocol.write().loopArrayIterations([2, 3, 4]).result.should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3])); | ||
}); | ||
it('loop should stop when end() called', function () { | ||
var protocol = new Protocol(); | ||
protocol.define('loopArrayEnd', { | ||
@@ -179,4 +185,3 @@ write: function (values) { | ||
writer = new protocol.Writer(); | ||
writer.loopArrayEnd([2, 3, 4]).result().should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3])); | ||
protocol.write().loopArrayEnd([2, 3, 4]).result.should.be.eql(new Buffer([0, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, 3])); | ||
}); | ||
@@ -186,4 +191,3 @@ }); | ||
it('methods should be chainable', function () { | ||
var writer; | ||
var protocol = new Protocol(); | ||
protocol.define('char', { | ||
@@ -195,5 +199,18 @@ write: function (char) { | ||
writer = new protocol.Writer(); | ||
writer.skip(0).demand(1).loop(['a', 'b', 'c', 'd'], writer.char).result().should.be.eql(new Buffer([97, 98, 99, 100])); | ||
protocol.write().skip(0).demand(1).loop(['a', 'b', 'c', 'd'], protocol.writer.char).result.should.be.eql(new Buffer([97, 98, 99, 100])); | ||
}); | ||
it('reset() should reset writer buffer', function () { | ||
var protocol = new Protocol(); | ||
protocol.write().Int8(1).reset().Int8(2).result.should.be.eql(new Buffer([2])); | ||
}); | ||
it('should be able to grow buffer when needed', function () { | ||
var protocol = new Protocol({ | ||
writerBufSize: 1 | ||
}); | ||
protocol.writer.buffer.length.should.be.eql(1); | ||
protocol.write().Int8(1).Int8(2).result.should.be.eql(new Buffer([1, 2])); | ||
}); | ||
}); |
28
test2.js
@@ -1,18 +0,20 @@ | ||
"use strict"; | ||
'use strict'; | ||
var protocol = require('./lib/index'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
protocol.define('array', { | ||
read: function (context) { | ||
this | ||
.Int32BE('length') | ||
.loop('items', this.Int32BE, context.length); | ||
return context.items; | ||
} | ||
}); | ||
var Protocol = require('./lib/index'); | ||
var writer = new protocol.Writer(2); | ||
var TestProtocol = Protocol.createProtobufProtocol(fs.readFileSync(path.join(__dirname, 'test/proto/basic.proto'))); | ||
writer.Int32BE(10); | ||
var protocol = new TestProtocol(); | ||
console.log(writer.result(), writer.buffer.length); | ||
// encode message | ||
var encoded = protocol.write().basic.Test({ | ||
string: 'hello' | ||
}).result; | ||
// decode message | ||
var decoded = protocol.read(encoded).basic.Test().result; | ||
console.log(decoded); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
135789
35
2058
259
3
3
1
+ Addedprotocol-buffers-schema@3.6.0(transitive)