-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathLazyArray.js
74 lines (61 loc) · 1.62 KB
/
LazyArray.js
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import {Array as ArrayT} from './Array.js';
import {Number as NumberT} from './Number.js';
import * as utils from './utils.js';
export class LazyArray extends ArrayT {
decode(stream, parent) {
const { pos } = stream;
const length = utils.resolveLength(this.length, stream, parent);
if (this.length instanceof NumberT) {
parent = {
parent,
_startOffset: pos,
_currentOffset: 0,
_length: length
};
}
const res = new LazyArrayValue(this.type, length, stream, parent);
stream.pos += length * this.type.size(null, parent);
return res;
}
size(val, ctx) {
if (val instanceof LazyArrayValue) {
val = val.toArray();
}
return super.size(val, ctx);
}
encode(stream, val, ctx) {
if (val instanceof LazyArrayValue) {
val = val.toArray();
}
return super.encode(stream, val, ctx);
}
}
class LazyArrayValue {
constructor(type, length, stream, ctx) {
this.type = type;
this.length = length;
this.stream = stream;
this.ctx = ctx;
this.base = this.stream.pos;
this.items = [];
}
get(index) {
if ((index < 0) || (index >= this.length)) {
return undefined;
}
if (this.items[index] == null) {
const { pos } = this.stream;
this.stream.pos = this.base + (this.type.size(null, this.ctx) * index);
this.items[index] = this.type.decode(this.stream, this.ctx);
this.stream.pos = pos;
}
return this.items[index];
}
toArray() {
const result = [];
for (let i = 0, end = this.length; i < end; i++) {
result.push(this.get(i));
}
return result;
}
}