@narumir/amf
Version:
Action Message Format for nodejs
189 lines (142 loc) • 4.26 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.AMF0Deserialize = void 0;
var _constants = require("./constants");
class AMF0Deserialize {
cursor = 0;
references = [];
constructor(data) {
this.data = data;
}
readData() {
const type = this.readUInt8();
switch (type) {
case _constants.AMF0DataType.NUMBER_MARKER:
return this.readNumberMarker();
case _constants.AMF0DataType.BOOLEAN_MARKER:
return this.readBooleanMarker();
case _constants.AMF0DataType.STRING_MARKER:
return this.readStringMarker();
case _constants.AMF0DataType.OBJECT_MARKER:
return this.readObjectMarker();
case _constants.AMF0DataType.MOVIECLIP_MARKER:
throw new Error("Sorry. this type not support, reserved for future.");
case _constants.AMF0DataType.NULL_MARKER:
return null;
case _constants.AMF0DataType.UNDEFINED_MARKER:
return undefined;
case _constants.AMF0DataType.REFERENCE_MARKER:
return this.readReferenceMarker();
case _constants.AMF0DataType.ECMA_ARRAY_MARKER:
return this.readECMAArrayMarker();
case _constants.AMF0DataType.OBJECT_END_MARKER:
return type;
case _constants.AMF0DataType.STRICT_ARRAY_MARKER:
return this.readStrictArrayMarker();
case _constants.AMF0DataType.DATE_MARKER:
return this.readDateMarker();
case _constants.AMF0DataType.LONG_STRING_MARKER:
return this.readLongStringMarker();
case _constants.AMF0DataType.UNSUPPORT_MARKER:
return;
case _constants.AMF0DataType.RECOREDSET_MARKER:
throw new Error("Sorry. this type not support, reserved for future.");
case _constants.AMF0DataType.XML_DOCUMENT_MARKER:
return this.readXMLDocumentMarker();
case _constants.AMF0DataType.TYPED_OBJECT_MARKER:
return this.readTypedObjectMarker();
case _constants.AMF0DataType.AVMPLUS_OBJECT_MARKER:
default:
throw new Error("Unknown AMF0 type error.");
}
}
readNumberMarker() {
const buf = this.data.readDoubleBE(this.cursor);
this.cursor += 8;
return buf;
}
readBooleanMarker() {
const buf = this.readUInt8();
return buf === 0 ? false : true;
}
readStringMarker() {
const len = this.readUInt16();
const str = this.data.toString("utf8", this.cursor, this.cursor + len);
this.cursor += len;
return str;
}
readObjectMarker() {
const ref = {};
while (true) {
const key = this.readStringMarker();
const value = this.readData();
if (value === _constants.AMF0DataType.OBJECT_END_MARKER) {
break;
}
ref[key] = value;
}
return ref;
}
readReferenceMarker() {
const idx = this.readUInt16();
const value = this.references[idx];
if (value == null) {
throw new Error("Reference value not found.");
}
return value;
}
readECMAArrayMarker() {
this.readUint32();
return this.readObjectMarker();
}
readStrictArrayMarker() {
const arr = [];
for (let len = this.readUint32(); len; len--) {
const key = this.readStringMarker();
const val = this.readData();
arr.push(val);
}
return arr;
}
readDateMarker() {
this.readUInt8();
const time = this.readNumberMarker();
this.readUInt16();
return new Date(time);
}
readLongStringMarker() {
const len = this.readUInt16();
const str = this.data.toString("utf-8", this.cursor, this.cursor + len);
this.cursor += len;
return str;
}
readTypedObjectMarker() {
const name = this.readStringMarker();
const obj = {
__name: name
};
Object.assign(obj, this.readObjectMarker());
return obj;
}
readXMLDocumentMarker() {
return this.readLongStringMarker();
}
readUInt8() {
const buf = this.data.readUint8(this.cursor);
this.cursor += 1;
return buf;
}
readUInt16() {
const buf = this.data.readUint16BE(this.cursor);
this.cursor += 2;
return buf;
}
readUint32() {
const buf = this.data.readUint32BE(this.cursor);
this.cursor += 4;
return buf;
}
}
exports.AMF0Deserialize = AMF0Deserialize;