From b4f59762426f50a349277623f1b83a8b0beaca03 Mon Sep 17 00:00:00 2001 From: Daniel Huigens Date: Tue, 8 May 2018 20:16:16 +0200 Subject: [PATCH] Writing partial lengths --- src/packet/packet.js | 14 +++++++++++++- src/packet/packetlist.js | 27 +++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/packet/packet.js b/src/packet/packet.js index ac7b6521..5561b360 100644 --- a/src/packet/packet.js +++ b/src/packet/packet.js @@ -68,6 +68,18 @@ export default { return util.concatUint8Array([new Uint8Array([255]), util.writeNumber(length, 4)]); }, + writePartialLength: function(power) { + if (power < 0 || power > 30) { + throw new Error('Partial Length power must be between 1 and 30'); + } + return new Uint8Array([224 + power]); + }, + + writeTag: function(tag_type) { + /* we're only generating v4 packet headers here */ + return new Uint8Array([0xC0 | tag_type]); + }, + /** * Writes a packet header version 4 with the given tag_type and length to a * string @@ -78,7 +90,7 @@ export default { */ writeHeader: function(tag_type, length) { /* we're only generating v4 packet headers here */ - return util.concatUint8Array([new Uint8Array([0xC0 | tag_type]), this.writeSimpleLength(length)]); + return util.concatUint8Array([this.writeTag(tag_type), this.writeSimpleLength(length)]); }, /** diff --git a/src/packet/packetlist.js b/src/packet/packetlist.js index 60123ffd..80ce760d 100644 --- a/src/packet/packetlist.js +++ b/src/packet/packetlist.js @@ -72,8 +72,31 @@ List.prototype.write = function () { for (let i = 0; i < this.length; i++) { const packetbytes = this[i].write(); - arr.push(packetParser.writeHeader(this[i].tag, packetbytes.length)); - arr.push(packetbytes); + if (util.isStream(packetbytes)) { + let buffer = []; + let bufferLength = 0; + const minLength = 512; + arr.push(packetParser.writeTag(this[i].tag)); + arr.push(packetbytes.transform((done, value) => { + if (!done) { + buffer.push(value); + bufferLength += value.length; + if (bufferLength >= minLength) { + const powerOf2 = Math.min(Math.log(bufferLength) / Math.LN2 | 0, 30); + const chunkSize = 2 ** powerOf2; + const bufferConcat = util.concatUint8Array([packetParser.writePartialLength(powerOf2)].concat(buffer)); + buffer = [bufferConcat.subarray(1 + chunkSize)]; + bufferLength = buffer[0].length; + return bufferConcat.subarray(0, 1 + chunkSize); + } + } else { + return util.concatUint8Array([packetParser.writeSimpleLength(bufferLength)].concat(buffer)); + } + })); + } else { + arr.push(packetParser.writeHeader(this[i].tag, packetbytes.length)); + arr.push(packetbytes); + } } return util.concatUint8Array(arr);