UNPKG

@astronautlabs/amf

Version:

Action Message Format (AMF0/3)

1,000 lines 36.1 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var ObjectValue_1; import { BitstreamElement, DefaultVariant, Field, Variant, VariantMarker } from "@astronautlabs/bitstream"; import { U29Serializer } from "./u29"; // 00100011 export var TypeMarker; (function (TypeMarker) { TypeMarker[TypeMarker["Undefined"] = 0] = "Undefined"; TypeMarker[TypeMarker["Null"] = 1] = "Null"; TypeMarker[TypeMarker["False"] = 2] = "False"; TypeMarker[TypeMarker["True"] = 3] = "True"; TypeMarker[TypeMarker["Integer"] = 4] = "Integer"; TypeMarker[TypeMarker["Double"] = 5] = "Double"; TypeMarker[TypeMarker["String"] = 6] = "String"; TypeMarker[TypeMarker["XmlDocument"] = 7] = "XmlDocument"; TypeMarker[TypeMarker["Date"] = 8] = "Date"; TypeMarker[TypeMarker["Array"] = 9] = "Array"; TypeMarker[TypeMarker["Object"] = 10] = "Object"; TypeMarker[TypeMarker["Xml"] = 11] = "Xml"; TypeMarker[TypeMarker["ByteArray"] = 12] = "ByteArray"; TypeMarker[TypeMarker["VectorInt"] = 13] = "VectorInt"; TypeMarker[TypeMarker["VectorUint"] = 14] = "VectorUint"; TypeMarker[TypeMarker["VectorDouble"] = 15] = "VectorDouble"; TypeMarker[TypeMarker["VectorObject"] = 16] = "VectorObject"; TypeMarker[TypeMarker["Dictionary"] = 17] = "Dictionary"; })(TypeMarker || (TypeMarker = {})); export const REFERENCE_TYPES = [ TypeMarker.XmlDocument, TypeMarker.Date, TypeMarker.Array, TypeMarker.Object, TypeMarker.Xml, TypeMarker.ByteArray, TypeMarker.VectorDouble, TypeMarker.VectorInt, TypeMarker.VectorUint, TypeMarker.VectorObject, TypeMarker.Dictionary, TypeMarker.String ]; export function Type(type) { return (target, propertyKey) => { Reflect.defineMetadata('amf:type', type, target, propertyKey); }; } export function amfTypeForProperty(object, propertyKey) { let value = object[propertyKey]; if (object.prototype) { let declared = Reflect.getMetadata('amf:type', object.prototype); if (declared) return declared; } return amfTypeForValue(value); } export function amfValueForProperty(object, propertyKey) { if (object[propertyKey] instanceof Value) return object[propertyKey]; return new (amfTypeForProperty(object, propertyKey))().with({ value: object[propertyKey] }); } export function amfTypeForValue(value) { if (typeof value === 'number') return DoubleValue; if (typeof value === 'undefined') return UndefinedValue; if (value === null) return NullValue; if (value === true) return TrueValue; if (value === false) return FalseValue; if (typeof value === 'string') return StringValue; if (value instanceof Date) return DateValue; if (value instanceof Buffer) return ByteArray; if (value instanceof Uint32Array) return UIntVectorValue; if (value instanceof Int32Array) return IntVectorValue; if (value instanceof Map) return DictionaryValue; if (Array.isArray(value)) return ArrayValue; if (typeof value === 'object') return ObjectValueWithLiteralTraits; } export class References { constructor() { this.strings = []; this.traits = []; this.values = []; } } /** * Represents an AMF3 "Value" in the binary protocol */ export class Value extends BitstreamElement { get references() { if (!this.context.__references) this.context.__references = new References(); return this.context.__references; } get value() { return undefined; } set value(value) { throw new Error(`Value cannot be set on this type [${this.constructor.name}]`); } static get undefined() { return new UndefinedValue(); } static get null() { return new NullValue(); } static boolean(value) { if (value) return new TrueValue(); else return new FalseValue(); } static int(value) { return new IntegerValue().with({ value }); } static double(value) { return new DoubleValue().with({ value }); } static string(value) { return new StringValue().with({ value }); } static xmlDocument(value) { return new XmlDocumentValue().with({ value }); } static xml(value) { return new XmlValue().with({ value }); } static date(value) { return new DateValue().with({ value }); } static any(value) { return value instanceof Value ? value : new (amfTypeForValue(value))().with({ value }); } static array(array) { let keys = Object.keys(array); let keySet = new Set(keys); let associativeKeySet = new Set(keys); let isSparse = false; let maxDenseKey = undefined; // Determine how dense the array is and which keys are associative. // This will include any keys that are not part of the dense portion // of the array for (let i = 0, max = array.length; i < max; ++i) { if (!keySet.has(i.toString())) { isSparse = true; continue; } if (!isSparse) { maxDenseKey = i; associativeKeySet.delete(i.toString()); } } return new ArrayValue().with({ values: array.slice(0, maxDenseKey + 1) .map(value => Value.any(value)), associativeValues: Array.from(associativeKeySet.values()) .map(key => new AssociativeValue().with({ key, value: Value.any(array[key]) })) }); } static object(value) { return new ObjectValueWithLiteralTraits().with({ value }); } static byteArray(buffer) { return new ByteArray().with({ value: Buffer.from(buffer) }); } static vector(value, isFixed = false) { if (value instanceof Int32Array) return new IntVectorValue().with({ value, isFixed }); if (value instanceof Uint32Array) return new UIntVectorValue().with({ value, isFixed }); if (Array.isArray(value)) { if (value.some(x => typeof x !== 'number')) { throw new TypeError(`Passing number[] to vector() produces a DoubleVector ` + `but the passed array has one or more elements which are ` + `not of type 'number'. Did you mean to use objectVector()?`); } return new DoubleVectorValue().with({ value, isFixed }); } throw new TypeError(`The passed value cannot be converted to an Int32, Uint32 or Double AMF3 vector!`); } static objectVector(values, isFixed = false) { return new ObjectVectorValue().with({ values: values.map(x => Value.any(x)), isFixed }); } static dictionary(map) { return new DictionaryValue().with({ value: map }); } } __decorate([ Field(8 * 1), __metadata("design:type", Number) ], Value.prototype, "marker", void 0); let UndefinedValue = class UndefinedValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Undefined; } get value() { return undefined; } }; UndefinedValue = __decorate([ Variant(i => i.marker === TypeMarker.Undefined) ], UndefinedValue); export { UndefinedValue }; let NullValue = class NullValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Null; } get value() { return null; } }; NullValue = __decorate([ Variant(i => i.marker === TypeMarker.Null) ], NullValue); export { NullValue }; let FalseValue = class FalseValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.False; } get value() { return false; } }; FalseValue = __decorate([ Variant(i => i.marker === TypeMarker.False) ], FalseValue); export { FalseValue }; let TrueValue = class TrueValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.True; } get value() { return true; } }; TrueValue = __decorate([ Variant(i => i.marker === TypeMarker.True) ], TrueValue); export { TrueValue }; let IntegerValue = class IntegerValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Integer; } get value() { return this.$value; } set value(value) { this.$value = value; } }; __decorate([ Field(0, { serializer: new U29Serializer() }), __metadata("design:type", Number) ], IntegerValue.prototype, "$value", void 0); IntegerValue = __decorate([ Variant(i => i.marker === TypeMarker.Integer) ], IntegerValue); export { IntegerValue }; let DoubleValue = class DoubleValue extends Value { constructor() { super(...arguments); this.marker = TypeMarker.Double; } get value() { return this.$value; } set value(value) { this.$value = value; } }; __decorate([ Field(8 * 8, { number: { format: 'float' } }), __metadata("design:type", Number) ], DoubleValue.prototype, "$value", void 0); DoubleValue = __decorate([ Variant(i => i.marker === TypeMarker.Double) ], DoubleValue); export { DoubleValue }; export class StringOrReference extends BitstreamElement { get isReference() { return !this.isLiteral; } get isLiteral() { return (this.$lengthOrReference & 0x1) === 1; } get id() { return this.isReference ? this.$lengthOrReference >> 1 : undefined; } ; set id(value) { if (value > 0xFFFFFFF) throw new Error(`Maximum ID is 0xFFFFFFF (1114111)`); this.$lengthOrReference = (value << 1); this.$value = undefined; } get value() { return this.$value; } set value(value) { this.$lengthOrReference = (Buffer.from(value).length << 1) | 0x1; this.$value = value; } } __decorate([ Field(0, { serializer: new U29Serializer() }), __metadata("design:type", Number) ], StringOrReference.prototype, "$lengthOrReference", void 0); __decorate([ Field((i) => i.$lengthOrReference >> 1, { presentWhen: (i) => !i.isReference }), __metadata("design:type", String) ], StringOrReference.prototype, "$value", void 0); let ReferenceValue = class ReferenceValue extends Value { }; ReferenceValue = __decorate([ Variant(i => REFERENCE_TYPES.includes(i.marker)) ], ReferenceValue); export { ReferenceValue }; /** * Represents the "String" type of "Value" in Adobe's ActionScript Message Format (AMF) version 3. * - U29Serializer: Encodes/decodes values in AMF3's custom variable-length integer format * - Low bit of 0 or 1 on the "length" field determines if the value is a reference to a String Table entry * or is an inline string literal * - Thus IDs and lengths are limited to 2^28 since variable length strs are max 29 bits * * From the user's perspective, just set either `id` or `value`. When reading use `isReference()` to determine * whether this string is a reference to the string table or literal and `id` or `value` respectively. `id` and * `value` return `undefined` when they are not relevant for this object. */ let StringValue = class StringValue extends ReferenceValue { constructor() { super(...arguments); this.marker = TypeMarker.String; this.stringOrReference = new StringOrReference(); } get isLiteral() { return this.stringOrReference.isLiteral; } get isReference() { return this.stringOrReference.isReference; } get id() { return this.stringOrReference.id; } set id(id) { this.stringOrReference.id = id; } ; get value() { return this.stringOrReference.value; } set value(value) { this.stringOrReference.value = value; } }; __decorate([ Field(), __metadata("design:type", StringOrReference) ], StringValue.prototype, "stringOrReference", void 0); StringValue = __decorate([ Variant(i => [TypeMarker.String, TypeMarker.XmlDocument, TypeMarker.Xml].includes(i.marker)) ], StringValue); export { StringValue }; let XmlDocumentValue = class XmlDocumentValue extends StringValue { constructor() { super(...arguments); this.marker = TypeMarker.XmlDocument; } }; XmlDocumentValue = __decorate([ Variant(i => i.marker === TypeMarker.XmlDocument) ], XmlDocumentValue); export { XmlDocumentValue }; let XmlValue = class XmlValue extends StringValue { constructor() { super(...arguments); this.marker = TypeMarker.Xml; } }; XmlValue = __decorate([ Variant(i => i.marker === TypeMarker.Xml) ], XmlValue); export { XmlValue }; let DateValue = class DateValue extends ReferenceValue { constructor() { super(...arguments); this.marker = TypeMarker.Date; this.$indicator = 0x1; this.$value = 0; } get isLiteral() { return this.$indicator !== 0; } get isReference() { return !this.isLiteral; } get value() { var _a; return (_a = this.$date) !== null && _a !== void 0 ? _a : (this.$date = new Date(this.$value)); } set value(value) { if (value === null || value === void 0) throw new TypeError(`AMF3 cannot transport null/undefined Date`); if (!(value instanceof Date)) throw new TypeError(`Value must be a valid Date`); this.$date = value; this.$value = value.getTime(); } }; __decorate([ Field(0, { serializer: new U29Serializer() }), __metadata("design:type", Number) ], DateValue.prototype, "$indicator", void 0); __decorate([ Field(8 * 8, { number: { format: 'float' }, presentWhen: i => i.isLiteral }), __metadata("design:type", Number) ], DateValue.prototype, "$value", void 0); DateValue = __decorate([ Variant(i => i.marker === TypeMarker.Date) ], DateValue); export { DateValue }; export class AssociativeValueSerializer { *read(reader, type, parent, field) { let assocs = []; while (true) { let av = AssociativeValue.read(reader).next(); if (av.done === false) { yield av.value; return; } if (av.value.key === '') break; assocs.push(av.value); } return assocs; } write(writer, type, parent, field, value) { value.forEach(a => a.write(writer)); new AssociativeValue().with({ key: '' }).write(writer); } } export class AssociativeValue extends BitstreamElement { get key() { return this.$key.value; } set key(value) { this.$key.value = value; } } __decorate([ Field(), __metadata("design:type", StringOrReference) ], AssociativeValue.prototype, "$key", void 0); __decorate([ Field(0, { presentWhen: i => i.key !== '' }), __metadata("design:type", Value) ], AssociativeValue.prototype, "value", void 0); let ArrayValue = class ArrayValue extends ReferenceValue { constructor() { super(...arguments); this.marker = TypeMarker.Array; this.associativeValues = []; } get isReference() { return !this.isLiteral; } get isLiteral() { return (this.$denseLengthOrReference & 0x1) === 1; } get id() { return this.isReference ? this.$denseLengthOrReference >> 1 : undefined; } ; set id(value) { if (value > 0xFFFFFFF) throw new Error(`Maximum ID is 0xFFFFFFF (1114111)`); this.$denseLengthOrReference = (value << 1); this.values = undefined; } get denseLength() { var _a, _b; if (this.isLiteral) return (_b = (_a = this.values) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : this.$denseLengthOrReference >> 1; } get values() { return this.$values; } set values(value) { this.$values = value; this.$denseLengthOrReference = value.length << 1 | 0x1; } }; __decorate([ Field(0, { serializer: new U29Serializer(), writtenValue: (i) => i.isLiteral ? ((i.values.length << 1) | 0x1) : (i.id << 1) }), __metadata("design:type", Number) ], ArrayValue.prototype, "$denseLengthOrReference", void 0); __decorate([ Field(0, { array: { type: AssociativeValue }, serializer: new AssociativeValueSerializer() }), __metadata("design:type", Array) ], ArrayValue.prototype, "associativeValues", void 0); __decorate([ Field(i => i.denseLength, { array: { type: Value } }), __metadata("design:type", Array) ], ArrayValue.prototype, "$values", void 0); ArrayValue = __decorate([ Variant(i => i.marker === TypeMarker.Array) ], ArrayValue); export { ArrayValue }; export class ClassRegistry { constructor() { this._map = new Map(); } register(klass, name) { this._map.set(name !== null && name !== void 0 ? name : klass.name, klass); } get(name) { return this._map.get(name); } } let ObjectValue = ObjectValue_1 = class ObjectValue extends ReferenceValue { constructor() { super(...arguments); this.marker = TypeMarker.Object; this._dynamicMembers = []; this._values = []; } get registry() { // So this happens when creating the value outside of parsing. // TODO: Not clear this is the best behavior if (!this.context) return new ClassRegistry(); if (!this.context.__classes) this.context.__classes = new ClassRegistry(); return this.context.__classes; } get isReference() { return !this.isLiteral; } get isLiteral() { return (this.$objectTypeIndicator & 0x1) === 1; } get isTraitLiteral() { return this.isLiteral && (this.$objectTypeIndicator & 0x2) === 2; } get isTraitReference() { return !this.isTraitLiteral; } get isExternalizable() { return this.isTraitLiteral && (this.$objectTypeIndicator & 0x4) === 0x4; } get id() { return this.isReference ? this.$objectTypeIndicator >> 1 : undefined; } set id(value) { this.$objectTypeIndicator = value << 1; } static reference(id) { return new ObjectValue_1().with({ id }); } get dynamicMembers() { return this._dynamicMembers; } set dynamicMembers(value) { this._dynamicMembers = value; } get values() { return this._values; } set values(value) { if (value === undefined || value === null) throw new TypeError(`Value cannot be set to undefined/null`); this._values = value; } }; __decorate([ Field(0, { serializer: new U29Serializer() }), __metadata("design:type", Number) ], ObjectValue.prototype, "$objectTypeIndicator", void 0); __decorate([ VariantMarker(), __metadata("design:type", Object) ], ObjectValue.prototype, "$variantMarker", void 0); __decorate([ Field(0, { array: { type: AssociativeValue, hasMore: (i) => i.dynamicMembers.length === 0 || i.dynamicMembers[i.dynamicMembers.length - 1].key !== '' }, presentWhen: i => i.isDynamic, serializer: new AssociativeValueSerializer() }), __metadata("design:type", Array) ], ObjectValue.prototype, "_dynamicMembers", void 0); __decorate([ Field((i) => i.traits.sealedMemberNames.length, { array: { type: Value } }), __metadata("design:type", Array) ], ObjectValue.prototype, "_values", void 0); ObjectValue = ObjectValue_1 = __decorate([ Variant(i => i.marker === TypeMarker.Object) ], ObjectValue); export { ObjectValue }; export class Traits extends BitstreamElement { constructor() { super(...arguments); this.sealedMemberNames = []; } get isDynamic() { return this.parent.as(ObjectValueWithLiteralTraits).isDynamic; } } __decorate([ Field(), __metadata("design:type", StringOrReference) ], Traits.prototype, "className", void 0); __decorate([ Field((i) => i.parent.as(ObjectValueWithLiteralTraits).sealedMemberNameCount, { array: { type: StringOrReference } }), __metadata("design:type", Array) ], Traits.prototype, "sealedMemberNames", void 0); let ObjectValueWithInternalTraits = class ObjectValueWithInternalTraits extends ObjectValue { constructor() { super(...arguments); this.$objectTypeIndicator = 0b001; } get traits() { return undefined; } get value() { return this._value; } set value(value) { this._value = value; } get values() { return super.values; } set values(value) { if (value === undefined || value === null) throw new TypeError(`Cannot assign null/undefined to ObjectValueWithInternalTraits.values`); super.values = value; this.buildValue(); } set dynamicMembers(value) { super.dynamicMembers = value; this.buildValue(); } buildValue() { var _a; if (!this.traits) { return; } let values = (_a = this.values) !== null && _a !== void 0 ? _a : []; let obj; let klass = this.registry.get(this.traits.className.value); if (klass) { obj = new klass(); } else { obj = {}; } this._value = this.traits.sealedMemberNames.reduce((o, name, i) => { var _a; return (o[name.value] = (_a = values[i]) === null || _a === void 0 ? void 0 : _a.value, o); }, obj); if (this.dynamicMembers) this.dynamicMembers.forEach(m => this._value[m.key] = m.value); } onParseFinished() { this.buildValue(); } }; ObjectValueWithInternalTraits = __decorate([ Variant(i => !i.isExternalizable) ], ObjectValueWithInternalTraits); export { ObjectValueWithInternalTraits }; let ObjectValueWithLiteralTraits = class ObjectValueWithLiteralTraits extends ObjectValueWithInternalTraits { constructor() { super(...arguments); this.$objectTypeIndicator = 0b011; } get isDynamic() { return (this.$objectTypeIndicator & 0x8) === 0x8; } set isDynamic(value) { if (value) this.$objectTypeIndicator |= 0x8; else this.$objectTypeIndicator &= ~0x8; } get sealedMemberNameCount() { return (this.$objectTypeIndicator & 0x1ffffff0) >>> 4; } set sealedMemberNameCount(value) { this.$objectTypeIndicator &= 0xF; this.$objectTypeIndicator |= (value << 4); } get traits() { return this.$traits; } set traits(value) { this.$traits = value; this.buildValue(); } get value() { return super.value; } set value(value) { let keys = Object.keys(value); this.traits = new Traits().with({ className: new StringOrReference().with({ value: '' }), sealedMemberNames: keys.map(x => new StringOrReference().with({ value: x })) }); this.sealedMemberNameCount = keys.length; let encoded = keys.map(key => amfValueForProperty(value, key)); this.values = encoded; this.buildValue(); } }; __decorate([ Field(), __metadata("design:type", Traits) ], ObjectValueWithLiteralTraits.prototype, "$traits", void 0); ObjectValueWithLiteralTraits = __decorate([ Variant(i => i.isTraitLiteral) ], ObjectValueWithLiteralTraits); export { ObjectValueWithLiteralTraits }; let ObjectValueWithReferencedTraits = class ObjectValueWithReferencedTraits extends ObjectValueWithInternalTraits { constructor() { super(...arguments); this.$objectTypeIndicator = 0b001; } get traitsId() { return this.$objectTypeIndicator & 0x7ffffff; } set traitsId(id) { this.$objectTypeIndicator &= 0x18000000; this.$objectTypeIndicator |= (id & 0x7ffffff); } get traits() { return this.references.traits[this.traitsId]; } set traits(value) { let index = this.references.traits.indexOf(value); if (index < 0) throw new Error(`The traits value ${value.toJSON()} is not in the traits index.`); this.traitsId = index; } }; ObjectValueWithReferencedTraits = __decorate([ Variant(i => i.isTraitReference) ], ObjectValueWithReferencedTraits); export { ObjectValueWithReferencedTraits }; let ObjectValueWithExternalizableTraits = class ObjectValueWithExternalizableTraits extends ObjectValue { constructor() { super(...arguments); this.$objectTypeIndicator = 0b111; } }; __decorate([ Field(), __metadata("design:type", StringOrReference) ], ObjectValueWithExternalizableTraits.prototype, "className", void 0); ObjectValueWithExternalizableTraits = __decorate([ Variant(i => i.isExternalizable) ], ObjectValueWithExternalizableTraits); export { ObjectValueWithExternalizableTraits }; let ObjectValueWithUnknownExternalizableTraits = class ObjectValueWithUnknownExternalizableTraits extends ObjectValueWithExternalizableTraits { constructor() { super(); throw new TypeError(`Unsupported externalizable object value`); } }; ObjectValueWithUnknownExternalizableTraits = __decorate([ DefaultVariant(), __metadata("design:paramtypes", []) ], ObjectValueWithUnknownExternalizableTraits); export { ObjectValueWithUnknownExternalizableTraits }; let ByteArray = class ByteArray extends ReferenceValue { constructor() { super(...arguments); this.marker = TypeMarker.ByteArray; } get isReference() { return !this.isLiteral; } get isLiteral() { return (this.$lengthOrReference & 0x1) === 1; } get id() { return this.isReference ? this.$lengthOrReference >> 1 : undefined; } set id(value) { this.$lengthOrReference = value << 1; } get value() { return this.isLiteral ? this.$value : undefined; } set value(value) { this.$value = value; this.$lengthOrReference = value.length << 1 | 0x1; } ; }; __decorate([ Field(0, { serializer: new U29Serializer(), writtenValue: i => i.value.length }), __metadata("design:type", Number) ], ByteArray.prototype, "$lengthOrReference", void 0); __decorate([ Field(i => i.$length), __metadata("design:type", Buffer) ], ByteArray.prototype, "$value", void 0); ByteArray = __decorate([ Variant(i => i.marker === TypeMarker.ByteArray) ], ByteArray); export { ByteArray }; function int32ArrayToBytes(array) { let buf = new Uint8Array(array.length * array.BYTES_PER_ELEMENT); let view = new DataView(buf.buffer); for (let i = 0, max = array.length; i < max; ++i) { view.setInt32(i * array.BYTES_PER_ELEMENT, array[i], false); } return buf; } function uint32ArrayToBytes(array) { let buf = new Uint8Array(array.length * array.BYTES_PER_ELEMENT); let view = new DataView(buf.buffer); for (let i = 0, max = array.length; i < max; ++i) view.setUint32(i * array.BYTES_PER_ELEMENT, array[i], false); return buf; } function doubleArrayToBytes(array) { let buf = new Uint8Array(array.length * 8); let view = new DataView(buf.buffer); for (let i = 0, max = array.length; i < max; ++i) view.setFloat64(i * 8, array[i], false); } function bytesToInt32Array(array) { if (!array) return undefined; let buf = new Int32Array(array.length / 4); let view = new DataView(array.buffer); for (let i = 0, max = buf.length; i < max; ++i) { buf[i] = view.getInt32(i * buf.BYTES_PER_ELEMENT, false); } return buf; } function bytesToUint32Array(array) { let buf = new Uint32Array(array.length / 4); let view = new DataView(array.buffer); for (let i = 0, max = buf.length; i < max; ++i) buf[i] = view.getUint32(i * buf.BYTES_PER_ELEMENT, false); return buf; } function bytesToDoubleArray(array) { let buf = []; let view = new DataView(array.buffer); for (let i = 0, max = array.length / 8; i < max; ++i) buf[i] = view.getFloat64(i * 8, false); return buf; } let VectorValue = class VectorValue extends ReferenceValue { constructor() { super(...arguments); this.isFixed = true; } get isReference() { return !this.isLiteral; } get isLiteral() { return (this.$lengthOrReference & 0x1) === 1; } get id() { return this.isReference ? this.$lengthOrReference >> 1 : undefined; } set id(value) { this.$lengthOrReference = value << 1; } get length() { return this.isLiteral ? this.$lengthOrReference >> 1 : undefined; } }; __decorate([ Field(0, { serializer: new U29Serializer(), writtenValue: i => i.value.length }), __metadata("design:type", Number) ], VectorValue.prototype, "$lengthOrReference", void 0); __decorate([ Field(8, { presentWhen: i => i.isLiteral }), __metadata("design:type", Boolean) ], VectorValue.prototype, "isFixed", void 0); VectorValue = __decorate([ Variant(i => [TypeMarker.VectorDouble, TypeMarker.VectorInt, TypeMarker.VectorObject, TypeMarker.VectorUint].includes(i.marker)) ], VectorValue); export { VectorValue }; let ObjectVectorValue = class ObjectVectorValue extends VectorValue { constructor() { super(...arguments); this.marker = TypeMarker.VectorObject; } get value() { return this.values; } set value(value) { this.values = value; this.$lengthOrReference = value.length << 1 | 0x1; } }; __decorate([ Field(i => i.length, { array: { type: Value } }), __metadata("design:type", Array) ], ObjectVectorValue.prototype, "values", void 0); __decorate([ Field(), __metadata("design:type", StringOrReference) ], ObjectVectorValue.prototype, "objectTypeName", void 0); ObjectVectorValue = __decorate([ Variant(i => i.marker === TypeMarker.VectorObject) ], ObjectVectorValue); export { ObjectVectorValue }; let DoubleVectorValue = class DoubleVectorValue extends VectorValue { constructor() { super(...arguments); this.marker = TypeMarker.VectorDouble; } get value() { return this.values; } set value(value) { this.values = value; this.$lengthOrReference = value.length << 1 | 0x1; } }; __decorate([ Field(i => i.length, { array: { type: Number, elementLength: 8 * 4 }, number: { format: 'float' } }), __metadata("design:type", Array) ], DoubleVectorValue.prototype, "values", void 0); DoubleVectorValue = __decorate([ Variant(i => i.marker === TypeMarker.VectorDouble) ], DoubleVectorValue); export { DoubleVectorValue }; let IntVectorValue = class IntVectorValue extends VectorValue { constructor() { super(...arguments); this.marker = TypeMarker.VectorInt; } get bytes() { return this._bytes; } set bytes(value) { this._bytes = value; this._elements = bytesToInt32Array(value); this.$lengthOrReference = this._elements.length << 1 | 0x1; } get value() { return this._elements; } set value(value) { this._elements = value; this._bytes = int32ArrayToBytes(value); this.$lengthOrReference = value.length << 1 | 0x1; } }; __decorate([ Field(i => i.length * 8 * 4), __metadata("design:type", Uint8Array), __metadata("design:paramtypes", [Object]) ], IntVectorValue.prototype, "bytes", null); IntVectorValue = __decorate([ Variant(i => i.marker === TypeMarker.VectorInt) ], IntVectorValue); export { IntVectorValue }; let UIntVectorValue = class UIntVectorValue extends VectorValue { constructor() { super(...arguments); this.marker = TypeMarker.VectorUint; } get bytes() { return this._bytes; } set bytes(value) { this._bytes = value; this._elements = bytesToUint32Array(value); this.$lengthOrReference = this._elements.length << 1 | 0x1; } get value() { return this._elements; } set value(value) { this._elements = value; this._bytes = uint32ArrayToBytes(value); this.$lengthOrReference = this._elements.length << 1 | 0x1; } }; __decorate([ Field(i => i.length * 8 * 4), __metadata("design:type", Uint8Array), __metadata("design:paramtypes", [Object]) ], UIntVectorValue.prototype, "bytes", null); UIntVectorValue = __decorate([ Variant(i => i.marker === TypeMarker.VectorUint) ], UIntVectorValue); export { UIntVectorValue }; export class DictionaryEntry extends BitstreamElement { } __decorate([ Field(), __metadata("design:type", Value) ], DictionaryEntry.prototype, "key", void 0); __decorate([ Field(), __metadata("design:type", Value) ], DictionaryEntry.prototype, "value", void 0); let DictionaryValue = class DictionaryValue extends ReferenceValue { constructor() { super(...arguments); this.marker = TypeMarker.Dictionary; } get isReference() { return !this.isLiteral; } get isLiteral() { return (this.$lengthOrReference & 0x1) === 1; } get id() { return this.isReference ? this.$lengthOrReference >> 1 : undefined; } set id(value) { this.$lengthOrReference = value << 1; } get length() { return this.isLiteral ? this.$lengthOrReference >> 1 : undefined; } get value() { return new Map(this.entries.map(e => [e.key.value, e.value.value])); } set value(value) { let entries = []; value.forEach((v, k) => { entries.push(new DictionaryEntry().with({ key: Value.any(k), value: Value.any(v) })); }); this.entries = entries; } get entries() { return this.$entries; } set entries(value) { this.$entries = value; this.$lengthOrReference = this.$entries.length << 1 | 0x1; } }; __decorate([ Field(0, { serializer: new U29Serializer(), writtenValue: i => i.value.length }), __metadata("design:type", Number) ], DictionaryValue.prototype, "$lengthOrReference", void 0); __decorate([ Field(8, { presentWhen: i => i.isLiteral }), __metadata("design:type", Boolean) ], DictionaryValue.prototype, "hasWeakKeys", void 0); __decorate([ Field(i => i.length, { presentWhen: i => i.isLiteral, array: { type: DictionaryEntry } }), __metadata("design:type", Array) ], DictionaryValue.prototype, "$entries", void 0); DictionaryValue = __decorate([ Variant(i => i.marker === TypeMarker.Dictionary) ], DictionaryValue); export { DictionaryValue }; //# sourceMappingURL=amf3.js.map