diff --git a/src/js/ripple/serializedobject.js b/src/js/ripple/serializedobject.js index 11cad35e..a5599aeb 100644 --- a/src/js/ripple/serializedobject.js +++ b/src/js/ripple/serializedobject.js @@ -1,14 +1,14 @@ -var binformat = require('./binformat'), - sjcl = require('../../../build/sjcl'), - extend = require('extend'), - stypes = require('./serializedtypes'); +var binformat = require('./binformat'); +var sjcl = require('../../../build/sjcl'); +var extend = require('extend'); +var stypes = require('./serializedtypes'); var UInt256 = require('./uint256').UInt256; var SerializedObject = function (buf) { if (Array.isArray(buf) || (Buffer && Buffer.isBuffer(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)); } else if (!buf) { this.buffer = []; @@ -19,30 +19,32 @@ var SerializedObject = function (buf) { }; SerializedObject.from_json = function (obj) { - var typedef; var so = new SerializedObject(); + var typedef; // Create a copy of the object so we don't modify it obj = extend({}, obj); - if ("number" === typeof obj.TransactionType) { - obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType); - - if (!obj.TransactionType) { - throw new Error("Transaction type ID is invalid."); + switch (typeof obj.TransactionType) { + case 'number': + obj.TransactionType = SerializedObject.lookup_type_tx(obj.TransactionType); + if (!obj.TransactionType) { + throw new Error("Transaction type ID is invalid."); + } + break; + case 'string': + typedef = binformat.tx[obj.TransactionType].slice(); + obj.TransactionType = typedef.shift(); + break; + default: + if (typeof obj.LedgerEntryType !== 'undefined') { + // XXX: TODO + throw new Error("Ledger entry binary format not yet implemented."); + } else { + throw new Error("Object to be serialized must contain either " + "TransactionType or LedgerEntryType."); } } - if ("string" === typeof obj.TransactionType) { - typedef = binformat.tx[obj.TransactionType].slice(); - - obj.TransactionType = typedef.shift(); - } else if ("undefined" !== typeof obj.LedgerEntryType) { - // XXX: TODO - throw new Error("Ledger entry binary format not yet implemented."); - } else throw new Error("Object to be serialized must contain either " + - "TransactionType or LedgerEntryType."); - so.serialize(typedef, obj); return so; @@ -57,26 +59,26 @@ SerializedObject.prototype.resetPointer = function () { this.pointer = 0; }; - -var readOrPeek = function (advance) { +function readOrPeek(advance) { return function(numberOfBytes) { - var start = this.pointer; - var end = start+numberOfBytes; - if (end > this.buffer.length) { - throw new Error("There aren't that many bytes left."); - } else { - var result = this.buffer.slice(start,end); - if (advance) {this.pointer = end;} - return result; - } - } -} + var start = this.pointer; + var end = start + numberOfBytes; + if (end > this.buffer.length) { + throw new Error("There aren't that many bytes left."); + } else { + var result = this.buffer.slice(start, end); + if (advance) { + this.pointer = end; + } + return result; + } + } +}; + SerializedObject.prototype.read = readOrPeek(true); SerializedObject.prototype.peek = readOrPeek(false); - -SerializedObject.prototype.to_bits = function () -{ +SerializedObject.prototype.to_bits = function () { return sjcl.codec.bytes.toBits(this.buffer); }; @@ -84,211 +86,196 @@ 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" + 0: "Payment", + 3: "AccountSet", + 5: "SetRegularKey", + 7: "OfferCreate", + 8: "OfferCancel", + 9: "Contract", + 10: "RemoveContract", + 20: "TrustSet", + 100: "EnableFeature", + 101: "SetFee" }; var LEDGER_ENTRY_TYPES = { - 97:"AccountRoot", - 99:"Contract", - 100:"DirectoryNode", - 102:"Features", - 103:"GeneratorMap", - 104:"LedgerHashes", - 110:"Nickname", - 111:"Offer", - 114:"RippleState", - 115:"FeeSettings" + 97: "AccountRoot", + 99: "Contract", + 100: "DirectoryNode", + 102: "Features", + 103: "GeneratorMap", + 104: "LedgerHashes", + 110: "Nickname", + 111: "Offer", + 114: "RippleState", + 115: "FeeSettings" }; var TRANSACTION_RESULTS = { - 0 :"tesSUCCESS", - 100:"tecCLAIM", - 101:"tecPATH_PARTIAL", - 102:"tecUNFUNDED_ADD", - 103:"tecUNFUNDED_OFFER", - 104:"tecUNFUNDED_PAYMENT", - 105:"tecFAILED_PROCESSING", - 121:"tecDIR_FULL", - 122:"tecINSUF_RESERVE_LINE", - 123:"tecINSUF_RESERVE_OFFER", - 124:"tecNO_DST", - 125:"tecNO_DST_INSUF_XRP", - 126:"tecNO_LINE_INSUF_RESERVE", - 127:"tecNO_LINE_REDUNDANT", - 128:"tecPATH_DRY", - 129:"tecUNFUNDED", // Deprecated, old ambiguous unfunded. - 130:"tecMASTER_DISABLED", - 131:"tecNO_REGULAR_KEY", - 132:"tecOWNERS" + 0 : "tesSUCCESS", + 100: "tecCLAIM", + 101: "tecPATH_PARTIAL", + 102: "tecUNFUNDED_ADD", + 103: "tecUNFUNDED_OFFER", + 104: "tecUNFUNDED_PAYMENT", + 105: "tecFAILED_PROCESSING", + 121: "tecDIR_FULL", + 122: "tecINSUF_RESERVE_LINE", + 123: "tecINSUF_RESERVE_OFFER", + 124: "tecNO_DST", + 125: "tecNO_DST_INSUF_XRP", + 126: "tecNO_LINE_INSUF_RESERVE", + 127: "tecNO_LINE_REDUNDANT", + 128: "tecPATH_DRY", + 129: "tecUNFUNDED", // Deprecated, old ambiguous unfunded. + 130: "tecMASTER_DISABLED", + 131: "tecNO_REGULAR_KEY", + 132: "tecOWNERS" }; - - - - 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); - 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; - return output; -} + var old_pointer = this.pointer; + this.resetPointer(); + var output = { }; -function jsonify_structure(thing,field_name) { - var output; - var typeof_thing = typeof thing; - if ("number" === typeof thing) { //Special codes - if (field_name) { - if (field_name === "LedgerEntryType") { - output = LEDGER_ENTRY_TYPES[thing] || thing; - } else if (field_name === "TransactionResult") { - output = TRANSACTION_RESULTS[thing] || thing; - } else if (field_name === "TransactionType") { - output = TRANSACTION_TYPES[thing] || thing; - } else { - output = thing; - } - } else { - output = thing; - } - } else if ("object" === typeof thing && - "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.push(jsonify_structure(thing[i])); - } - } else if ("object" === typeof thing) { - //console.log("here1", thing); - //iterate over object {} - output = {}; - var keys = Object.keys(thing); - for (var i=0; i 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; + 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); + } else { + buffer[0] += field_id & 0xf; + } return buffer; }; function sort_field_compare(a, b) { // Sort by type id first, then by field id - return a[3].id !== b[3].id ? - a[3].id - b[3].id : - a[2] - b[2]; + return a[3].id !== b[3].id ? a[3].id - b[3].id : a[2] - b[2]; }; + SerializedObject._sort_typedef = function (typedef) { return typedef.sort(sort_field_compare); }; SerializedObject.lookup_type_tx = function (id) { - for (var i in binformat.tx) { - if (!binformat.tx.hasOwnProperty(i)) continue; + var keys = Object.keys(binformat.tx); + var result = null; - if (binformat.tx[i][0] === id) { - return i; + for (var i=0; i