UNPKG

@narumir/amf

Version:

Action Message Format for nodejs

367 lines (276 loc) 8.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AMF0Serialize = void 0; var _constants = require("./constants"); class AMF0Serialize { buffer = Buffer.alloc(0); references = []; constructor(data) { this.writeData(data); } getResult() { return this.buffer; } writeNumberMarker(data) { this.writeUInt8(_constants.AMF0DataType.NUMBER_MARKER); const buf = Buffer.alloc(8); buf.writeDoubleBE(data); this.buffer = Buffer.concat([this.buffer, buf]); } writeBooleanMarker(data) { this.writeUInt8(_constants.AMF0DataType.BOOLEAN_MARKER); const buf = Buffer.alloc(1, 0); buf.writeUint8(data ? 1 : 0); this.buffer = Buffer.concat([this.buffer, buf]); } writeStringMarker(data, withMarker = true) { if (withMarker) { this.writeUInt8(_constants.AMF0DataType.STRING_MARKER); } const buf = Buffer.from(data); this.writeUInt16(buf.length); this.buffer = Buffer.concat([this.buffer, buf]); } writeObjectMarker(data) { this.writeUInt8(_constants.AMF0DataType.OBJECT_MARKER); for (let key in data) { this.writeStringMarker(key, false); this.writeData(data[key]); } this.writeStringMarker("", false); this.writeObjectEndMarker(); } writeNullMarker() { this.writeUInt8(_constants.AMF0DataType.NULL_MARKER); } writeUndefinedMarker() { this.writeUInt8(_constants.AMF0DataType.UNDEFINED_MARKER); } writeReferenceMarker(data) { this.writeUInt8(_constants.AMF0DataType.REFERENCE_MARKER); const idx = this.references.indexOf(data); if (idx === -1) { this.references.push(data); } if (idx > _constants.AMF0_NORMAL_MAX_SIZE) { throw new Error("Out of Reference range."); } this.writeUInt16(idx); } writeECMAArrayMarker(data) { const idx = this.references.indexOf(data); if (idx >= 0) { this.writeReferenceMarker(data); } this.references.push(data); this.writeUInt8(_constants.AMF0DataType.ECMA_ARRAY_MARKER); this.writeUInt32(data.length); for (const key in data) { this.writeStringMarker(key, false); this.writeData(data[key]); } this.writeUInt16(0); this.writeUInt8(_constants.AMF0DataType.OBJECT_END_MARKER); } writeObjectEndMarker() { this.writeUInt8(_constants.AMF0DataType.OBJECT_END_MARKER); } writeStrictArrayMarker(data) { const idx = this.references.indexOf(data); if (idx >= 0) { this.writeReferenceMarker(data); } this.references.push(data); this.writeUInt8(_constants.AMF0DataType.STRICT_ARRAY_MARKER); this.writeUInt32(data.length); for (const key in data) { this.writeStringMarker(key, false); this.writeData(data[key]); } this.writeUInt16(0); this.writeUInt8(_constants.AMF0DataType.OBJECT_END_MARKER); } writeDateMarker(data) { this.writeUInt8(_constants.AMF0DataType.DATE_MARKER); this.writeNumberMarker(data.getTime()); this.writeUInt16(0); } writeLongStringMarker(data, withMarker = true) { if (withMarker) { this.writeUInt8(_constants.AMF0DataType.LONG_STRING_MARKER); } const buf = Buffer.from(data); this.writeUInt16(buf.length); this.buffer = Buffer.concat([this.buffer, buf]); } writeUnsupportMarker() { this.writeUInt8(_constants.AMF0DataType.UNSUPPORT_MARKER); } writeXMLDocumentMarker(data) { this.writeUInt8(_constants.AMF0DataType.XML_DOCUMENT_MARKER); this.writeLongStringMarker(data, false); } writeTypedObjectMarker(data) { const idx = this.references.indexOf(data); if (idx >= 0) { this.writeReferenceMarker(data); } this.references.push(data); this.writeUInt8(_constants.AMF0DataType.TYPED_OBJECT_MARKER); this.writeStringMarker(data.constructor.name, false); for (const key in data) { this.writeStringMarker(key, false); this.writeData(data[key]); } this.writeUInt16(0); this.writeUInt8(_constants.AMF0DataType.OBJECT_END_MARKER); } writeData(data) { if (data == null) { throw new Error("Unknown data."); } if (data.marker == null) { return this.writeWithoutMarker(data); } switch (data.marker) { case _constants.AMF0Marker.NUMBER: if (typeof data.value !== "number") { break; } return this.writeNumberMarker(data.value); case _constants.AMF0Marker.BOOLEAN: if (typeof data.value !== "boolean") { break; } return this.writeBooleanMarker(data.value); case _constants.AMF0Marker.STRING: if (typeof data.value !== "string") { break; } const str = data.value; return str.length > _constants.AMF0_NORMAL_MAX_SIZE ? this.writeLongStringMarker(str) : this.writeStringMarker(str); case _constants.AMF0Marker.OBJECT: if (!this.isObject(data.value)) { break; } return this.writeObjectMarker(data.value); case _constants.AMF0Marker.NULL: return this.writeNullMarker(); case _constants.AMF0Marker.UNDEFINED: return this.writeUndefinedMarker(); case _constants.AMF0Marker.ECMA_ARRAY: return this.writeECMAArrayMarker(data.value); case _constants.AMF0Marker.STRICT_ARRAY: return this.writeStrictArrayMarker(data.value); case _constants.AMF0Marker.DATE: if (data.value instanceof Date === false) { break; } return this.writeDateMarker(data.value); case _constants.AMF0Marker.XML_DOCUMENT: if (typeof data.value !== "string") { break; } return this.writeXMLDocumentMarker(data.value); case _constants.AMF0Marker.TYPED_OBJECT: if (!this.isTypedObject(data.value)) { break; } return this.writeTypedObjectMarker(data.value); case _constants.AMF0Marker.AVM_PLUS_OBJECT: // TODO return; default: throw new TypeError("Unknown AMF types."); } return this.writeUnsupportMarker(); } writeWithoutMarker(data) { if (data === null) { return this.writeNullMarker(); } if (data === undefined) { return this.writeUndefinedMarker(); } if (typeof data === "number") { return this.writeNumberMarker(data); } if (typeof data === "boolean") { return this.writeBooleanMarker(data); } if (typeof data === "string") { return data.length > _constants.AMF0_NORMAL_MAX_SIZE ? this.writeLongStringMarker(data) : this.writeStringMarker(data); } if (data instanceof Date) { return this.writeDateMarker(data); } if (Array.isArray(data)) { return this.isStrictArray(data) ? this.writeStrictArrayMarker(data) : this.writeECMAArrayMarker(data); } if (this.isObject(data)) { return this.writeObjectMarker(data); } if (this.isTypedObject(data)) { return this.writeTypedObjectMarker(data); } return this.writeUnsupportMarker(); } writeUInt8(data) { const buf = Buffer.alloc(1, 0); buf.writeUint8(data); this.buffer = Buffer.concat([this.buffer, buf]); } writeUInt16(data) { const buf = Buffer.alloc(2, 0); buf.writeUint16BE(data); this.buffer = Buffer.concat([this.buffer, buf]); } writeUInt32(data) { const buf = Buffer.alloc(4, 0); buf.writeUint32BE(data); this.buffer = Buffer.concat([this.buffer, buf]); } isObject(data) { if (data == null) { return false; } if (typeof data !== "object") { return false; } if (data instanceof Date) { return false; } if (data.constructor.name !== "Object") { return false; } return true; } isTypedObject(data) { if (data == null) { return false; } if (typeof data !== "object") { return false; } if (data instanceof Date) { return false; } if (data.constructor.name === "Object") { return false; } return true; } isStrictArray(data) { let length = 0; for (const _ in data) { length += 1; } if (data.length !== length) { return false; } return true; } } exports.AMF0Serialize = AMF0Serialize;