Bitfields encoding/decoding
This commit is contained in:
parent
f356a070cc
commit
e6d4e4c029
|
@ -33,8 +33,8 @@ API documentation is available [here](https://bitchan.github.io/bitmessage/docs/
|
|||
- [ ] net_addr
|
||||
- [ ] encrypted
|
||||
- [x] message encodings
|
||||
- [ ] service features
|
||||
- [ ] pubkey features
|
||||
- [x] service features
|
||||
- [x] pubkey features
|
||||
- [ ] Message types
|
||||
- [ ] version
|
||||
- [ ] verack
|
||||
|
|
|
@ -251,18 +251,84 @@ exports.var_int_list = {
|
|||
},
|
||||
};
|
||||
|
||||
exports.messageEncodings = Object.create(var_int);
|
||||
Object.assign(exports.messageEncodings, {
|
||||
/**
|
||||
* Message encodings. Extends {@link var_int} by adding known encoding type
|
||||
* constants.
|
||||
* @see {@link https://bitmessage.org/wiki/Protocol_specification#Message_Encodings}
|
||||
*/
|
||||
exports.messageEncodings = Object.assign(Object.create(var_int), {
|
||||
/**
|
||||
* Any data with this number may be ignored. The sending node might
|
||||
* simply be sharing its public key with you.
|
||||
*/
|
||||
IGNORE: 0,
|
||||
/**
|
||||
* UTF-8. No 'Subject' or 'Body' sections. Useful for simple strings
|
||||
* of data, like URIs or magnet links.
|
||||
*/
|
||||
TRIVIAL: 1,
|
||||
/**
|
||||
* UTF-8. Uses 'Subject' and 'Body' sections. No MIME is used.
|
||||
*/
|
||||
SIMPLE: 2,
|
||||
});
|
||||
|
||||
exports.serviceFeatures = {
|
||||
NODE_NETWORK: 1,
|
||||
// Creates bitfield class of the specified size.
|
||||
var bitfield = function(size) {
|
||||
var bytesize = size / 8;
|
||||
return {
|
||||
decode: function(buf) {
|
||||
assert(buf.length === bytesize, "Bad buffer size");
|
||||
var features = [];
|
||||
var index;
|
||||
for (var i = 0; i < size; i++) {
|
||||
index = bytesize - Math.floor(i / 8) - 1;
|
||||
if ((buf[index] & (1 << (i % 8))) !== 0) { // jshint ignore:line
|
||||
features.push(i);
|
||||
}
|
||||
}
|
||||
return features;
|
||||
},
|
||||
|
||||
encode: function(features) {
|
||||
var buf = new Buffer(bytesize);
|
||||
buf.fill(0);
|
||||
features.forEach(function(feature) {
|
||||
assert(feature >= 0, "Bad feature");
|
||||
assert(feature <= (size - 1), "Bad feature");
|
||||
var index = bytesize - Math.floor(feature / 8) - 1;
|
||||
buf[index] |= 1 << (feature % 8); // jshint ignore:line
|
||||
});
|
||||
return buf;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
exports.pubkeyFeatures = {
|
||||
/**
|
||||
* Service bitfield features. Implements encoding/decoding for a 8-byte
|
||||
* buffer object.
|
||||
* @see {@link https://bitmessage.org/wiki/Protocol_specification#version}
|
||||
*/
|
||||
exports.serviceFeatures = Object.assign(bitfield(64), {
|
||||
/** This is a normal network node. */
|
||||
NODE_NETWORK: 0,
|
||||
});
|
||||
|
||||
/**
|
||||
* Pubkey bitfield features. Implements encoding/decoding for a 4-byte
|
||||
* buffer object.
|
||||
* @see {@link https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features}
|
||||
*/
|
||||
exports.pubkeyFeatures = Object.assign(bitfield(32), {
|
||||
/**
|
||||
* Receiving node expects that the RIPE hash encoded in their address
|
||||
* preceedes the encrypted message data of msg messages bound for
|
||||
* them.
|
||||
*/
|
||||
INCLUDE_DESTINATION: 30,
|
||||
/**
|
||||
* If true, the receiving node does send acknowledgements (rather than
|
||||
* dropping them).
|
||||
*/
|
||||
DOES_ACK: 31,
|
||||
};
|
||||
});
|
||||
|
|
42
test.js
42
test.js
|
@ -5,10 +5,14 @@ var allTests = typeof window === "undefined" ?
|
|||
|
||||
var bmcrypto = require("./lib/crypto");
|
||||
var bitmessage = require("./lib");
|
||||
var message = bitmessage.structs.message;
|
||||
var var_int = bitmessage.structs.var_int;
|
||||
var var_str = bitmessage.structs.var_str;
|
||||
var var_int_list = bitmessage.structs.var_int_list;
|
||||
var structs = bitmessage.structs;
|
||||
var message = structs.message;
|
||||
var var_int = structs.var_int;
|
||||
var var_str = structs.var_str;
|
||||
var var_int_list = structs.var_int_list;
|
||||
var messageEncodings = structs.messageEncodings;
|
||||
var serviceFeatures = structs.serviceFeatures;
|
||||
var pubkeyFeatures = structs.pubkeyFeatures;
|
||||
var WIF = bitmessage.WIF;
|
||||
var Address = bitmessage.Address;
|
||||
|
||||
|
@ -166,6 +170,36 @@ describe("Common structures", function() {
|
|||
expect(var_int_list.encode([1, 1024, 1125899906842624, 40000, 100000]).toString("hex")).to.equal("0501fd0400ff0004000000000000fd9c40fe000186a0");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Message encodings", function() {
|
||||
it("should decode", function() {
|
||||
expect(messageEncodings.decode(Buffer([2])).value).to.equal(messageEncodings.SIMPLE);
|
||||
});
|
||||
|
||||
it("should encode", function() {
|
||||
expect(messageEncodings.encode(messageEncodings.SIMPLE).toString("hex")).to.equal("02");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Service features", function() {
|
||||
it("should decode", function() {
|
||||
expect(serviceFeatures.decode(Buffer("0000000000000001", "hex"))).to.have.members([serviceFeatures.NODE_NETWORK]);
|
||||
});
|
||||
|
||||
it("should encode", function() {
|
||||
expect(serviceFeatures.encode([serviceFeatures.NODE_NETWORK]).toString("hex")).to.equal("0000000000000001");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Pubkey features", function() {
|
||||
it("should decode", function() {
|
||||
expect(pubkeyFeatures.decode(Buffer("c0000000", "hex"))).to.have.members([pubkeyFeatures.DOES_ACK, pubkeyFeatures.INCLUDE_DESTINATION]);
|
||||
});
|
||||
|
||||
it("should encode", function() {
|
||||
expect(pubkeyFeatures.encode([pubkeyFeatures.INCLUDE_DESTINATION, pubkeyFeatures.DOES_ACK]).toString("hex")).to.equal("c0000000");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("WIF", function() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user