@astronautlabs/amf
Version:
Action Message Format (AMF0/3)
1,015 lines • 39.2 kB
JavaScript
"use strict";
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;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DictionaryValue = exports.DictionaryEntry = exports.UIntVectorValue = exports.IntVectorValue = exports.DoubleVectorValue = exports.ObjectVectorValue = exports.VectorValue = exports.ByteArray = exports.ObjectValueWithUnknownExternalizableTraits = exports.ObjectValueWithExternalizableTraits = exports.ObjectValueWithReferencedTraits = exports.ObjectValueWithLiteralTraits = exports.ObjectValueWithInternalTraits = exports.Traits = exports.ObjectValue = exports.ClassRegistry = exports.ArrayValue = exports.AssociativeValue = exports.AssociativeValueSerializer = exports.DateValue = exports.XmlValue = exports.XmlDocumentValue = exports.StringValue = exports.ReferenceValue = exports.StringOrReference = exports.DoubleValue = exports.IntegerValue = exports.TrueValue = exports.FalseValue = exports.NullValue = exports.UndefinedValue = exports.Value = exports.References = exports.amfTypeForValue = exports.amfValueForProperty = exports.amfTypeForProperty = exports.Type = exports.REFERENCE_TYPES = exports.TypeMarker = void 0;
const bitstream_1 = require("@astronautlabs/bitstream");
const u29_1 = require("./u29");
// 00100011
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 = exports.TypeMarker || (exports.TypeMarker = {}));
exports.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
];
function Type(type) {
return (target, propertyKey) => {
Reflect.defineMetadata('amf:type', type, target, propertyKey);
};
}
exports.Type = Type;
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);
}
exports.amfTypeForProperty = amfTypeForProperty;
function amfValueForProperty(object, propertyKey) {
if (object[propertyKey] instanceof Value)
return object[propertyKey];
return new (amfTypeForProperty(object, propertyKey))().with({ value: object[propertyKey] });
}
exports.amfValueForProperty = amfValueForProperty;
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;
}
exports.amfTypeForValue = amfTypeForValue;
class References {
constructor() {
this.strings = [];
this.traits = [];
this.values = [];
}
}
exports.References = References;
/**
* Represents an AMF3 "Value" in the binary protocol
*/
class Value extends bitstream_1.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([
(0, bitstream_1.Field)(8 * 1),
__metadata("design:type", Number)
], Value.prototype, "marker", void 0);
exports.Value = Value;
let UndefinedValue = class UndefinedValue extends Value {
constructor() {
super(...arguments);
this.marker = TypeMarker.Undefined;
}
get value() { return undefined; }
};
UndefinedValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Undefined)
], UndefinedValue);
exports.UndefinedValue = UndefinedValue;
let NullValue = class NullValue extends Value {
constructor() {
super(...arguments);
this.marker = TypeMarker.Null;
}
get value() { return null; }
};
NullValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Null)
], NullValue);
exports.NullValue = NullValue;
let FalseValue = class FalseValue extends Value {
constructor() {
super(...arguments);
this.marker = TypeMarker.False;
}
get value() { return false; }
};
FalseValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.False)
], FalseValue);
exports.FalseValue = FalseValue;
let TrueValue = class TrueValue extends Value {
constructor() {
super(...arguments);
this.marker = TypeMarker.True;
}
get value() { return true; }
};
TrueValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.True)
], TrueValue);
exports.TrueValue = 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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer() }),
__metadata("design:type", Number)
], IntegerValue.prototype, "$value", void 0);
IntegerValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Integer)
], IntegerValue);
exports.IntegerValue = 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([
(0, bitstream_1.Field)(8 * 8, { number: { format: 'float' } }),
__metadata("design:type", Number)
], DoubleValue.prototype, "$value", void 0);
DoubleValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Double)
], DoubleValue);
exports.DoubleValue = DoubleValue;
class StringOrReference extends bitstream_1.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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer() }),
__metadata("design:type", Number)
], StringOrReference.prototype, "$lengthOrReference", void 0);
__decorate([
(0, bitstream_1.Field)((i) => i.$lengthOrReference >> 1, { presentWhen: (i) => !i.isReference }),
__metadata("design:type", String)
], StringOrReference.prototype, "$value", void 0);
exports.StringOrReference = StringOrReference;
let ReferenceValue = class ReferenceValue extends Value {
};
ReferenceValue = __decorate([
(0, bitstream_1.Variant)(i => exports.REFERENCE_TYPES.includes(i.marker))
], ReferenceValue);
exports.ReferenceValue = 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([
(0, bitstream_1.Field)(),
__metadata("design:type", StringOrReference)
], StringValue.prototype, "stringOrReference", void 0);
StringValue = __decorate([
(0, bitstream_1.Variant)(i => [TypeMarker.String, TypeMarker.XmlDocument, TypeMarker.Xml].includes(i.marker))
], StringValue);
exports.StringValue = StringValue;
let XmlDocumentValue = class XmlDocumentValue extends StringValue {
constructor() {
super(...arguments);
this.marker = TypeMarker.XmlDocument;
}
};
XmlDocumentValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.XmlDocument)
], XmlDocumentValue);
exports.XmlDocumentValue = XmlDocumentValue;
let XmlValue = class XmlValue extends StringValue {
constructor() {
super(...arguments);
this.marker = TypeMarker.Xml;
}
};
XmlValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Xml)
], XmlValue);
exports.XmlValue = 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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer() }),
__metadata("design:type", Number)
], DateValue.prototype, "$indicator", void 0);
__decorate([
(0, bitstream_1.Field)(8 * 8, { number: { format: 'float' }, presentWhen: i => i.isLiteral }),
__metadata("design:type", Number)
], DateValue.prototype, "$value", void 0);
DateValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Date)
], DateValue);
exports.DateValue = DateValue;
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);
}
}
exports.AssociativeValueSerializer = AssociativeValueSerializer;
class AssociativeValue extends bitstream_1.BitstreamElement {
get key() { return this.$key.value; }
set key(value) { this.$key.value = value; }
}
__decorate([
(0, bitstream_1.Field)(),
__metadata("design:type", StringOrReference)
], AssociativeValue.prototype, "$key", void 0);
__decorate([
(0, bitstream_1.Field)(0, { presentWhen: i => i.key !== '' }),
__metadata("design:type", Value)
], AssociativeValue.prototype, "value", void 0);
exports.AssociativeValue = AssociativeValue;
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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer(), writtenValue: (i) => i.isLiteral ? ((i.values.length << 1) | 0x1) : (i.id << 1) }),
__metadata("design:type", Number)
], ArrayValue.prototype, "$denseLengthOrReference", void 0);
__decorate([
(0, bitstream_1.Field)(0, { array: { type: AssociativeValue }, serializer: new AssociativeValueSerializer() }),
__metadata("design:type", Array)
], ArrayValue.prototype, "associativeValues", void 0);
__decorate([
(0, bitstream_1.Field)(i => i.denseLength, { array: { type: Value } }),
__metadata("design:type", Array)
], ArrayValue.prototype, "$values", void 0);
ArrayValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Array)
], ArrayValue);
exports.ArrayValue = ArrayValue;
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);
}
}
exports.ClassRegistry = ClassRegistry;
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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer() }),
__metadata("design:type", Number)
], ObjectValue.prototype, "$objectTypeIndicator", void 0);
__decorate([
(0, bitstream_1.VariantMarker)(),
__metadata("design:type", Object)
], ObjectValue.prototype, "$variantMarker", void 0);
__decorate([
(0, bitstream_1.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([
(0, bitstream_1.Field)((i) => i.traits.sealedMemberNames.length, { array: { type: Value } }),
__metadata("design:type", Array)
], ObjectValue.prototype, "_values", void 0);
ObjectValue = ObjectValue_1 = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Object)
], ObjectValue);
exports.ObjectValue = ObjectValue;
class Traits extends bitstream_1.BitstreamElement {
constructor() {
super(...arguments);
this.sealedMemberNames = [];
}
get isDynamic() {
return this.parent.as(ObjectValueWithLiteralTraits).isDynamic;
}
}
__decorate([
(0, bitstream_1.Field)(),
__metadata("design:type", StringOrReference)
], Traits.prototype, "className", void 0);
__decorate([
(0, bitstream_1.Field)((i) => i.parent.as(ObjectValueWithLiteralTraits).sealedMemberNameCount, { array: { type: StringOrReference } }),
__metadata("design:type", Array)
], Traits.prototype, "sealedMemberNames", void 0);
exports.Traits = Traits;
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([
(0, bitstream_1.Variant)(i => !i.isExternalizable)
], ObjectValueWithInternalTraits);
exports.ObjectValueWithInternalTraits = 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([
(0, bitstream_1.Field)(),
__metadata("design:type", Traits)
], ObjectValueWithLiteralTraits.prototype, "$traits", void 0);
ObjectValueWithLiteralTraits = __decorate([
(0, bitstream_1.Variant)(i => i.isTraitLiteral)
], ObjectValueWithLiteralTraits);
exports.ObjectValueWithLiteralTraits = 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([
(0, bitstream_1.Variant)(i => i.isTraitReference)
], ObjectValueWithReferencedTraits);
exports.ObjectValueWithReferencedTraits = ObjectValueWithReferencedTraits;
let ObjectValueWithExternalizableTraits = class ObjectValueWithExternalizableTraits extends ObjectValue {
constructor() {
super(...arguments);
this.$objectTypeIndicator = 0b111;
}
};
__decorate([
(0, bitstream_1.Field)(),
__metadata("design:type", StringOrReference)
], ObjectValueWithExternalizableTraits.prototype, "className", void 0);
ObjectValueWithExternalizableTraits = __decorate([
(0, bitstream_1.Variant)(i => i.isExternalizable)
], ObjectValueWithExternalizableTraits);
exports.ObjectValueWithExternalizableTraits = ObjectValueWithExternalizableTraits;
let ObjectValueWithUnknownExternalizableTraits = class ObjectValueWithUnknownExternalizableTraits extends ObjectValueWithExternalizableTraits {
constructor() {
super();
throw new TypeError(`Unsupported externalizable object value`);
}
};
ObjectValueWithUnknownExternalizableTraits = __decorate([
(0, bitstream_1.DefaultVariant)(),
__metadata("design:paramtypes", [])
], ObjectValueWithUnknownExternalizableTraits);
exports.ObjectValueWithUnknownExternalizableTraits = 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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer(), writtenValue: i => i.value.length }),
__metadata("design:type", Number)
], ByteArray.prototype, "$lengthOrReference", void 0);
__decorate([
(0, bitstream_1.Field)(i => i.$length),
__metadata("design:type", Buffer)
], ByteArray.prototype, "$value", void 0);
ByteArray = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.ByteArray)
], ByteArray);
exports.ByteArray = 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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer(), writtenValue: i => i.value.length }),
__metadata("design:type", Number)
], VectorValue.prototype, "$lengthOrReference", void 0);
__decorate([
(0, bitstream_1.Field)(8, { presentWhen: i => i.isLiteral }),
__metadata("design:type", Boolean)
], VectorValue.prototype, "isFixed", void 0);
VectorValue = __decorate([
(0, bitstream_1.Variant)(i => [TypeMarker.VectorDouble, TypeMarker.VectorInt, TypeMarker.VectorObject, TypeMarker.VectorUint].includes(i.marker))
], VectorValue);
exports.VectorValue = 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([
(0, bitstream_1.Field)(i => i.length, { array: { type: Value } }),
__metadata("design:type", Array)
], ObjectVectorValue.prototype, "values", void 0);
__decorate([
(0, bitstream_1.Field)(),
__metadata("design:type", StringOrReference)
], ObjectVectorValue.prototype, "objectTypeName", void 0);
ObjectVectorValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.VectorObject)
], ObjectVectorValue);
exports.ObjectVectorValue = 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([
(0, bitstream_1.Field)(i => i.length, { array: { type: Number, elementLength: 8 * 4 }, number: { format: 'float' } }),
__metadata("design:type", Array)
], DoubleVectorValue.prototype, "values", void 0);
DoubleVectorValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.VectorDouble)
], DoubleVectorValue);
exports.DoubleVectorValue = 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([
(0, bitstream_1.Field)(i => i.length * 8 * 4),
__metadata("design:type", Uint8Array),
__metadata("design:paramtypes", [Object])
], IntVectorValue.prototype, "bytes", null);
IntVectorValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.VectorInt)
], IntVectorValue);
exports.IntVectorValue = 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([
(0, bitstream_1.Field)(i => i.length * 8 * 4),
__metadata("design:type", Uint8Array),
__metadata("design:paramtypes", [Object])
], UIntVectorValue.prototype, "bytes", null);
UIntVectorValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.VectorUint)
], UIntVectorValue);
exports.UIntVectorValue = UIntVectorValue;
class DictionaryEntry extends bitstream_1.BitstreamElement {
}
__decorate([
(0, bitstream_1.Field)(),
__metadata("design:type", Value)
], DictionaryEntry.prototype, "key", void 0);
__decorate([
(0, bitstream_1.Field)(),
__metadata("design:type", Value)
], DictionaryEntry.prototype, "value", void 0);
exports.DictionaryEntry = DictionaryEntry;
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([
(0, bitstream_1.Field)(0, { serializer: new u29_1.U29Serializer(), writtenValue: i => i.value.length }),
__metadata("design:type", Number)
], DictionaryValue.prototype, "$lengthOrReference", void 0);
__decorate([
(0, bitstream_1.Field)(8, { presentWhen: i => i.isLiteral }),
__metadata("design:type", Boolean)
], DictionaryValue.prototype, "hasWeakKeys", void 0);
__decorate([
(0, bitstream_1.Field)(i => i.length, { presentWhen: i => i.isLiteral, array: { type: DictionaryEntry } }),
__metadata("design:type", Array)
], DictionaryValue.prototype, "$entries", void 0);
DictionaryValue = __decorate([
(0, bitstream_1.Variant)(i => i.marker === TypeMarker.Dictionary)
], DictionaryValue);
exports.DictionaryValue = DictionaryValue;
//# sourceMappingURL=amf3.js.map