UNPKG

2.32 kBJavaScriptView Raw
1const lodash = require('lodash');
2const { assert, format } = require('../util');
3const BaseCoder = require('./BaseCoder');
4const { encodeUInt256, decodeUInt256, pack, unpack } = require('./util');
5
6class ArrayCoder extends BaseCoder {
7 static from({ type, name, components }, abiCoder) {
8 const match = type.match(/^(.*)\[([0-9]*)]$/);
9 if (!match) {
10 return undefined;
11 }
12
13 const [, subType, size] = match;
14 return new this({
15 name,
16 coder: abiCoder({ type: subType, components }),
17 size: size ? parseInt(size, 10) : undefined,
18 });
19 }
20
21 constructor({ name, coder, size }) {
22 if (size !== undefined) {
23 assert(Number.isInteger(size) && 0 < size, {
24 message: 'invalid size',
25 expect: 'integer && >0',
26 got: size,
27 coder: { name },
28 });
29 }
30
31 super({ name });
32 this.type = `${coder.type}[${size > 0 ? size : ''}]`;
33 this.size = size;
34 this.coder = coder;
35 this.dynamic = Boolean(size === undefined) || coder.dynamic;
36 }
37
38 /**
39 * @param array {array}
40 * @return {Buffer}
41 */
42 encode(array) {
43 assert(Array.isArray(array), {
44 message: 'unexpected type',
45 expect: 'array',
46 got: typeof array,
47 coder: this,
48 });
49
50 if (this.size !== undefined) {
51 assert(array.length === this.size, {
52 message: 'length not match',
53 expect: this.size,
54 got: array.length,
55 coder: this,
56 });
57 }
58
59 const coders = lodash.range(array.length).map(() => this.coder);
60 let buffer = pack(coders, array);
61 if (this.size === undefined) {
62 buffer = Buffer.concat([encodeUInt256(array.length), buffer]);
63 }
64 return buffer;
65 }
66
67 /**
68 * @param stream {HexStream}
69 * @return {array}
70 */
71 decode(stream) {
72 let length = this.size;
73
74 if (length === undefined) {
75 length = Number(decodeUInt256(stream));
76 }
77
78 const coders = lodash.range(length).map(() => this.coder);
79 return unpack(coders, stream);
80 }
81
82 encodeIndex(value) {
83 try {
84 return format.hex64(value);
85 } catch (e) {
86 throw new Error('not supported encode array to index');
87 }
88 }
89
90 decodeIndex(hex) {
91 return hex;
92 }
93}
94
95module.exports = ArrayCoder;