From 6ce83107c8ff5e13b32dbf54fd570b1163fdc5ba Mon Sep 17 00:00:00 2001 From: wltsmrz Date: Mon, 9 Sep 2013 13:05:40 -0700 Subject: [PATCH] Cleanup --- src/js/ripple/serializedtypes.js | 634 ++++++++++++++++--------------- test/serializedtypes-test.js | 2 +- 2 files changed, 332 insertions(+), 304 deletions(-) diff --git a/src/js/ripple/serializedtypes.js b/src/js/ripple/serializedtypes.js index 65735c88..ac0b8b71 100644 --- a/src/js/ripple/serializedtypes.js +++ b/src/js/ripple/serializedtypes.js @@ -6,25 +6,24 @@ * SerializedObject.parse() or SerializedObject.serialize(). */ -var extend = require('extend'), - utils = require('./utils'), - sjcl = require('../../../build/sjcl'); +var extend = require('extend'); +var utils = require('./utils'); +var sjcl = require('../../../build/sjcl'); -var amount = require('./amount'), - UInt128 = require('./uint128').UInt128, - UInt160 = require('./uint160').UInt160, - UInt256 = require('./uint256').UInt256, - Amount = amount.Amount, - Currency= amount.Currency; +var amount = require('./amount'); +var UInt128 = require('./uint128').UInt128; +var UInt160 = require('./uint160').UInt160; +var UInt256 = require('./uint256').UInt256; +var Amount = amount.Amount; +var Currency = amount.Currency; // Shortcuts -var hex = sjcl.codec.hex, - bytes = sjcl.codec.bytes; +var hex = sjcl.codec.hex; +var bytes = sjcl.codec.bytes; var jsbn = require('./jsbn'); var BigInteger = jsbn.BigInteger; - var SerializedType = function (methods) { extend(this, methods); }; @@ -38,7 +37,6 @@ function serialize_hex(so, hexData, noLength) { }; - /** * parses bytes as hex */ @@ -52,41 +50,44 @@ SerializedType.serialize_varint = function (so, val) { } if (val <= 192) { so.append([val]); - } else if (val <= 12,480) { + } else if (val <= 12480) { val -= 193; so.append([193 + (val >>> 8), val & 0xff]); } else if (val <= 918744) { val -= 12481; so.append([ - 241 + (val >>> 16), - val >>> 8 & 0xff, - val & 0xff + 241 + (val >>> 16), + val >>> 8 & 0xff, + val & 0xff ]); - } else throw new Error("Variable integer overflow."); + } else { + throw new Error("Variable integer overflow."); + } }; SerializedType.prototype.parse_varint = function (so) { var b1 = so.read(1)[0], b2, b3; + var result; if (b1 <= 192) { - return b1; + result = b1; } else if (b1 <= 240) { b2 = so.read(1)[0]; - return 193 + (b1-193)*256 + b2; + result = 193 + (b1-193)*256 + b2; } else if (b1 <= 254) { b2 = so.read(1)[0]; b3 = so.read(1)[0]; - return 12481 + (b1-241)*65536 + b2*256 + b3 + result = 12481 + (b1-241)*65536 + b2*256 + b3 } else { throw new Error("Invalid varint length indicator"); } + return result; }; - // 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. @@ -97,7 +98,7 @@ SerializedType.prototype.parse_varint = function (so) { * The result is appended to the serialized object ("so"). */ function append_byte_array(so, val, bytes) { - if ("number" !== typeof val) { + if (isNaN(val) || val === null) { throw new Error("Integer is not a number"); } if (val < 0 || val >= (Math.pow(256, bytes))) { @@ -113,7 +114,7 @@ function append_byte_array(so, val, bytes) { // Convert a certain number of bytes from the serialized object ("so") into an integer. function readAndSum(so, bytes) { var sum = 0; - for (var i = 0; i 16) { throw new Error("Int64 is too large"); } + while (hex.length < 16) { hex = "0" + hex; } + return serialize_hex(so, hex, true); //noLength = true }, parse: function (so) { var hi = readAndSum(so, 4); var lo = readAndSum(so, 4); - - var result = new BigInteger(""+hi); + var result = new BigInteger(String(hi)); result.shiftLeft(32); result.add(lo); return result; @@ -233,14 +237,14 @@ var STHash160 = exports.Hash160 = new SerializedType({ // Internal var STCurrency = new SerializedType({ serialize: function (so, val) { - var currency = val.to_json(); - if ("XRP" === currency) { + var currency = val.to_json().toUpperCase(); + if (currency === 'XRP') { serialize_hex(so, UInt160.HEX_ZERO, true); - } else if ("string" === typeof currency && currency.length === 3) { - var currencyCode = currency.toUpperCase(), - currencyData = utils.arraySet(20, 0); + } else if (typeof currency === 'string'&& currency.length === 3) { + var currencyCode = currency.toUpperCase(); + var currencyData = utils.arraySet(20, 0); - if (!/^[A-Z]{3}$/.test(currencyCode) || currencyCode === "XRP" ) { + if (!/^[A-Z]{3}$/.test(currencyCode)) { throw new Error('Invalid currency code'); } @@ -282,6 +286,7 @@ var STAmount = exports.Amount = new SerializedType({ if (valueHex.length > 16) { throw new Error('Value out of bounds'); } + while (valueHex.length < 16) { valueHex = "0" + valueHex; } @@ -328,15 +333,16 @@ var STAmount = exports.Amount = new SerializedType({ var amount = new Amount(); var value_bytes = so.read(8); var is_zero = !(value_bytes[0] & 0x7f); + for (var i=1; i<8; i++) { is_zero = is_zero && !value_bytes[i]; } + if (value_bytes[0] & 0x80) { //non-native var currency = STCurrency.parse(so); var issuer_bytes = so.read(20); var issuer = UInt160.from_bytes(issuer_bytes); - var offset = ((value_bytes[0] & 0x3f) << 2) + (value_bytes[1] >>> 6) - 97; var mantissa_bytes = value_bytes.slice(1); mantissa_bytes[0] &= 0x3f; @@ -351,7 +357,6 @@ var STAmount = exports.Amount = new SerializedType({ amount._currency = currency; amount._issuer = issuer; amount._is_native = false; - } else { //native var integer_bytes = value_bytes.slice(); @@ -366,8 +371,11 @@ var STAmount = exports.Amount = new SerializedType({ var STVL = exports.VariableLength = new SerializedType({ serialize: function (so, val) { - if ("string" === typeof val) serialize_hex(so, val); - else throw new Error("Unknown datatype."); + if (typeof val === 'string') { + serialize_hex(so, val); + } else { + throw new Error("Unknown datatype."); + } }, parse: function (so) { var len = this.parse_varint(so); @@ -385,33 +393,39 @@ var STAccount = exports.Account = new SerializedType({ }, parse: function (so) { var len = this.parse_varint(so); - //console.log("KKKKKKKKKKK",len); + if (len !== 20) { throw new Error("Non-standard-length account ID"); } + var result = UInt160.from_bytes(so.read(len)); + + //XX if (false && !result.is_valid()) { throw new Error("Invalid Account"); } + return result; } }); var STPathSet = exports.PathSet = new SerializedType({ - typeBoundary: 0xff, - typeEnd: 0x00, - typeAccount: 0x01, - typeCurrency: 0x10, - typeIssuer: 0x20, + typeBoundary: 0xff, + typeEnd: 0x00, + typeAccount: 0x01, + typeCurrency: 0x10, + typeIssuer: 0x20, serialize: function (so, val) { // XXX - for (var i = 0, l = val.length; i < l; i++) { + for (var i=0, l=val.length; i= 16) { - STInt8.serialize(so, type_bits) - } - if (field_bits >= 16) { - STInt8.serialize(so, field_bits) - } - var serialized_object_type = TYPES_MAP[type_bits]; - //do something with val[keys] and val[keys[i]]; - serialized_object_type.serialize(so, value); -} + //so: a byte-stream to serialize into. + //field_name: a string for the field name ("LedgerEntryType" etc.) + //value: the value of that field. + var field_coordinates = INVERSE_FIELDS_MAP[field_name]; + var type_bits = parseInt(field_coordinates[0]); + var field_bits = parseInt(field_coordinates[1]); + var tag_byte = (type_bits < 16 ? type_bits << 4 : 0) | (field_bits < 16 ? field_bits : 0) + STInt8.serialize(so, tag_byte) + if (type_bits >= 16) { + STInt8.serialize(so, type_bits) + } + + if (field_bits >= 16) { + STInt8.serialize(so, field_bits) + } + + var serialized_object_type = TYPES_MAP[type_bits]; + //do something with val[keys] and val[keys[i]]; + serialized_object_type.serialize(so, 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. -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_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 { - field_name = FIELDS_MAP[type_bits][field_bits]; - } - if ("undefined" === typeof field_name) { - throw Error("Unknown field "+tag_byte); - } else { - return [field_name, type.parse(so)]; //key, value - } - } -} +exports.parse_whatever = parse_whatever; +function parse_whatever(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_bits = so.read(1)[0]; + } + + type = TYPES_MAP[type_bits]; + + if (typeof type === 'undefined') { + throw Error("Unknown type"); + } else { + if (field_bits === 0) { + field_name = FIELDS_MAP[type_bits][so.read(1)[0]]; + } else { + field_name = FIELDS_MAP[type_bits][field_bits]; + } + if (typeof field_name === 'undefined') { + throw Error("Unknown field " + tag_byte); + } else { + return [field_name, type.parse(so)]; //key, value + } + } +}; var STObject = exports.Object = new SerializedType({ serialize: function (so, val) { var keys = Object.keys(val); - for (var i=0; i= 16) { - STInt8.serialize(so, type_bits) - } - if (field_bits >= 16) { - STInt8.serialize(so, field_bits) - } - var serialized_object_type = TYPES_MAP[type_bits]; - //do something with val[keys] and val[keys[i]]; - serialized_object_type.serialize(so, val[keys[i]]); - */ - } - STInt8.serialize(so, 0xe1); //Object ending marker + var type_bits = parseInt(field_coordinates[0]); + var field_bits = parseInt(field_coordinates[1]); + console.log(type_bits, field_bits); + var tag_byte=(type_bits < 16 ? type_bits<<4 : 0) | (field_bits < 16 ? field_bits : 0) + STInt8.serialize(so, tag_byte) + if (type_bits >= 16) { + STInt8.serialize(so, type_bits) + } + if (field_bits >= 16) { + STInt8.serialize(so, field_bits) + } + var serialized_object_type = TYPES_MAP[type_bits]; + //do something with val[keys] and val[keys[i]]; + serialized_object_type.serialize(so, val[keys[i]]); + */ + } + 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 - so.read(1); - 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; + while (so.peek(1)[0] !== 0xe1) { + var key_and_value = parse_whatever(so); + output[key_and_value[0]] = key_and_value[1]; + } + so.read(1); + return output; } }); var STArray = exports.Array = new SerializedType({ - serialize: function (so, val) { + serialize: function (so, val) { for (var i=0; i