diff --git a/lib/bufferwriter.js b/lib/bufferwriter.js index 2082aed..babbfe9 100644 --- a/lib/bufferwriter.js +++ b/lib/bufferwriter.js @@ -1,3 +1,5 @@ +var BN = require('./bn'); + var BufferWriter = function BufferWriter(bufs) { if (!(this instanceof BufferWriter)) return new BufferReader(buf); @@ -48,21 +50,17 @@ BufferWriter.prototype.writeUInt32LE = function(n) { return this; }; -//TODO: What if n is so large that it loses precision? -BufferWriter.prototype.writeUInt64BE = function(n) { - var buf = new Buffer(8); - buf.writeInt32BE(n & -1, 4); - buf.writeUInt32BE(Math.floor(n / 0x100000000), 0); +BufferWriter.prototype.writeUInt64BEBN = function(bn) { + var buf = bn.toBuffer({size: 8}); this.write(buf); return this; }; //TODO: What if n is so large that it loses precision? -BufferWriter.prototype.writeUInt64LE = function(n) { - var buf = new Buffer(8); - buf.writeInt32LE(n & -1, 0); - buf.writeUInt32LE(Math.floor(n / 0x100000000), 4); - this.write(buf); +BufferWriter.prototype.writeUInt64LEBN = function(bn) { + var buf = bn.toBuffer({size: 8}); + var reversebuf = new Buffer(Array.apply(new Array(), buf).reverse()); + this.write(reversebuf); return this; }; @@ -72,6 +70,12 @@ BufferWriter.prototype.writeVarInt = function(n) { return this; }; +BufferWriter.prototype.writeVarIntBN = function(bn) { + var buf = BufferWriter.varIntBufBN(bn); + this.write(buf); + return this; +}; + //TODO: What if n is so large that it loses precision? BufferWriter.varIntBuf = function(n) { var buf = undefined; @@ -95,4 +99,27 @@ BufferWriter.varIntBuf = function(n) { return buf; }; +BufferWriter.varIntBufBN = function(bn) { + var buf = undefined; + var n = bn.toNumber(); + if (n < 253) { + buf = new Buffer(1); + buf.writeUInt8(n, 0); + } else if (n < 0x10000) { + buf = new Buffer(1 + 2); + buf.writeUInt8(253, 0); + buf.writeUInt16LE(n, 1); + } else if (n < 0x100000000) { + buf = new Buffer(1 + 4); + buf.writeUInt8(254, 0); + buf.writeUInt32LE(n, 1); + } else { + var bw = new BufferWriter(); + bw.writeUInt8(255); + bw.writeUInt64LEBN(bn); + var buf = bw.concat(); + } + return buf; +}; + module.exports = BufferWriter; diff --git a/test/test.bufferwriter.js b/test/test.bufferwriter.js index 05be1f5..70d0305 100644 --- a/test/test.bufferwriter.js +++ b/test/test.bufferwriter.js @@ -1,4 +1,5 @@ var BufferWriter = require('../lib/bufferwriter'); +var BN = require('../lib/bn'); var should = require('chai').should(); describe('BufferWriter', function() { @@ -75,20 +76,20 @@ describe('BufferWriter', function() { }); - describe('#writeUInt64BE', function() { + describe('#writeUInt64BEBN', function() { it('should write 1', function() { var bw = new BufferWriter(); - bw.writeUInt64BE(1).concat().toString('hex').should.equal('0000000000000001'); + bw.writeUInt64BEBN(BN(1)).concat().toString('hex').should.equal('0000000000000001'); }); }); - describe('#writeUInt64LE', function() { + describe('#writeUInt64LEBN', function() { it('should write 1', function() { var bw = new BufferWriter(); - bw.writeUInt64LE(1).concat().toString('hex').should.equal('0100000000000000'); + bw.writeUInt64LEBN(BN(1)).concat().toString('hex').should.equal('0100000000000000'); }); }); @@ -121,4 +122,32 @@ describe('BufferWriter', function() { }); + describe('#writeVarIntBN', function() { + + it('should write a 1 byte varInt', function() { + var bw = new BufferWriter(); + bw.writeVarIntBN(BN(1)); + bw.concat().length.should.equal(1); + }); + + it('should write a 3 byte varInt', function() { + var bw = new BufferWriter(); + bw.writeVarIntBN(BN(1000)); + bw.concat().length.should.equal(3); + }); + + it('should write a 5 byte varInt', function() { + var bw = new BufferWriter(); + bw.writeVarIntBN(BN(Math.pow(2, 16 + 1))); + bw.concat().length.should.equal(5); + }); + + it('should write a 9 byte varInt', function() { + var bw = new BufferWriter(); + bw.writeVarIntBN(BN(Math.pow(2, 32 + 1))); + bw.concat().length.should.equal(9); + }); + + }); + });