849 lines
19 KiB
JavaScript
849 lines
19 KiB
JavaScript
/**
|
|
* framer.js - packet framer for bcoin
|
|
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
|
* https://github.com/indutny/bcoin
|
|
*/
|
|
|
|
var bcoin = require('../../bcoin');
|
|
var network = require('./network');
|
|
var constants = require('./constants');
|
|
var bn = require('bn.js');
|
|
var utils = bcoin.utils;
|
|
var assert = utils.assert;
|
|
|
|
/**
|
|
* Framer
|
|
*/
|
|
|
|
function Framer(options) {
|
|
if (!(this instanceof Framer))
|
|
return new Framer(options);
|
|
|
|
options = options || {};
|
|
|
|
this.options = options;
|
|
|
|
this.agent = new Buffer(options.userAgent || constants.userAgent, 'ascii');
|
|
}
|
|
|
|
Framer.prototype.header = function header(cmd, payload) {
|
|
var h = new Buffer(24);
|
|
var len, i;
|
|
|
|
cmd = new Buffer(cmd, 'ascii');
|
|
|
|
assert(cmd.length < 12);
|
|
assert(payload.length <= 0xffffffff);
|
|
|
|
// Magic value
|
|
utils.writeU32(h, network.magic, 0);
|
|
|
|
// Command
|
|
len = utils.copy(cmd, h, 4);
|
|
for (i = 4 + len; i < 4 + 12; i++)
|
|
h[i] = 0;
|
|
|
|
// Payload length
|
|
utils.writeU32(h, payload.length, 16);
|
|
|
|
// Checksum
|
|
utils.copy(utils.checksum(payload), h, 20);
|
|
|
|
return h;
|
|
};
|
|
|
|
Framer.prototype.packet = function packet(cmd, payload) {
|
|
var h = this.header(cmd, payload);
|
|
return Buffer.concat([h, payload]);
|
|
};
|
|
|
|
Framer.prototype.version = function version(options) {
|
|
if (!options)
|
|
options = {};
|
|
|
|
options.agent = this.agent;
|
|
|
|
return this.packet('version', Framer.version(options));
|
|
};
|
|
|
|
Framer.prototype.verack = function verack() {
|
|
return this.packet('verack', Framer.verack());
|
|
};
|
|
|
|
Framer.prototype.inv = function inv(items) {
|
|
return this.packet('inv', Framer.inv(items));
|
|
};
|
|
|
|
Framer.prototype.getData = function getData(items) {
|
|
return this.packet('getdata', Framer.getData(items));
|
|
};
|
|
|
|
Framer.prototype.notFound = function notFound(items) {
|
|
return this.packet('notfound', Framer.notFound(items));
|
|
};
|
|
|
|
Framer.prototype.ping = function ping(data) {
|
|
return this.packet('ping', Framer.ping(data));
|
|
};
|
|
|
|
Framer.prototype.pong = function pong(data) {
|
|
return this.packet('pong', Framer.pong(data));
|
|
};
|
|
|
|
Framer.prototype.filterLoad = function filterLoad(bloom, update) {
|
|
return this.packet('filterload', Framer.filterLoad(bloom, update));
|
|
};
|
|
|
|
Framer.prototype.filterClear = function filterClear() {
|
|
return this.packet('filterclear', Framer.filterClear());
|
|
};
|
|
|
|
Framer.prototype.getHeaders = function getHeaders(hashes, stop) {
|
|
return this.packet('getheaders', Framer.getHeaders(hashes, stop));
|
|
};
|
|
|
|
Framer.prototype.getBlocks = function getBlocks(hashes, stop) {
|
|
return this.packet('getblocks', Framer.getBlocks(hashes, stop));
|
|
};
|
|
|
|
Framer.prototype.utxo =
|
|
Framer.prototype.coin = function _coin(coin) {
|
|
return this.packet('utxo', Framer.coin(coin, false));
|
|
};
|
|
|
|
Framer.prototype.tx = function tx(tx) {
|
|
return this.packet('tx', Framer.tx(tx));
|
|
};
|
|
|
|
Framer.prototype.witnessTX = function witnessTX(tx) {
|
|
return this.packet('tx', Framer.witnessTX(tx));
|
|
};
|
|
|
|
Framer.prototype.block = function _block(block) {
|
|
return this.packet('block', Framer.block(block));
|
|
};
|
|
|
|
Framer.prototype.witnessBlock = function witnessBlock(block) {
|
|
return this.packet('block', Framer.witnessBlock(block));
|
|
};
|
|
|
|
Framer.prototype.merkleBlock = function merkleBlock(block) {
|
|
return this.packet('merkleblock', Framer.merkleBlock(block));
|
|
};
|
|
|
|
Framer.prototype.headers = function headers(block) {
|
|
return this.packet('headers', Framer.headers(block));
|
|
};
|
|
|
|
Framer.prototype.reject = function reject(details) {
|
|
return this.packet('reject', Framer.reject(details));
|
|
};
|
|
|
|
Framer.prototype.addr = function addr(peers) {
|
|
return this.packet('addr', Framer.addr(peers));
|
|
};
|
|
|
|
Framer.prototype.mempool = function mempool() {
|
|
return this.packet('mempool', Framer.mempool());
|
|
};
|
|
|
|
Framer.address = function address(data, full, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
if (!data)
|
|
data = {};
|
|
|
|
if (!data.ts)
|
|
data.ts = utils.now() - (process.uptime() | 0);
|
|
|
|
if (!data.services)
|
|
data.services = 0;
|
|
|
|
if (!data.ipv4)
|
|
data.ipv4 = new Buffer([]);
|
|
|
|
if (!data.port)
|
|
data.port = network.port;
|
|
|
|
if (full)
|
|
p.writeU32(data.ts);
|
|
|
|
p.writeU64(data.services);
|
|
|
|
if (data.ipv6) {
|
|
data.ipv6 = utils.ip2array(data.ipv6, 6);
|
|
p.writeBytes(data.ipv6);
|
|
} else {
|
|
data.ipv4 = utils.ip2array(data.ipv4, 4);
|
|
// We don't have an ipv6, convert ipv4 to ipv4-mapped ipv6 address
|
|
p.writeU32BE(0x00000000);
|
|
p.writeU32BE(0x00000000);
|
|
p.writeU32BE(0x0000ffff);
|
|
p.writeBytes(data.ipv4);
|
|
}
|
|
|
|
p.writeU16BE(data.port);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.version = function version(options, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var i, remote, local;
|
|
|
|
if (!options.agent)
|
|
options.agent = new Buffer(constants.userAgent, 'ascii');
|
|
|
|
if (!options)
|
|
options = {};
|
|
|
|
if (!options.remote)
|
|
options.remote = {};
|
|
|
|
if (!options.local)
|
|
options.local = {};
|
|
|
|
if (options.local.services == null)
|
|
options.local.services = constants.bcoinServices;
|
|
|
|
p.writeU32(constants.version);
|
|
p.writeU64(constants.bcoinServices);
|
|
p.write64(utils.now());
|
|
Framer.address(options.remote, false, p);
|
|
Framer.address(options.local, false, p);
|
|
p.writeU64(utils.nonce());
|
|
p.writeVarString(options.agent);
|
|
p.writeU32(options.height || 0);
|
|
p.writeU8(options.relay ? 1 : 0);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.verack = function verack() {
|
|
return new Buffer([]);
|
|
};
|
|
|
|
Framer._inv = function _inv(items, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var i, hash;
|
|
var off = 0;
|
|
|
|
assert(items.length <= 50000);
|
|
|
|
p.writeIntv(items.length);
|
|
|
|
for (i = 0; i < items.length; i++) {
|
|
p.writeU32(constants.inv[items[i].type]);
|
|
p.writeHash(items[i].hash);
|
|
}
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.inv = function inv(items, writer) {
|
|
return Framer._inv(items, writer);
|
|
};
|
|
|
|
Framer.getData = function getData(items, writer) {
|
|
return Framer._inv(items, writer);
|
|
};
|
|
|
|
Framer.notFound = function notFound(items, writer) {
|
|
return Framer._inv(items, writer);
|
|
};
|
|
|
|
Framer.ping = function ping(data) {
|
|
var p = new Buffer(8);
|
|
utils.writeU64(p, data.nonce, 0);
|
|
return p;
|
|
};
|
|
|
|
Framer.pong = function pong(data) {
|
|
var p = new Buffer(8);
|
|
utils.writeU64(p, data.nonce, 0);
|
|
return p;
|
|
};
|
|
|
|
Framer.filterLoad = function filterLoad(bloom, update, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
p.writeVarBytes(bloom.toBuffer());
|
|
p.writeU32(bloom.n);
|
|
p.writeU32(bloom.tweak);
|
|
p.writeU8(constants.filterFlags[update]);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.filterClear = function filterClear() {
|
|
return new Buffer([]);
|
|
};
|
|
|
|
Framer.getHeaders = function getHeaders(hashes, stop, writer) {
|
|
// NOTE: getheaders can have a null hash
|
|
if (!hashes)
|
|
hashes = [];
|
|
|
|
return Framer._getBlocks(hashes, stop, writer);
|
|
};
|
|
|
|
Framer.getBlocks = function getBlocks(hashes, stop, writer) {
|
|
return Framer._getBlocks(hashes, stop, writer);
|
|
};
|
|
|
|
Framer._getBlocks = function _getBlocks(hashes, stop, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var i;
|
|
|
|
p.writeU32(constants.version);
|
|
p.writeIntv(hashes.length);
|
|
|
|
for (i = 0; i < hashes.length; i++)
|
|
p.writeHash(hashes[i]);
|
|
|
|
p.writeHash(stop || constants.zeroHash);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.binput = function _input(input) {
|
|
var off = 0;
|
|
var script, p;
|
|
|
|
script = input.script.encode();
|
|
p = new Buffer(32 + 4 + utils.sizeIntv(script.length) + script.length + 4);
|
|
|
|
off += utils.copy(new Buffer(input.prevout.hash, 'hex'), p, off);
|
|
off += utils.writeU32(p, input.prevout.index, off);
|
|
|
|
off += utils.writeIntv(p, script.length, off);
|
|
off += utils.copy(script, p, off);
|
|
|
|
off += utils.writeU32(p, input.sequence, off);
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.boutput = function _output(output) {
|
|
var off = 0;
|
|
var script, p;
|
|
|
|
script = output.script.encode();
|
|
p = new Buffer(8 + utils.sizeIntv(script.length) + script.length);
|
|
|
|
off += utils.write64(p, output.value, off);
|
|
assert(output.value.byteLength() <= 8);
|
|
|
|
off += utils.writeIntv(p, script.length, off);
|
|
off += utils.copy(script, p, off);
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.utxo =
|
|
Framer.coin = function _coin(coin, extended, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var height = coin.height;
|
|
|
|
if (height === -1)
|
|
height = 0x7fffffff;
|
|
|
|
assert(coin.value.byteLength() <= 8);
|
|
|
|
p.writeU32(coin.version);
|
|
p.writeU32(height);
|
|
p.write64(coin.value);
|
|
p.writeVarBytes(coin.script.encode());
|
|
|
|
if (extended) {
|
|
p.writeHash(coin.hash);
|
|
p.writeU32(coin.index);
|
|
p.writeU8(coin.spent ? 1 : 0);
|
|
}
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.btx = function _tx(tx) {
|
|
var inputs = [];
|
|
var outputs = [];
|
|
var inputSize = 0;
|
|
var outputSize = 0;
|
|
var off = 0;
|
|
var p, i, input, output;
|
|
|
|
for (i = 0; i < tx.inputs.length; i++) {
|
|
input = Framer.binput(tx.inputs[i]);
|
|
inputs.push(input);
|
|
inputSize += input.length;
|
|
}
|
|
|
|
for (i = 0; i < tx.outputs.length; i++) {
|
|
output = Framer.boutput(tx.outputs[i]);
|
|
outputs.push(output);
|
|
outputSize += output.length;
|
|
}
|
|
|
|
p = new Buffer(4
|
|
+ utils.sizeIntv(tx.inputs.length) + inputSize
|
|
+ utils.sizeIntv(tx.outputs.length) + outputSize
|
|
+ 4);
|
|
|
|
off += utils.write32(p, tx.version, off);
|
|
|
|
off += utils.writeIntv(p, tx.inputs.length, off);
|
|
for (i = 0; i < inputs.length; i++) {
|
|
input = inputs[i];
|
|
off += utils.copy(input, p, off);
|
|
}
|
|
|
|
off += utils.writeIntv(p, tx.outputs.length, off);
|
|
for (i = 0; i < outputs.length; i++) {
|
|
output = outputs[i];
|
|
off += utils.copy(output, p, off);
|
|
}
|
|
|
|
off += utils.writeU32(p, tx.locktime, off);
|
|
|
|
p._witnessSize = 0;
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.tx = function _tx(tx, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
p.write32(tx.version);
|
|
|
|
p.writeUIntv(tx.inputs.length);
|
|
for (i = 0; i < tx.inputs.length; i++)
|
|
Framer.input(tx.inputs[i], p);
|
|
|
|
p.writeUIntv(tx.outputs.length);
|
|
for (i = 0; i < tx.outputs.length; i++)
|
|
Framer.output(tx.outputs[i], p);
|
|
|
|
p.writeU32(tx.locktime);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
p._witnessSize = 0;
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.input = function _input(input, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
p.writeHash(input.prevout.hash);
|
|
p.writeU32(input.prevout.index);
|
|
p.writeVarBytes(input.script.encode());
|
|
p.writeU32(input.sequence);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.output = function _output(output, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
assert(output.value.byteLength() <= 8);
|
|
|
|
p.write64(output.value);
|
|
p.writeVarBytes(output.script.encode());
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.witnessTX = function _witnessTX(tx, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var witnessSize = 0;
|
|
|
|
p.write32(tx.version);
|
|
p.writeU8(0);
|
|
p.writeU8(tx.flag || 1);
|
|
|
|
p.writeUIntv(tx.inputs.length);
|
|
|
|
for (i = 0; i < tx.inputs.length; i++)
|
|
Framer.input(tx.inputs[i], p);
|
|
|
|
p.writeUIntv(tx.outputs.length);
|
|
|
|
for (i = 0; i < tx.outputs.length; i++)
|
|
Framer.output(tx.outputs[i], p);
|
|
|
|
for (i = 0; i < tx.inputs.length; i++) {
|
|
var start = p.written;
|
|
Framer.witness(tx.inputs[i].witness, p);
|
|
witnessSize += p.written - start;
|
|
}
|
|
|
|
p.writeU32(tx.locktime);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
p._witnessSize = witnessSize + 2;
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.witnessBlockSize = function witnessBlockSize(block) {
|
|
return Framer.witnessBlock(block, new BufferWriter())._witnessSize;
|
|
};
|
|
|
|
Framer.witnessTXSize = function witnessTXSize(tx) {
|
|
return Framer.witnessTXSize(block, new BufferWriter())._witnessSize;
|
|
};
|
|
|
|
Framer.witness = function _witness(witness, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
p.writeUIntv(witness.items.length);
|
|
|
|
for (i = 0; i < witness.items.length; i++)
|
|
p.writeVarBytes(witness.items[i]);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.block = function _block(block, writer) {
|
|
return Framer._block(block, false, writer);
|
|
};
|
|
|
|
Framer.witnessBlock = function _witnessBlock(block, writer) {
|
|
return Framer._block(block, true, writer);
|
|
};
|
|
|
|
Framer.renderTX = function renderTX(tx, useWitness, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
if (tx._raw) {
|
|
if (!useWitness && bcoin.protocol.parser.isWitnessTX(tx._raw)) {
|
|
Framer.tx(tx, p);
|
|
witnessSize = p._witnessSize;
|
|
} else {
|
|
p.writeBytes(tx._raw);
|
|
witnessSize = tx._witnessSize;
|
|
}
|
|
} else {
|
|
if (useWitness && bcoin.tx.prototype.hasWitness.call(tx))
|
|
Framer.witnessTX(tx, p);
|
|
else
|
|
Framer.tx(tx, p);
|
|
witnessSize = p._witnessSize;
|
|
}
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
p._witnessSize = witnessSize;
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer._block = function _block(block, useWitness, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var witnessSize = 0;
|
|
var i, tx;
|
|
|
|
p.write32(block.version);
|
|
p.writeHash(block.prevBlock);
|
|
p.writeHash(block.merkleRoot);
|
|
p.writeU32(block.ts);
|
|
p.writeU32(block.bits);
|
|
p.writeU32(block.nonce);
|
|
p.writeIntv(block.txs.length);
|
|
|
|
for (i = 0; i < block.txs.length; i++) {
|
|
Framer.renderTX(block.txs[i], useWitness, p);
|
|
witnessSize += p._witnessSize;
|
|
}
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
p._witnessSize = witnessSize;
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.merkleBlock = function _merkleBlock(block, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
p.write32(block.version);
|
|
p.writeHash(block.prevBlock);
|
|
p.writeHash(block.merkleRoot);
|
|
p.writeU32(block.ts);
|
|
p.writeU32(block.bits);
|
|
p.writeU32(block.nonce);
|
|
p.writeU32(block.totalTX);
|
|
|
|
p.writeIntv(block.hashes.length);
|
|
|
|
for (i = 0; i < block.hashes.length; i++)
|
|
p.writeHash(block.hashes[i]);
|
|
|
|
p.writeVarBytes(block.flags);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.headers = function _headers(block, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var i;
|
|
|
|
p.write32(block.version);
|
|
p.writeHash(block.prevBlock);
|
|
p.writeHash(block.merkleRoot);
|
|
p.writeU32(block.ts);
|
|
p.writeU32(block.bits);
|
|
p.writeU32(block.nonce);
|
|
p.writeIntv(block.totalTX);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.reject = function reject(details, writer) {
|
|
var p = new BufferWriter(writer);
|
|
|
|
p.writeVarString(details.message || '', 'ascii');
|
|
p.writeU8(ccode, off);
|
|
p.writeVarString(details.reason || '', 'ascii');
|
|
if (details.data)
|
|
p.writeBytes(details.data);
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.addr = function addr(peers, writer) {
|
|
var p = new BufferWriter(writer);
|
|
var i, peer;
|
|
|
|
p.writeIntv(peers.length);
|
|
|
|
for (i = 0; i < peers.length; i++) {
|
|
peer = peers[i];
|
|
Framer.address({
|
|
ts: peer.ts,
|
|
services: peer.services,
|
|
ipv6: peer.ipv6,
|
|
ipv4: peer.ipv4,
|
|
port: peer.port
|
|
}, true, p);
|
|
}
|
|
|
|
if (!writer)
|
|
p = p.render();
|
|
|
|
return p;
|
|
};
|
|
|
|
Framer.mempool = function mempool() {
|
|
return new Buffer([]);
|
|
};
|
|
|
|
function BufferWriter(options) {
|
|
if (options instanceof BufferWriter)
|
|
return options;
|
|
|
|
if (!(this instanceof BufferWriter))
|
|
return new BufferWriter(options);
|
|
|
|
this.data = [];
|
|
this.written = 0;
|
|
}
|
|
|
|
BufferWriter.prototype.render = function render() {
|
|
var data = new Buffer(this.written);
|
|
var off = 0;
|
|
var i;
|
|
|
|
for (i = 0; i < this.data.length; i++) {
|
|
item = this.data[i];
|
|
switch (item[0]) {
|
|
case 'u8': off += utils.writeU8(data, item[1], off); break;
|
|
case 'u16': off += utils.writeU16(data, item[1], off); break;
|
|
case 'u16be': off += utils.writeU16BE(data, item[1], off); break;
|
|
case 'u32': off += utils.writeU32(data, item[1], off); break;
|
|
case 'u32be': off += utils.writeU32BE(data, item[1], off); break;
|
|
case 'u64': off += utils.writeU64(data, item[1], off); break;
|
|
case 'u64be': off += utils.writeU64BE(data, item[1], off); break;
|
|
case '8': off += utils.write8(data, item[1], off); break;
|
|
case '16': off += utils.write16(data, item[1], off); break;
|
|
case '16be': off += utils.write16BE(data, item[1], off); break;
|
|
case '32': off += utils.write32(data, item[1], off); break;
|
|
case '32be': off += utils.write32BE(data, item[1], off); break;
|
|
case '64': off += utils.write64(data, item[1], off); break;
|
|
case '64be': off += utils.write64BE(data, item[1], off); break;
|
|
case 'varint': off += utils.writeIntv(data, item[1], off); break;
|
|
case 'bytes': off += utils.copy(item[1], data, off); break;
|
|
}
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
BufferWriter.prototype.writeU8 = function writeU8(value) {
|
|
this.written += 1;
|
|
this.data.push(['u8', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeU16 = function writeU16(value) {
|
|
this.written += 2;
|
|
this.data.push(['u16', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeU16BE = function writeU16BE(value) {
|
|
this.written += 2;
|
|
this.data.push(['u16be', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeU32 = function writeU32(value) {
|
|
this.written += 4;
|
|
this.data.push(['u32', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeU32BE = function writeU32BE(value) {
|
|
this.written += 4;
|
|
this.data.push(['u32be', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeU64 = function writeU64(value) {
|
|
this.written += 8;
|
|
this.data.push(['u64', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeU64BE = function writeU64BE(value) {
|
|
this.written += 8;
|
|
this.data.push(['u64be', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.write8 = function write8(value) {
|
|
this.written += 1;
|
|
this.data.push(['8', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.write16 = function write16(value) {
|
|
this.written += 2;
|
|
this.data.push(['16', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.write16BE = function write16BE(value) {
|
|
this.written += 2;
|
|
this.data.push(['16be', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.write32 = function write32(value) {
|
|
this.written += 4;
|
|
this.data.push(['32', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.write32BE = function write32BE(value) {
|
|
this.written += 4;
|
|
this.data.push(['32be', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.write64 = function write64(value) {
|
|
this.written += 8;
|
|
this.data.push(['64', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.write64BE = function write64BE(value) {
|
|
this.written += 8;
|
|
this.data.push(['64be', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeBytes = function writeBytes(value) {
|
|
this.written += value.length;
|
|
this.data.push(['bytes', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.getSize = function getSize() {
|
|
return this.written;
|
|
};
|
|
|
|
BufferWriter.prototype.writeString = function writeString(value, enc) {
|
|
if (typeof value === 'string')
|
|
value = new Buffer(value, enc);
|
|
this.writeBytes(value);
|
|
};
|
|
|
|
BufferWriter.prototype.writeHash = function writeHash(value) {
|
|
if (typeof value === 'string')
|
|
value = new Buffer(value, 'hex');
|
|
this.writeBytes(value);
|
|
};
|
|
|
|
BufferWriter.prototype.writeVarString = function writeVarString(value, enc) {
|
|
if (typeof value === 'string')
|
|
value = new Buffer(value, enc);
|
|
this.writeVarBytes(value);
|
|
};
|
|
|
|
BufferWriter.prototype.writeVarBytes = function writeVarBytes(value) {
|
|
this.written += utils.sizeIntv(value.length);
|
|
this.written += value.length;
|
|
this.data.push(['varint', value.length]);
|
|
this.data.push(['bytes', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeNullString = function writeNullString(value, enc) {
|
|
this.writeString(value, enc);
|
|
this.writeU8(0);
|
|
};
|
|
|
|
BufferWriter.prototype.writeIntv = function writeIntv(value) {
|
|
this.written += utils.sizeIntv(value);
|
|
this.data.push(['varint', value]);
|
|
};
|
|
|
|
BufferWriter.prototype.writeUIntv = function writeUIntv(value) {
|
|
this.written += utils.sizeIntv(value);
|
|
this.data.push(['varint', value]);
|
|
};
|
|
|
|
/**
|
|
* Expose
|
|
*/
|
|
|
|
Framer.BufferWriter = BufferWriter;
|
|
module.exports = Framer;
|