From 812b73ffbcd41739c6a82a8a7b77310d23a4103a Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 27 Jul 2016 16:26:43 -0700 Subject: [PATCH] bip151: use reference slices initially for parsing. --- lib/bcoin/bip151.js | 72 ++++++++++++++++++++++++++++---------- lib/bcoin/workers.js | 83 ++++++++++++++++++++++++-------------------- 2 files changed, 100 insertions(+), 55 deletions(-) diff --git a/lib/bcoin/bip151.js b/lib/bcoin/bip151.js index 7ea88411..e63e0e00 100644 --- a/lib/bcoin/bip151.js +++ b/lib/bcoin/bip151.js @@ -273,32 +273,68 @@ BIP151Stream.prototype.verify = function verify(tag) { */ BIP151Stream.prototype.feed = function feed(data) { - var chunk, off, len; + var chunk; this.total += data.length; this.pending.push(data); while (this.total >= this.waiting) { - chunk = new Buffer(this.waiting); - off = 0; - len = 0; - - while (off < chunk.length) { - len = this.pending[0].copy(chunk, off); - if (len === this.pending[0].length) - this.pending.shift(); - else - this.pending[0] = this.pending[0].slice(len); - off += len; - } - - assert.equal(off, chunk.length); - - this.total -= chunk.length; + chunk = this.read(this.waiting); this.parse(chunk); } }; +/** + * Read and consume a number of bytes + * from the buffered stream. + * @param {Number} size + * @returns {Buffer} + */ + +BIP151Stream.prototype.read = function read(size) { + var pending, chunk, off, len; + + assert(this.total >= size, 'Reading too much.'); + + if (size === 0) + return new Buffer(0); + + pending = this.pending[0]; + + if (pending.length > size) { + chunk = pending.slice(0, size); + this.pending[0] = pending.slice(size); + this.total -= chunk.length; + return chunk; + } + + if (pending.length === size) { + chunk = this.pending.shift(); + this.total -= chunk.length; + return chunk; + } + + chunk = new Buffer(size); + off = 0; + len = 0; + + while (off < chunk.length) { + pending = this.pending[0]; + len = pending.copy(chunk, off); + if (len === pending.length) + this.pending.shift(); + else + this.pending[0] = pending.slice(len); + off += len; + } + + assert.equal(off, chunk.length); + + this.total -= chunk.length; + + return chunk; +}; + /** * Parse a ciphertext payload chunk. * Potentially emits a `packet` event. @@ -350,7 +386,7 @@ BIP151Stream.prototype.parse = function parse(data) { this.decrypt(payload); this.sequence(); - p = bcoin.reader(payload, true); + p = bcoin.reader(payload); while (p.left()) { try { diff --git a/lib/bcoin/workers.js b/lib/bcoin/workers.js index 14b68a62..5ac1f028 100644 --- a/lib/bcoin/workers.js +++ b/lib/bcoin/workers.js @@ -948,52 +948,61 @@ function Parser() { utils.inherits(Parser, EventEmitter); Parser.prototype.feed = function feed(data) { - var chunk, off, len; + var chunk; this.total += data.length; this.pending.push(data); while (this.total >= this.waiting) { - if (this.waiting === 0) { - this.parse(new Buffer(0)); - continue; - } - - if (this.pending[0].length > this.waiting) { - chunk = this.pending[0].slice(0, this.waiting); - this.pending[0] = this.pending[0].slice(this.waiting); - this.total -= chunk.length; - this.parse(chunk); - continue; - } - - if (this.pending[0].length === this.waiting) { - chunk = this.pending.shift(); - this.total -= chunk.length; - this.parse(chunk); - continue; - } - - chunk = new Buffer(this.waiting); - off = 0; - len = 0; - - while (off < chunk.length) { - len = this.pending[0].copy(chunk, off); - if (len === this.pending[0].length) - this.pending.shift(); - else - this.pending[0] = this.pending[0].slice(len); - off += len; - } - - assert.equal(off, chunk.length); - - this.total -= chunk.length; + chunk = this.read(this.waiting); this.parse(chunk); } }; +Parser.prototype.read = function read(size) { + var pending, chunk, off, len; + + assert(this.total >= size, 'Reading too much.'); + + if (size === 0) + return new Buffer(0); + + pending = this.pending[0]; + + if (pending.length > size) { + chunk = pending.slice(0, size); + this.pending[0] = pending.slice(size); + this.total -= chunk.length; + return chunk; + } + + if (pending.length === size) { + chunk = this.pending.shift(); + this.total -= chunk.length; + return chunk; + } + + chunk = new Buffer(size); + off = 0; + len = 0; + + while (off < chunk.length) { + pending = this.pending[0]; + len = pending.copy(chunk, off); + if (len === pending.length) + this.pending.shift(); + else + this.pending[0] = pending.slice(len); + off += len; + } + + assert.equal(off, chunk.length); + + this.total -= chunk.length; + + return chunk; +}; + Parser.prototype.parse = function parse(data) { var packet;