-
Notifications
You must be signed in to change notification settings - Fork 1.3k
/
array.ts
46 lines (37 loc) · 1.34 KB
/
array.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { concatWithDynamicData } from '../utilities';
import type { TypesOfCoder } from './abstract-coder';
import { Coder } from './abstract-coder';
type InputValueOf<TCoder extends Coder> = Array<TypesOfCoder<TCoder>['Input']>;
type DecodedValueOf<TCoder extends Coder> = Array<TypesOfCoder<TCoder>['Decoded']>;
export class ArrayCoder<TCoder extends Coder> extends Coder<
InputValueOf<TCoder>,
DecodedValueOf<TCoder>
> {
coder: TCoder;
length: number;
constructor(coder: TCoder, length: number) {
super('array', `[${coder.type}; ${length}]`, length * coder.encodedLength);
this.coder = coder;
this.length = length;
}
encode(value: InputValueOf<TCoder>): Uint8Array {
if (!Array.isArray(value)) {
this.throwError('expected array value', value);
}
if (this.length !== value.length) {
this.throwError('Types/values length mismatch', value);
}
return concatWithDynamicData(Array.from(value).map((v) => this.coder.encode(v)));
}
decode(data: Uint8Array, offset: number): [DecodedValueOf<TCoder>, number] {
let newOffset = offset;
const decodedValue = Array(this.length)
.fill(0)
.map(() => {
let decoded;
[decoded, newOffset] = this.coder.decode(data, newOffset);
return decoded;
});
return [decodedValue as DecodedValueOf<TCoder>, newOffset];
}
}