mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-28 08:05:51 +00:00
SerializedObject to_json method, and a simple test for that. Tests are still preliminary, and refactoring is still necessary.
This commit is contained in:
@@ -97,6 +97,95 @@ SerializedObject.prototype.to_hex = function () {
|
||||
return sjcl.codec.hex.fromBits(this.to_bits()).toUpperCase();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
var TRANSACTION_TYPES = {
|
||||
0:"Payment",
|
||||
3:"AccountSet",
|
||||
5:"SetRegularKey",
|
||||
7:"OfferCreate",
|
||||
8:"OfferCancel",
|
||||
9:"Contract",
|
||||
10:"RemoveContract",
|
||||
20:"TrustSet",
|
||||
100:"EnableFeature",
|
||||
101:"SetFee"
|
||||
};
|
||||
|
||||
SerializedObject.prototype.to_json = function() {
|
||||
var old_pointer = this.pointer;
|
||||
this.resetPointer();
|
||||
var output = "{";
|
||||
while (true) {
|
||||
var key_and_value = stypes.parse_whatever(this);
|
||||
var key = key_and_value[0];
|
||||
var value = key_and_value[1];
|
||||
output += ("\"" + key + "\":" + jsonify_structure(value,key));
|
||||
output += ",";
|
||||
if (this.pointer == this.buffer.length) {
|
||||
break;
|
||||
} else if (this.pointer > this.buffer.length) {
|
||||
console.log("WARNING: Buffer length exceeded during SerializedObject.to_json");
|
||||
break;
|
||||
}
|
||||
}
|
||||
output = output.slice(0,-1);
|
||||
output += "}";
|
||||
this.pointer = old_pointer;
|
||||
output = JSON.parse(output);
|
||||
return output;
|
||||
}
|
||||
|
||||
function jsonify_structure(thing,field_name) {
|
||||
var output;
|
||||
var typeof_thing = typeof thing;
|
||||
if (typeof_thing === "number") { //Special codes
|
||||
if (field_name) {
|
||||
if (field_name === "LedgerEntryType") {
|
||||
output = thing; //TODO: Do we have special codes for LedgerEntryType?
|
||||
} else if (field_name === "TransactionType") {
|
||||
output = "\""+TRANSACTION_TYPES[thing]+"\"" || thing;
|
||||
} else {
|
||||
output = thing;
|
||||
}
|
||||
} else {
|
||||
output = thing;
|
||||
}
|
||||
} else if (typeof_thing === "boolean") {
|
||||
output = thing;
|
||||
} else if (typeof_thing === "string") {
|
||||
output = "\"" + thing + "\"";
|
||||
} else if ( "function" === typeof thing.to_json ) {
|
||||
output = "\"" + thing.to_json() + "\"";
|
||||
} else if (Array.isArray(thing)) {
|
||||
//console.log("here2");
|
||||
//iterate over array []
|
||||
output = "[";
|
||||
for (var i=0; i< thing.length; i++) {
|
||||
output += jsonify_structure(thing[i]);
|
||||
output += ",";
|
||||
}
|
||||
output = output.slice(0,-1);
|
||||
output += "]";
|
||||
} else {
|
||||
//console.log("here1", thing);
|
||||
//iterate over object {}
|
||||
output = "{";
|
||||
var keys = Object.keys(thing);
|
||||
//console.log(keys);
|
||||
for (var i=0; i<keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var value = thing[key]
|
||||
output += "\""+ key + "\":" + jsonify_structure(value);
|
||||
output += ","
|
||||
}
|
||||
output = output.slice(0,-1);
|
||||
output += "}";
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
SerializedObject.prototype.serialize = function (typedef, obj)
|
||||
{
|
||||
// Ensure canonical order
|
||||
@@ -184,4 +273,5 @@ SerializedObject.lookup_type_tx = function (id) {
|
||||
return null;
|
||||
};
|
||||
|
||||
|
||||
exports.SerializedObject = SerializedObject;
|
||||
|
||||
@@ -43,7 +43,7 @@ function serialize_hex(so, hexData, noLength) {
|
||||
* parses bytes as hex
|
||||
*/
|
||||
function convert_bytes_to_hex (byte_array) {
|
||||
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(byte_array));
|
||||
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(byte_array)).toUpperCase();
|
||||
}
|
||||
|
||||
SerializedType.serialize_varint = function (so, val) {
|
||||
@@ -83,6 +83,10 @@ SerializedType.prototype.parse_varint = function (so) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// In the following, we assume that the inputs are in the proper range. Is this correct?
|
||||
|
||||
// Helper functions for 1-, 2-, and 4-byte integers.
|
||||
@@ -374,7 +378,7 @@ var STAccount = exports.Account = new SerializedType({
|
||||
},
|
||||
parse: function (so) {
|
||||
var len = this.parse_varint(so);
|
||||
console.log("KKKKKKKKKKK",len);
|
||||
//console.log("KKKKKKKKKKK",len);
|
||||
if (len !== 20) {
|
||||
throw new Error("Non-standard-length account ID");
|
||||
}
|
||||
@@ -529,25 +533,26 @@ function serialize_whatever(so, field_name, value) {
|
||||
|
||||
//What should this helper function be attached to?
|
||||
//Take the serialized object, figure out what type/field it is, and return the parsing of that.
|
||||
function parse_whatever(so) {
|
||||
var parse_whatever = exports.parse_whatever = function(so) {
|
||||
var tag_byte = so.read(1)[0];
|
||||
var type_bits = tag_byte >> 4;
|
||||
var field_bits = tag_byte & 0x0f;
|
||||
var type;
|
||||
var field_name;
|
||||
if (type_bits === 0) {
|
||||
type = TYPES_MAP[so.read(1)[0]];
|
||||
} else {
|
||||
type = TYPES_MAP[type_bits];
|
||||
type_bits = so.read(1)[0];
|
||||
}
|
||||
type = TYPES_MAP[type_bits];
|
||||
if ("undefined" === typeof type) {
|
||||
throw Error("Unknown type");
|
||||
} else {
|
||||
if (field_bits === 0) {
|
||||
field_name = FIELDS_MAP[type_bits][so.read(1)[0]];
|
||||
} else {
|
||||
//console.log("!!!!!!!!!!IJOIOJIOJO", type_bits, field_bits);
|
||||
field_name = FIELDS_MAP[type_bits][field_bits];
|
||||
}
|
||||
//console.log("PARSING WHATEVER!!!!", type_bits, type, field_name);
|
||||
if ("undefined" === typeof field_name) {
|
||||
throw Error("Unknown field");
|
||||
} else {
|
||||
@@ -587,13 +592,16 @@ var STObject = exports.Object = new SerializedType({
|
||||
STInt8.serialize(so, 0xe1); //Object ending marker
|
||||
},
|
||||
parse: function (so) {
|
||||
//console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", so.buffer, so.pointer);
|
||||
var output = {};
|
||||
while (true) {
|
||||
if (so.peek(1)[0] === 0xe1) { //ending marker
|
||||
break;
|
||||
} else {
|
||||
//console.log("WTF M8");
|
||||
var key_and_value = parse_whatever(so);
|
||||
output[key_and_value[0]] = key_and_value[1];
|
||||
//console.log("BBBBBBBBBBBBB", key_and_value, output);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
@@ -722,4 +730,3 @@ for (var key1 in FIELDS_MAP) {
|
||||
INVERSE_FIELDS_MAP[FIELDS_MAP[key1][key2]] = [key1, key2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -217,7 +217,6 @@ UInt.prototype.to_hex = function () {
|
||||
return null;
|
||||
|
||||
var bytes = this.to_bytes();
|
||||
|
||||
return sjcl.codec.hex.fromBits(sjcl.codec.bytes.toBits(bytes)).toUpperCase();
|
||||
};
|
||||
|
||||
|
||||
47
test/serializedobject-test.js
Normal file
47
test/serializedobject-test.js
Normal file
@@ -0,0 +1,47 @@
|
||||
var buster = require("buster");
|
||||
|
||||
var SerializedObject = require("../src/js/ripple/serializedobject").SerializedObject;
|
||||
//var types = require("../src/js/ripple/serializedtypes");
|
||||
|
||||
var jsbn = require('../src/js/ripple/jsbn');
|
||||
var BigInteger = jsbn.BigInteger;
|
||||
|
||||
try {
|
||||
var conf = require('./config');
|
||||
} catch(exception) {
|
||||
var conf = require('./config-example');
|
||||
}
|
||||
|
||||
var config = require('../src/js/ripple/config').load(conf);
|
||||
|
||||
buster.testCase("Serialized objects", {
|
||||
"SerializedObject" : {
|
||||
"From json and back" : function () {
|
||||
var input_json = {
|
||||
"Account":"r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS",
|
||||
"Amount":"274579388",
|
||||
"Destination":"r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS",
|
||||
"Fee":"15",
|
||||
"Flags":0,
|
||||
"Paths":[[{"account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV","currency":"USD","issuer":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV"},{"currency":"XRP"}]],
|
||||
"SendMax":{"currency":"USD","issuer":"r4qLSAzv4LZ9TLsR7diphGwKnSEAMQTSjS","value":"2.74579388"},
|
||||
"Sequence":351,
|
||||
"SigningPubKey":"02854B06CE8F3E65323F89260E9E19B33DA3E01B30EA4CA172612DE77973FAC58A",
|
||||
"TransactionType":"Payment",
|
||||
"TxnSignature":"30450221009DA3A42DD25E3B22EC45AD8BA8FC7A954264264A816D300B2DF69F814D7D4DD2022072C9627F97EEC6DA13DE841E06E2CD985EF06A0FBB15DDBF0800D0730C8986BF"
|
||||
}
|
||||
so = SerializedObject.from_json(input_json);
|
||||
var output_json = so.to_json();
|
||||
//console.log(input_json);
|
||||
assert.equals(input_json,output_json);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
@@ -14,7 +14,7 @@ try {
|
||||
|
||||
var config = require('../src/js/ripple/config').load(conf);
|
||||
|
||||
buster.testCase("Serialized types", { /*
|
||||
buster.testCase("Serialized types", {
|
||||
"Int8" : {
|
||||
"Serialize 0" : function () {
|
||||
var so = new SerializedObject();
|
||||
@@ -433,8 +433,8 @@ buster.testCase("Serialized types", { /*
|
||||
var so = new SerializedObject("94838D7EA4C680000000000000000000000000005553440000000000B5F762798A53D543A014CAF8B297CFF8F2F937E8");
|
||||
assert.equals(types.Amount.parse(so).to_text_full(), "-1/USD/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh");
|
||||
},
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
|
||||
"PathSet" : {
|
||||
"Serialize single empty path [[]]" : function () {
|
||||
@@ -445,7 +445,6 @@ buster.testCase("Serialized types", { /*
|
||||
|
||||
"Serialize [[e],[e,e]]" : function () {
|
||||
var so = new SerializedObject();
|
||||
//types.PathSet.serialize(so, [[{account:123, currency:"USD", issuer:789}],[{account:123, currency:"BTC", issuer:789},{account:987, currency:"EUR", issuer:321}]]);
|
||||
types.PathSet.serialize(so, [[{account:123, currency:"USD", issuer:789}],[{account:123, currency:"BTC", issuer:789},{account:987, currency:"EUR", issuer:321}]]);
|
||||
assert.equals(so.to_hex(), "31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF31000000000000000000000000000000000000007B000000000000000000000000425443000000000000000000000000000000000000000000000003153100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100"); //TODO: Check this independently
|
||||
},
|
||||
@@ -458,9 +457,7 @@ buster.testCase("Serialized types", { /*
|
||||
|
||||
"Parse [[e],[e,e]]" : function () {
|
||||
var so = new SerializedObject("31000000000000000000000000000000000000007B00000000000000000000000055534400000000000000000000000000000000000000000000000315FF31000000000000000000000000000000000000007B000000000000000000000000425443000000000000000000000000000000000000000000000003153100000000000000000000000000000000000003DB0000000000000000000000004555520000000000000000000000000000000000000000000000014100");
|
||||
//console.log("AAAA!",types.PathSet);
|
||||
parsed_path=types.PathSet.parse(so);
|
||||
//console.log(parsed_path);
|
||||
assert.equals(parsed_path,[[{account:{_value:123}, currency:{_value:"USD"}, issuer:{_value:789}}],[{account:{_value:123}, currency:{_value:"BTC"}, issuer:{_value:789}},{account:{_value:987}, currency:{_value:"EUR"}, issuer:{_value:321}}]]);
|
||||
}
|
||||
|
||||
@@ -481,22 +478,41 @@ buster.testCase("Serialized types", { /*
|
||||
var so = new SerializedObject();
|
||||
types.Object.serialize(so, {"TakerPays":"87654321.12345678/EUR/rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh", "TakerGets":"213", "Fee":789});
|
||||
assert.equals(so.to_hex(), "64D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E86540000000000000D5684000000000000315E1");
|
||||
//console.log("!!!!!!!!!!!!!!!!!!",so.to_hex());
|
||||
//TODO: Check independently.
|
||||
},
|
||||
"Parse same object" : function () {
|
||||
var so = new SerializedObject("64D65F241D335BF24E0000000000000000000000004555520000000000B5F762798A53D543A014CAF8B297CFF8F2F937E86540000000000000D5684000000000000315E1");
|
||||
var parsed_object=types.Object.parse(so);
|
||||
refute.equals(parsed_object,{"TakerPays":{_value:123}, "TakerGets":{_value:456}, "Fee":{_value:789}});
|
||||
assert.equals(parsed_object,
|
||||
{ TakerPays:
|
||||
{ _value: { '0': 56357454, '1': 32653779, t: 2, s: 0 },
|
||||
_offset: -8,
|
||||
_is_native: false,
|
||||
_is_negative: false,
|
||||
_currency: { _value: 'EUR' },
|
||||
_issuer: { _value: -422657445385694440895149034202122766475892017176 } },
|
||||
TakerGets:
|
||||
{ _value: { '0': 213, '1': 0, '2': 0, t: 1, s: 0 },
|
||||
_offset: 0,
|
||||
_is_native: true,
|
||||
_is_negative: false,
|
||||
_currency: { _value: NaN },
|
||||
_issuer: { _value: NaN } },
|
||||
Fee:
|
||||
{ _value: { '0': 789, '1': 0, '2': 0, t: 1, s: 0 },
|
||||
_offset: 0,
|
||||
_is_native: true,
|
||||
_is_negative: false,
|
||||
_currency: { _value: NaN },
|
||||
_issuer: { _value: NaN } } }
|
||||
);
|
||||
//TODO: Check independently.
|
||||
console.log("LEFT OFF HERE!!!!!!!!!!!!!!!!!!!!!!!!!!!! MAKE THIS WORK!!!!!!!!!!");
|
||||
console.log(parsed_object);
|
||||
},
|
||||
|
||||
'Serialize simple object {"DestinationTag":123, "QualityIn":456, "QualityOut":789}' : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Object.serialize(so, {"DestinationTag":123, "QualityIn":456, "QualityOut":789});
|
||||
//console.log("what?", so.to_hex());
|
||||
//console.log("DOES THE JSON METHOD WORK?", so.to_json());
|
||||
assert.equals(so.to_hex(), "2E0000007B2014000001C8201500000315E1");
|
||||
//TODO: Check independently.
|
||||
},
|
||||
@@ -505,11 +521,11 @@ buster.testCase("Serialized types", { /*
|
||||
var parsed_object=types.Object.parse(so);
|
||||
assert.equals(parsed_object,{"DestinationTag":123, "QualityIn":456, "QualityOut":789});
|
||||
//TODO: Check independently.
|
||||
},
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
"Array" : {/*
|
||||
"Array" : {
|
||||
"Serialize empty array []" : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Array.serialize(so, []);
|
||||
@@ -519,36 +535,35 @@ buster.testCase("Serialized types", { /*
|
||||
var so = new SerializedObject("F1");
|
||||
var parsed_object=types.Array.parse(so);
|
||||
assert.equals(parsed_object,[]);
|
||||
},*/
|
||||
},
|
||||
'Serialize 3-length array [{"TakerPays":123}, {"TakerGets":456}, {"Fee":789}]' : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Array.serialize(so, [{"TakerPays":123}, {"TakerGets":456}, {"Fee":789}]);
|
||||
//TODO: Check this manually
|
||||
|
||||
assert.equals(so.to_hex(), "64400000000000007B6540000000000001C8684000000000000315F1");
|
||||
},
|
||||
"Parse the same array" : function () {
|
||||
var so = new SerializedObject("64400000000000007B6540000000000001C8684000000000000315F1");
|
||||
var parsed_object=types.Array.parse(so);
|
||||
//console.log("WE GOT:", parsed_object[0].TakerPays._value, parsed_object[1].TakerGets._value, parsed_object[2].Fee._value);
|
||||
console.log("WE GOT BACK 1:", parsed_object);
|
||||
assert.equals([123,456,789],[parsed_object[0].TakerPays._value, parsed_object[1].TakerGets._value, parsed_object[2].Fee._value]);
|
||||
},
|
||||
'Serialize 3-length array [{"DestinationTag":123}, {"QualityIn":456}, {"Fee":789}]' : function () {
|
||||
var so = new SerializedObject();
|
||||
types.Array.serialize(so, [{"DestinationTag":123}, {"QualityIn":456}, {"Fee":789}]);
|
||||
//TODO: Check this manually
|
||||
console.log("WE GOT!!:",so.to_hex());
|
||||
//console.log("DOES THE JSON METHOD WORK2?", so.to_json());
|
||||
assert.equals(so.to_hex(), "2E0000007B2014000001C8684000000000000315F1");
|
||||
},
|
||||
"Parse the same array 2" : function () {
|
||||
var so = new SerializedObject("2E0000007B2014000001C8684000000000000315F1");
|
||||
var parsed_object=types.Array.parse(so);
|
||||
console.log("WE GOT BACK 2:", parsed_object);
|
||||
//TODO: Is this correct? Return some things as integers, and others as objects?
|
||||
assert.equals([123,456,789],[parsed_object[0].DestinationTag, parsed_object[1].QualityIn, parsed_object[2].Fee._value]);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user