Implement var_int_list
This commit is contained in:
parent
1b950bb872
commit
a3c4ebac7d
19
README.md
19
README.md
|
@ -35,23 +35,11 @@ With the help of browserify `bitmessage` provides different implementations for
|
||||||
- [ ] HMAC-SHA-256
|
- [ ] HMAC-SHA-256
|
||||||
- [ ] Core structures
|
- [ ] Core structures
|
||||||
- [x] var_int
|
- [x] var_int
|
||||||
- [x] encode
|
- [x] var_str
|
||||||
- [x] decode
|
- [x] var_int_list
|
||||||
- [ ] var_str
|
|
||||||
- [ ] encode
|
|
||||||
- [ ] decode
|
|
||||||
- [ ] var_int_list
|
|
||||||
- [ ] encode
|
|
||||||
- [ ] decode
|
|
||||||
- [ ] inv_vect
|
- [ ] inv_vect
|
||||||
- [ ] encode
|
|
||||||
- [ ] decode
|
|
||||||
- [ ] net_addr
|
- [ ] net_addr
|
||||||
- [ ] encode
|
|
||||||
- [ ] decode
|
|
||||||
- [ ] bitfield
|
- [ ] bitfield
|
||||||
- [ ] encode
|
|
||||||
- [ ] decode
|
|
||||||
- [ ] High-level objects
|
- [ ] High-level objects
|
||||||
- [ ] Address
|
- [ ] Address
|
||||||
- [x] encode
|
- [x] encode
|
||||||
|
@ -63,8 +51,7 @@ With the help of browserify `bitmessage` provides different implementations for
|
||||||
- [ ] encode
|
- [ ] encode
|
||||||
- [ ] decode
|
- [ ] decode
|
||||||
- [x] WIF
|
- [x] WIF
|
||||||
- [x] encode
|
- [ ] POW
|
||||||
- [x] decode
|
|
||||||
- [ ] Parse PyBitmessage configs
|
- [ ] Parse PyBitmessage configs
|
||||||
- [ ] decode keys.dat
|
- [ ] decode keys.dat
|
||||||
- [ ] decode knownnodes.dat
|
- [ ] decode knownnodes.dat
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
* platform and [node-int64](https://www.npmjs.com/package/node-int64)
|
* platform and [node-int64](https://www.npmjs.com/package/node-int64)
|
||||||
* for Browser. You may replace it with other library with the same API.
|
* for Browser. You may replace it with other library with the same API.
|
||||||
*/
|
*/
|
||||||
|
// TODO(Kagami): Find another JS implementation, it should be able to
|
||||||
|
// operate with `uint64_t` not just store it.
|
||||||
exports.Int64 = require("int64-native");
|
exports.Int64 = require("int64-native");
|
||||||
/** Working with addresses. */
|
/** Working with addresses. */
|
||||||
exports.Address = require("./address");
|
exports.Address = require("./address");
|
||||||
|
|
|
@ -35,6 +35,8 @@ var var_int = exports.var_int = {
|
||||||
length = 5;
|
length = 5;
|
||||||
break;
|
break;
|
||||||
case 255:
|
case 255:
|
||||||
|
// TODO(Kagami): Should we still use native number if value is
|
||||||
|
// less than 2^53?
|
||||||
var hi = buf.readUInt32BE(1);
|
var hi = buf.readUInt32BE(1);
|
||||||
assert(hi !== 0, "Impractical var_int");
|
assert(hi !== 0, "Impractical var_int");
|
||||||
var lo = buf.readUInt32BE(5);
|
var lo = buf.readUInt32BE(5);
|
||||||
|
@ -120,6 +122,8 @@ exports.var_str = {
|
||||||
decode: function(buf) {
|
decode: function(buf) {
|
||||||
var decoded = var_int.decode(buf);
|
var decoded = var_int.decode(buf);
|
||||||
var strLength = decoded.value;
|
var strLength = decoded.value;
|
||||||
|
// FIXME(Kagami): We will fail here if var_int value is bigger than
|
||||||
|
// 2^32. Though it will require ~4G of RAM so it's not that bad.
|
||||||
// XXX(Kagami): Spec doesn't mention encoding, using UTF-8.
|
// XXX(Kagami): Spec doesn't mention encoding, using UTF-8.
|
||||||
var str = decoded.rest.slice(0, strLength).toString();
|
var str = decoded.rest.slice(0, strLength).toString();
|
||||||
var rest = decoded.rest.slice(strLength);
|
var rest = decoded.rest.slice(strLength);
|
||||||
|
@ -137,3 +141,43 @@ exports.var_str = {
|
||||||
return Buffer.concat([var_int.encode(strBuf.length), strBuf]);
|
return Buffer.concat([var_int.encode(strBuf.length), strBuf]);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* var_int_list.
|
||||||
|
* @see {@link https://bitmessage.org/wiki/Protocol_specification#Variable_length_list_of_integers}
|
||||||
|
*/
|
||||||
|
exports.var_int_list = {
|
||||||
|
/**
|
||||||
|
* Decode var_int_list.
|
||||||
|
* @param {Buffer} buf - Buffer that starts with encoded var_int_list
|
||||||
|
* @return {{list: number[], length: number, rest: Buffer}}
|
||||||
|
* Decoded var_int_list structure.
|
||||||
|
*/
|
||||||
|
decode: function(buf) {
|
||||||
|
var decoded = var_int.decode(buf);
|
||||||
|
var listLength = decoded.value;
|
||||||
|
// FIXME(Kagami): We will fail here if var_int value is bigger than
|
||||||
|
// 2^32. Though such list would require more than 4G of RAM so it's
|
||||||
|
// not that bad.
|
||||||
|
var list = new Array(listLength);
|
||||||
|
var rest = decoded.rest;
|
||||||
|
var sumLength = decoded.length;
|
||||||
|
for (var i = 0; i < listLength; i++) {
|
||||||
|
decoded = var_int.decode(rest);
|
||||||
|
list[i] = decoded.value;
|
||||||
|
rest = decoded.rest;
|
||||||
|
sumLength += decoded.length;
|
||||||
|
}
|
||||||
|
return {list: list, length: sumLength, rest: rest}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode list of numbers into var_int_list.
|
||||||
|
* @param {number[]} list - A number list
|
||||||
|
* @return {Buffer} Encoded var_int_list.
|
||||||
|
*/
|
||||||
|
encode: function(list) {
|
||||||
|
var listBuf = Buffer.concat(list.map(var_int.encode));
|
||||||
|
return Buffer.concat([var_int.encode(list.length), listBuf]);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
44
test.js
44
test.js
|
@ -9,6 +9,7 @@ var Address = bitmessage.Address;
|
||||||
var wif = bitmessage.wif;
|
var wif = bitmessage.wif;
|
||||||
var var_int = bitmessage.struct.var_int;
|
var var_int = bitmessage.struct.var_int;
|
||||||
var var_str = bitmessage.struct.var_str;
|
var var_str = bitmessage.struct.var_str;
|
||||||
|
var var_int_list = bitmessage.struct.var_int_list;
|
||||||
var bmcrypto = require("./lib/crypto");
|
var bmcrypto = require("./lib/crypto");
|
||||||
|
|
||||||
describe("Core structures", function() {
|
describe("Core structures", function() {
|
||||||
|
@ -61,15 +62,20 @@ describe("Core structures", function() {
|
||||||
describe("var_str", function() {
|
describe("var_str", function() {
|
||||||
it("should decode", function() {
|
it("should decode", function() {
|
||||||
var res;
|
var res;
|
||||||
|
res = var_str.decode(Buffer("00", "hex"));
|
||||||
|
expect(res.str).to.equal("");
|
||||||
|
expect(res.length).to.equal(1);
|
||||||
|
expect(res.rest.toString("hex")).to.equal("");
|
||||||
|
|
||||||
res = var_str.decode(Buffer("0474657374", "hex"));
|
res = var_str.decode(Buffer("0474657374", "hex"));
|
||||||
expect(res.str).to.equal("test");
|
expect(res.str).to.equal("test");
|
||||||
expect(res.length).to.equal(5);
|
expect(res.length).to.equal(5);
|
||||||
expect(res.rest.toString("hex")).to.equal("");
|
expect(res.rest.toString("hex")).to.equal("");
|
||||||
|
|
||||||
res = var_str.decode(Buffer("00", "hex"));
|
res = var_str.decode(Buffer("0474657374ffffff", "hex"));
|
||||||
expect(res.str).to.equal("");
|
expect(res.str).to.equal("test");
|
||||||
expect(res.length).to.equal(1);
|
expect(res.length).to.equal(5);
|
||||||
expect(res.rest.toString("hex")).to.equal("");
|
expect(res.rest.toString("hex")).to.equal("ffffff");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should encode", function() {
|
it("should encode", function() {
|
||||||
|
@ -77,6 +83,36 @@ describe("Core structures", function() {
|
||||||
expect(var_str.encode("").toString("hex")).to.equal("00");
|
expect(var_str.encode("").toString("hex")).to.equal("00");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("var_int_list", function() {
|
||||||
|
it("should decode", function() {
|
||||||
|
var res;
|
||||||
|
res = var_int_list.decode(Buffer("00", "hex"));
|
||||||
|
expect(res.list).to.deep.equal([]);
|
||||||
|
expect(res.length).to.equal(1);
|
||||||
|
expect(res.rest.toString("hex")).to.equal("");
|
||||||
|
|
||||||
|
res = var_int_list.decode(Buffer("0501fd0400ff0004000000000000fd9c40fe000186a0", "hex"));
|
||||||
|
expect(res.length).to.equal(22);
|
||||||
|
expect(res.list.length).to.equal(5);
|
||||||
|
expect(res.list[0]).to.equal(1);
|
||||||
|
expect(res.list[1]).to.equal(1024);
|
||||||
|
expect(res.list[2] == 1125899906842624).to.be.true;
|
||||||
|
expect(res.list[3]).to.equal(40000);
|
||||||
|
expect(res.list[4]).to.equal(100000);
|
||||||
|
expect(res.rest.toString("hex")).to.equal("");
|
||||||
|
|
||||||
|
res = var_int_list.decode(Buffer("0501fd0400ff0004000000000000fd9c40fe000186a0ffffff", "hex"));
|
||||||
|
expect(res.length).to.equal(22);
|
||||||
|
expect(res.list.length).to.equal(5);
|
||||||
|
expect(res.rest.toString("hex")).to.equal("ffffff");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should encode", function() {
|
||||||
|
expect(var_int_list.encode([]).toString("hex")).to.equal("00");
|
||||||
|
expect(var_int_list.encode([1, 1024, 1125899906842624, 40000, 100000]).toString("hex")).to.equal("0501fd0400ff0004000000000000fd9c40fe000186a0");
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("WIF", function() {
|
describe("WIF", function() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user