| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 | "use strict";Object.defineProperty(exports, "__esModule", { value: true });exports.ArrayCoder = exports.unpack = exports.pack = void 0;const index_js_1 = require("../../utils/index.js");const typed_js_1 = require("../typed.js");const abstract_coder_js_1 = require("./abstract-coder.js");const anonymous_js_1 = require("./anonymous.js");/** *  @_ignore */function pack(writer, coders, values) {    let arrayValues = [];    if (Array.isArray(values)) {        arrayValues = values;    }    else if (values && typeof (values) === "object") {        let unique = {};        arrayValues = coders.map((coder) => {            const name = coder.localName;            (0, index_js_1.assert)(name, "cannot encode object for signature with missing names", "INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });            (0, index_js_1.assert)(!unique[name], "cannot encode object for signature with duplicate names", "INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });            unique[name] = true;            return values[name];        });    }    else {        (0, index_js_1.assertArgument)(false, "invalid tuple value", "tuple", values);    }    (0, index_js_1.assertArgument)(coders.length === arrayValues.length, "types/value length mismatch", "tuple", values);    let staticWriter = new abstract_coder_js_1.Writer();    let dynamicWriter = new abstract_coder_js_1.Writer();    let updateFuncs = [];    coders.forEach((coder, index) => {        let value = arrayValues[index];        if (coder.dynamic) {            // Get current dynamic offset (for the future pointer)            let dynamicOffset = dynamicWriter.length;            // Encode the dynamic value into the dynamicWriter            coder.encode(dynamicWriter, value);            // Prepare to populate the correct offset once we are done            let updateFunc = staticWriter.writeUpdatableValue();            updateFuncs.push((baseOffset) => {                updateFunc(baseOffset + dynamicOffset);            });        }        else {            coder.encode(staticWriter, value);        }    });    // Backfill all the dynamic offsets, now that we know the static length    updateFuncs.forEach((func) => { func(staticWriter.length); });    let length = writer.appendWriter(staticWriter);    length += writer.appendWriter(dynamicWriter);    return length;}exports.pack = pack;/** *  @_ignore */function unpack(reader, coders) {    let values = [];    let keys = [];    // A reader anchored to this base    let baseReader = reader.subReader(0);    coders.forEach((coder) => {        let value = null;        if (coder.dynamic) {            let offset = reader.readIndex();            let offsetReader = baseReader.subReader(offset);            try {                value = coder.decode(offsetReader);            }            catch (error) {                // Cannot recover from this                if ((0, index_js_1.isError)(error, "BUFFER_OVERRUN")) {                    throw error;                }                value = error;                value.baseType = coder.name;                value.name = coder.localName;                value.type = coder.type;            }        }        else {            try {                value = coder.decode(reader);            }            catch (error) {                // Cannot recover from this                if ((0, index_js_1.isError)(error, "BUFFER_OVERRUN")) {                    throw error;                }                value = error;                value.baseType = coder.name;                value.name = coder.localName;                value.type = coder.type;            }        }        if (value == undefined) {            throw new Error("investigate");        }        values.push(value);        keys.push(coder.localName || null);    });    return abstract_coder_js_1.Result.fromItems(values, keys);}exports.unpack = unpack;/** *  @_ignore */class ArrayCoder extends abstract_coder_js_1.Coder {    coder;    length;    constructor(coder, length, localName) {        const type = (coder.type + "[" + (length >= 0 ? length : "") + "]");        const dynamic = (length === -1 || coder.dynamic);        super("array", type, localName, dynamic);        (0, index_js_1.defineProperties)(this, { coder, length });    }    defaultValue() {        // Verifies the child coder is valid (even if the array is dynamic or 0-length)        const defaultChild = this.coder.defaultValue();        const result = [];        for (let i = 0; i < this.length; i++) {            result.push(defaultChild);        }        return result;    }    encode(writer, _value) {        const value = typed_js_1.Typed.dereference(_value, "array");        if (!Array.isArray(value)) {            this._throwError("expected array value", value);        }        let count = this.length;        if (count === -1) {            count = value.length;            writer.writeValue(value.length);        }        (0, index_js_1.assertArgumentCount)(value.length, count, "coder array" + (this.localName ? (" " + this.localName) : ""));        let coders = [];        for (let i = 0; i < value.length; i++) {            coders.push(this.coder);        }        return pack(writer, coders, value);    }    decode(reader) {        let count = this.length;        if (count === -1) {            count = reader.readIndex();            // Check that there is *roughly* enough data to ensure            // stray random data is not being read as a length. Each            // slot requires at least 32 bytes for their value (or 32            // bytes as a link to the data). This could use a much            // tighter bound, but we are erroring on the side of safety.            (0, index_js_1.assert)(count * abstract_coder_js_1.WordSize <= reader.dataLength, "insufficient data length", "BUFFER_OVERRUN", { buffer: reader.bytes, offset: count * abstract_coder_js_1.WordSize, length: reader.dataLength });        }        let coders = [];        for (let i = 0; i < count; i++) {            coders.push(new anonymous_js_1.AnonymousCoder(this.coder));        }        return unpack(reader, coders);    }}exports.ArrayCoder = ArrayCoder;//# sourceMappingURL=array.js.map
 |