@foliojs-fork/restructure
Version:
Declaratively encode and decode binary data
82 lines (66 loc) • 1.82 kB
JavaScript
const ArrayT = require('./Array');
const {Number:NumberT} = require('./Number');
const utils = require('./utils');
const {inspect} = require('util');
class LazyArrayT 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 LazyArray(this.type, length, stream, parent);
stream.pos += length * this.type.size(null, parent);
return res;
}
size(val, ctx) {
if (val instanceof LazyArray) {
val = val.toArray();
}
return super.size(val, ctx);
}
encode(stream, val, ctx) {
if (val instanceof LazyArray) {
val = val.toArray();
}
return super.encode(stream, val, ctx);
}
}
class LazyArray {
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;
}
inspect() {
return inspect(this.toArray());
}
}
module.exports = LazyArrayT;