UNPKG

int4.js

Version:
73 lines (60 loc) 2.21 kB
// The RLP format // Serialization and deserialization for the BytesTree type, under the following grammar: // | First byte | Meaning | // | ---------- | -------------------------------------------------------------------------- | // | 0 to 127 | HEX(leaf) | // | 128 to 183 | HEX(length_of_leaf + 128) + HEX(leaf) | // | 184 to 191 | HEX(length_of_length_of_leaf + 128 + 55) + HEX(length_of_leaf) + HEX(leaf) | // | 192 to 247 | HEX(length_of_node + 192) + HEX(node) | // | 248 to 255 | HEX(length_of_length_of_node + 128 + 55) + HEX(length_of_node) + HEX(node) | const encode = tree => { const padEven = str => str.length % 2 === 0 ? str : "0" + str; const uint = num => padEven(num.toString(16)) const length = (len, add) => len < 56 ? uint(add + len) : uint(add + uint(len).length / 2 + 55) + uint(len); const dataTree = tree => { if (typeof tree === "string") { const hex = tree.slice(2); const pre = hex.length != 2 || hex >= "80" ? length(hex.length / 2, 128) : ""; return pre + hex; } else { const hex = tree.map(dataTree).join(""); const pre = length(hex.length / 2, 192) return pre + hex; } } return "0x" + dataTree(tree); }; const decode = hex => { let i = 2; const parseTree = () => { if (i >= hex.length) throw ""; const head = hex.slice(i,i+2); return head < "80" ? (i+=2, "0x" + head) : head < "c0" ? parseHex() : parseList(); } const parseLength = () => { const len = parseInt(hex.slice(i,i+=2), 16) % 64; return len < 56 ? len : parseInt(hex.slice(i, i += (len - 55) * 2), 16); } const parseHex = () => { const len = parseLength(); return "0x" + hex.slice(i, i += len * 2); } const parseList = () => { const lim = parseLength() * 2 + i; let list = []; while (i < lim) list.push(parseTree()); return list; } try { return parseTree(); } catch (e) { return []; } }; module.exports = {encode, decode};