| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 | 
							- import { defineProperties, isError, assert, assertArgument, assertArgumentCount } from "../../utils/index.js";
 
- import { Typed } from "../typed.js";
 
- import { Coder, Result, WordSize, Writer } from "./abstract-coder.js";
 
- import { AnonymousCoder } from "./anonymous.js";
 
- /**
 
-  *  @_ignore
 
-  */
 
- export 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;
 
-             assert(name, "cannot encode object for signature with missing names", "INVALID_ARGUMENT", { argument: "values", info: { coder }, value: values });
 
-             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 {
 
-         assertArgument(false, "invalid tuple value", "tuple", values);
 
-     }
 
-     assertArgument(coders.length === arrayValues.length, "types/value length mismatch", "tuple", values);
 
-     let staticWriter = new Writer();
 
-     let dynamicWriter = new 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;
 
- }
 
- /**
 
-  *  @_ignore
 
-  */
 
- export 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 (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 (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 Result.fromItems(values, keys);
 
- }
 
- /**
 
-  *  @_ignore
 
-  */
 
- export class ArrayCoder extends 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);
 
-         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.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);
 
-         }
 
-         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.
 
-             assert(count * WordSize <= reader.dataLength, "insufficient data length", "BUFFER_OVERRUN", { buffer: reader.bytes, offset: count * WordSize, length: reader.dataLength });
 
-         }
 
-         let coders = [];
 
-         for (let i = 0; i < count; i++) {
 
-             coders.push(new AnonymousCoder(this.coder));
 
-         }
 
-         return unpack(reader, coders);
 
-     }
 
- }
 
- //# sourceMappingURL=array.js.map
 
 
  |