mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-12-02 01:55:48 +00:00
Cleanup
This commit is contained in:
@@ -1,14 +1,14 @@
|
|||||||
var binformat = require('./binformat'),
|
var binformat = require('./binformat');
|
||||||
sjcl = require('../../../build/sjcl'),
|
var sjcl = require('../../../build/sjcl');
|
||||||
extend = require('extend'),
|
var extend = require('extend');
|
||||||
stypes = require('./serializedtypes');
|
var stypes = require('./serializedtypes');
|
||||||
|
|
||||||
var UInt256 = require('./uint256').UInt256;
|
var UInt256 = require('./uint256').UInt256;
|
||||||
|
|
||||||
var SerializedObject = function (buf) {
|
var SerializedObject = function (buf) {
|
||||||
if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf)) ) {
|
if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(buf)) ) {
|
||||||
this.buffer = buf;
|
this.buffer = buf;
|
||||||
} else if ("string" === typeof buf) {
|
} else if (typeof buf === 'string') {
|
||||||
this.buffer = sjcl.codec.bytes.fromBits(sjcl.codec.hex.toBits(buf));
|
this.buffer = sjcl.codec.bytes.fromBits(sjcl.codec.hex.toBits(buf));
|
||||||
} else if (!buf) {
|
} else if (!buf) {
|
||||||
this.buffer = [];
|
this.buffer = [];
|
||||||
@@ -19,29 +19,31 @@ var SerializedObject = function (buf) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
SerializedObject.from_json = function (obj) {
|
SerializedObject.from_json = function (obj) {
|
||||||
var typedef;
|
|
||||||
var so = new SerializedObject();
|
var so = new SerializedObject();
|
||||||
|
var typedef;
|
||||||
|
|
||||||
// Create a copy of the object so we don't modify it
|
// Create a copy of the object so we don't modify it
|
||||||
obj = extend({}, obj);
|
obj = extend({}, obj);
|
||||||
|
|
||||||
if ("number" === typeof obj.TransactionType) {
|
switch (typeof obj.TransactionType) {
|
||||||
|
case 'number':
|
||||||
obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType);
|
obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType);
|
||||||
|
|
||||||
if (!obj.TransactionType) {
|
if (!obj.TransactionType) {
|
||||||
throw new Error("Transaction type ID is invalid.");
|
throw new Error("Transaction type ID is invalid.");
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
case 'string':
|
||||||
if ("string" === typeof obj.TransactionType) {
|
|
||||||
typedef = binformat.tx[obj.TransactionType].slice();
|
typedef = binformat.tx[obj.TransactionType].slice();
|
||||||
|
|
||||||
obj.TransactionType = typedef.shift();
|
obj.TransactionType = typedef.shift();
|
||||||
} else if ("undefined" !== typeof obj.LedgerEntryType) {
|
break;
|
||||||
|
default:
|
||||||
|
if (typeof obj.LedgerEntryType !== 'undefined') {
|
||||||
// XXX: TODO
|
// XXX: TODO
|
||||||
throw new Error("Ledger entry binary format not yet implemented.");
|
throw new Error("Ledger entry binary format not yet implemented.");
|
||||||
} else throw new Error("Object to be serialized must contain either " +
|
} else {
|
||||||
"TransactionType or LedgerEntryType.");
|
throw new Error("Object to be serialized must contain either " + "TransactionType or LedgerEntryType.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
so.serialize(typedef, obj);
|
so.serialize(typedef, obj);
|
||||||
|
|
||||||
@@ -57,8 +59,7 @@ SerializedObject.prototype.resetPointer = function () {
|
|||||||
this.pointer = 0;
|
this.pointer = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function readOrPeek(advance) {
|
||||||
var readOrPeek = function (advance) {
|
|
||||||
return function(numberOfBytes) {
|
return function(numberOfBytes) {
|
||||||
var start = this.pointer;
|
var start = this.pointer;
|
||||||
var end = start + numberOfBytes;
|
var end = start + numberOfBytes;
|
||||||
@@ -66,17 +67,18 @@ var readOrPeek = function (advance) {
|
|||||||
throw new Error("There aren't that many bytes left.");
|
throw new Error("There aren't that many bytes left.");
|
||||||
} else {
|
} else {
|
||||||
var result = this.buffer.slice(start, end);
|
var result = this.buffer.slice(start, end);
|
||||||
if (advance) {this.pointer = end;}
|
if (advance) {
|
||||||
|
this.pointer = end;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
SerializedObject.prototype.read = readOrPeek(true);
|
SerializedObject.prototype.read = readOrPeek(true);
|
||||||
SerializedObject.prototype.peek = readOrPeek(false);
|
SerializedObject.prototype.peek = readOrPeek(false);
|
||||||
|
|
||||||
|
SerializedObject.prototype.to_bits = function () {
|
||||||
SerializedObject.prototype.to_bits = function ()
|
|
||||||
{
|
|
||||||
return sjcl.codec.bytes.toBits(this.buffer);
|
return sjcl.codec.bytes.toBits(this.buffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -84,9 +86,6 @@ SerializedObject.prototype.to_hex = function () {
|
|||||||
return sjcl.codec.hex.fromBits(this.to_bits()).toUpperCase();
|
return sjcl.codec.hex.fromBits(this.to_bits()).toUpperCase();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var TRANSACTION_TYPES = {
|
var TRANSACTION_TYPES = {
|
||||||
0: "Payment",
|
0: "Payment",
|
||||||
3: "AccountSet",
|
3: "AccountSet",
|
||||||
@@ -135,76 +134,62 @@ var TRANSACTION_RESULTS = {
|
|||||||
132: "tecOWNERS"
|
132: "tecOWNERS"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SerializedObject.prototype.to_json = function() {
|
SerializedObject.prototype.to_json = function() {
|
||||||
var old_pointer = this.pointer;
|
var old_pointer = this.pointer;
|
||||||
this.resetPointer();
|
this.resetPointer();
|
||||||
var output = { };
|
var output = { };
|
||||||
while (true) {
|
|
||||||
|
while (this.pointer < this.buffer.length) {
|
||||||
var key_and_value = stypes.parse_whatever(this);
|
var key_and_value = stypes.parse_whatever(this);
|
||||||
var key = key_and_value[0];
|
var key = key_and_value[0];
|
||||||
var value = key_and_value[1];
|
var value = key_and_value[1];
|
||||||
output[key] = jsonify_structure(value,key);
|
output[key] = jsonify_structure(value,key);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pointer = old_pointer;
|
this.pointer = old_pointer;
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function jsonify_structure(thing, field_name) {
|
function jsonify_structure(thing, field_name) {
|
||||||
var output;
|
var output;
|
||||||
var typeof_thing = typeof thing;
|
|
||||||
if ("number" === typeof thing) { //Special codes
|
switch (typeof thing) {
|
||||||
if (field_name) {
|
case 'number':
|
||||||
if (field_name === "LedgerEntryType") {
|
switch (field_name) {
|
||||||
|
case 'LedgerEntryType':
|
||||||
output = LEDGER_ENTRY_TYPES[thing] || thing;
|
output = LEDGER_ENTRY_TYPES[thing] || thing;
|
||||||
} else if (field_name === "TransactionResult") {
|
break;
|
||||||
|
case 'TransactionResult':
|
||||||
output = TRANSACTION_RESULTS[thing] || thing;
|
output = TRANSACTION_RESULTS[thing] || thing;
|
||||||
} else if (field_name === "TransactionType") {
|
break;
|
||||||
|
case 'TransactionType':
|
||||||
output = TRANSACTION_TYPES[thing] || thing;
|
output = TRANSACTION_TYPES[thing] || thing;
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
output = thing;
|
output = thing;
|
||||||
}
|
}
|
||||||
} else {
|
break;
|
||||||
output = thing;
|
case 'object':
|
||||||
}
|
if (typeof thing.to_json === 'function') {
|
||||||
} else if ("object" === typeof thing &&
|
|
||||||
"function" === typeof thing.to_json) {
|
|
||||||
output = thing.to_json();
|
output = thing.to_json();
|
||||||
} else if (Array.isArray(thing)) {
|
} else {
|
||||||
//console.log("here2");
|
output = new thing.constructor;
|
||||||
//iterate over array []
|
|
||||||
output = [];
|
|
||||||
for (var i=0; i< thing.length; i++) {
|
|
||||||
output.push(jsonify_structure(thing[i]));
|
|
||||||
}
|
|
||||||
} else if ("object" === typeof thing) {
|
|
||||||
//console.log("here1", thing);
|
|
||||||
//iterate over object {}
|
|
||||||
output = {};
|
|
||||||
var keys = Object.keys(thing);
|
var keys = Object.keys(thing);
|
||||||
for (var i=0; i<keys.length; i++) {
|
for (var i=0; i<keys.length; i++) {
|
||||||
var key = keys[i];
|
var key = keys[i];
|
||||||
var value = thing[key];
|
output[key] = jsonify_structure(thing[key], key);
|
||||||
output[key] = jsonify_structure(value,key);
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
output = thing;
|
output = thing;
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
};
|
||||||
|
|
||||||
SerializedObject.prototype.serialize = function (typedef, obj)
|
SerializedObject.prototype.serialize = function (typedef, obj) {
|
||||||
{
|
|
||||||
// Ensure canonical order
|
// Ensure canonical order
|
||||||
typedef = SerializedObject._sort_typedef(typedef.slice());
|
typedef = SerializedObject._sort_typedef(typedef.slice());
|
||||||
|
|
||||||
@@ -215,35 +200,30 @@ SerializedObject.prototype.serialize = function (typedef, obj)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SerializedObject.prototype.signing_hash = function (prefix)
|
SerializedObject.prototype.signing_hash = function (prefix) {
|
||||||
{
|
|
||||||
var sign_buffer = new SerializedObject();
|
var sign_buffer = new SerializedObject();
|
||||||
stypes.Int32.serialize(sign_buffer, prefix);
|
stypes.Int32.serialize(sign_buffer, prefix);
|
||||||
sign_buffer.append(this.buffer);
|
sign_buffer.append(this.buffer);
|
||||||
return sign_buffer.hash_sha512_half();
|
return sign_buffer.hash_sha512_half();
|
||||||
};
|
};
|
||||||
|
|
||||||
SerializedObject.prototype.hash_sha512_half = function ()
|
SerializedObject.prototype.hash_sha512_half = function () {
|
||||||
{
|
|
||||||
var bits = sjcl.codec.bytes.toBits(this.buffer),
|
var bits = sjcl.codec.bytes.toBits(this.buffer),
|
||||||
hash = sjcl.bitArray.bitSlice(sjcl.hash.sha512.hash(bits), 0, 256);
|
hash = sjcl.bitArray.bitSlice(sjcl.hash.sha512.hash(bits), 0, 256);
|
||||||
|
|
||||||
return UInt256.from_hex(sjcl.codec.hex.fromBits(hash));
|
return UInt256.from_hex(sjcl.codec.hex.fromBits(hash));
|
||||||
};
|
};
|
||||||
|
|
||||||
SerializedObject.prototype.serialize_field = function (spec, obj)
|
SerializedObject.prototype.serialize_field = function (spec, obj) {
|
||||||
{
|
var spec = spec.slice();
|
||||||
spec = spec.slice();
|
var name = spec.shift();
|
||||||
|
var presence = spec.shift();
|
||||||
|
var field_id = spec.shift();
|
||||||
|
var Type = spec.shift();
|
||||||
|
|
||||||
var name = spec.shift(),
|
if (typeof obj[name] !== 'undefined') {
|
||||||
presence = spec.shift(),
|
|
||||||
field_id = spec.shift(),
|
|
||||||
Type = spec.shift();
|
|
||||||
|
|
||||||
if ("undefined" !== typeof obj[name]) {
|
|
||||||
//console.log(name, Type.id, field_id);
|
//console.log(name, Type.id, field_id);
|
||||||
this.append(SerializedObject.get_field_header(Type.id, field_id));
|
this.append(SerializedObject.get_field_header(Type.id, field_id));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Type.serialize(this, obj[name]);
|
Type.serialize(this, obj[name]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -256,39 +236,46 @@ SerializedObject.prototype.serialize_field = function (spec, obj)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SerializedObject.get_field_header = function (type_id, field_id)
|
SerializedObject.get_field_header = function (type_id, field_id) {
|
||||||
{
|
|
||||||
var buffer = [0];
|
var buffer = [0];
|
||||||
if (type_id > 0xf) buffer.push(type_id & 0xff);
|
|
||||||
else buffer[0] += (type_id & 0xf) << 4;
|
|
||||||
|
|
||||||
if (field_id > 0xf) buffer.push(field_id & 0xff);
|
if (type_id > 0xf) {
|
||||||
else buffer[0] += field_id & 0xf;
|
buffer.push(type_id & 0xff);
|
||||||
|
} else {
|
||||||
|
buffer[0] += (type_id & 0xf) << 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (field_id > 0xf) {
|
||||||
|
buffer.push(field_id & 0xff);
|
||||||
|
} else {
|
||||||
|
buffer[0] += field_id & 0xf;
|
||||||
|
}
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
};
|
};
|
||||||
|
|
||||||
function sort_field_compare(a, b) {
|
function sort_field_compare(a, b) {
|
||||||
// Sort by type id first, then by field id
|
// Sort by type id first, then by field id
|
||||||
return a[3].id !== b[3].id ?
|
return a[3].id !== b[3].id ? a[3].id - b[3].id : a[2] - b[2];
|
||||||
a[3].id - b[3].id :
|
|
||||||
a[2] - b[2];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
SerializedObject._sort_typedef = function (typedef) {
|
SerializedObject._sort_typedef = function (typedef) {
|
||||||
return typedef.sort(sort_field_compare);
|
return typedef.sort(sort_field_compare);
|
||||||
};
|
};
|
||||||
|
|
||||||
SerializedObject.lookup_type_tx = function (id) {
|
SerializedObject.lookup_type_tx = function (id) {
|
||||||
for (var i in binformat.tx) {
|
var keys = Object.keys(binformat.tx);
|
||||||
if (!binformat.tx.hasOwnProperty(i)) continue;
|
var result = null;
|
||||||
|
|
||||||
if (binformat.tx[i][0] === id) {
|
for (var i=0; i<keys.length; i++) {
|
||||||
return i;
|
var key = keys[i];
|
||||||
|
if (binformat.tx[key][0] === id) {
|
||||||
|
result = key;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
exports.SerializedObject = SerializedObject;
|
exports.SerializedObject = SerializedObject;
|
||||||
|
|||||||
Reference in New Issue
Block a user