From baf5e50016b4333754ecf0cdccd2b0a59f1cb1e8 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 22 Mar 2016 19:25:50 -0700 Subject: [PATCH] recursive worker packet parsing. --- lib/bcoin/workers.js | 133 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 2 deletions(-) diff --git a/lib/bcoin/workers.js b/lib/bcoin/workers.js index 7e1cb926..704cd4b7 100644 --- a/lib/bcoin/workers.js +++ b/lib/bcoin/workers.js @@ -169,7 +169,7 @@ function createPacket(id, name, items) { return p.render(); } -function createBody(name, items) { +function createBody_(name, items) { var p = new BufferWriter(); var i, item; @@ -231,7 +231,7 @@ function createBody(name, items) { return p.render(); } -function parseBody(data) { +function parseBody_(data) { var p = new BufferReader(data, true); var name, count, i; var items = []; @@ -288,6 +288,135 @@ function parseBody(data) { }; } +function createBody(name, items) { + var p = new BufferWriter(); + + if (name) + p.writeVarString(name, 'ascii'); + else + p.writeUIntv(0); + + frameItem(items, p); + + p.writeU8(0x0a); + + return p.render(); +} + +function frameItem(item, p) { + var i, keys; + switch (typeof item) { + case 'string': + p.writeU8(1); + p.writeVarString(item, 'utf8'); + break; + case 'number': + p.writeU8(2); + p.write32(item); + break; + case 'boolean': + p.writeU8(3); + p.writeU8(item ? 1 : 0); + break; + case 'object': + case 'undefined': + if (item == null) { + p.writeU8(0); + } else { + if (item instanceof bcoin.block) { + p.writeU8(40); + p.writeVarBytes(item.render()); + } else if (item instanceof bcoin.tx) { + p.writeU8(41); + p.writeVarBytes(item.toExtended(true)); + } else if (item instanceof bcoin.coin) { + p.writeU8(42); + p.writeVarBytes(item.toExtended()); + } else if (item instanceof bn) { + p.writeU8(43); + p.writeVarBytes(item.toBuffer()); + } else if (Buffer.isBuffer(item)) { + p.writeU8(4); + p.writeVarBytes(item); + } else if (Array.isArray(item)) { + p.writeU8(5); + p.writeUIntv(item.length); + for (i = 0; i < item.length; i++) + frameItem(item[i], p); + } else { + keys = Object.keys(item); + p.writeU8(6); + p.writeUIntv(keys.length); + for (i = 0; i < keys.length; i++) { + p.writeVarString(keys[i], 'utf8'); + frameItem(item[keys[i]], p); + } + } + } + break; + default: + assert(false, 'Bad type: ' + typeof item); + } +} + +function parseBody(data) { + var p = new BufferReader(data, true); + var name, items; + + p.start(); + + name = p.readVarString('ascii'); + items = parseItem(p); + + assert(p.readU8() === 0x0a); + + p.end(); + + return { + name: name || null, + items: items + }; +} + +function parseItem(p) { + var i, count, items; + + switch (p.readU8()) { + case 0: + return null; + case 1: + return p.readVarString('utf8'); + case 2: + return p.read32(); + case 3: + return p.readU8() === 1; + case 4: + return p.readVarBytes(); + case 5: + items = []; + count = p.readUIntv(); + for (i = 0; i < count; i++) + items.push(parseItem(p)); + return items; + case 6: + count = p.readUIntv(); + items = {}; + for (i = 0; i < count; i++) + items[p.readVarString('utf8')] = parseItem(p); + return items; + case 40: + return bcoin.block.fromRaw(p.readVarBytes()); + case 41: + return bcoin.tx.fromExtended(p.readVarBytes(), true); + case 42: + return bcoin.coin.fromExtended(p.readVarBytes()); + case 43: + return new bn(p.readVarBytes()); + default: + assert(false, 'Bad type.'); + } +} + function parseHeader(data) { return { magic: utils.readU32(data, 0),