UNPKG

24.6 kBSource Map (JSON)View Raw
1{"version":3,"file":"index.umd.js","sources":["../src/const.js","../src/parser.js"],"sourcesContent":["const PRIMITIVE_TYPES = {\n UInt8: 1,\n UInt16LE: 2,\n UInt16BE: 2,\n UInt32LE: 4,\n UInt32BE: 4,\n Int8: 1,\n Int16LE: 2,\n Int16BE: 2,\n Int32LE: 4,\n Int32BE: 4,\n FloatLE: 4,\n FloatBE: 4,\n DoubleLE: 8,\n DoubleBE: 8,\n};\n\nconst SPECIAL_TYPES = {\n Array: null,\n Skip: null,\n Nest: null,\n Bit: null,\n String: null,\n};\n\nconst BIT_RANGE = Array.from(new Array(32), (val, index) => index + 1);\n\nlet NAME_MAP = {};\nObject.keys({ ...PRIMITIVE_TYPES, ...SPECIAL_TYPES }).forEach(type => {\n NAME_MAP[type.toLowerCase()] = type;\n});\n\nexport { PRIMITIVE_TYPES, SPECIAL_TYPES, BIT_RANGE, NAME_MAP };\n","import { PRIMITIVE_TYPES, BIT_RANGE, NAME_MAP } from \"./const\";\n\nconst has = Object.prototype.hasOwnProperty;\n\nexport default class Telegram {\n constructor() {\n this.chain = [];\n this.bitChain = [];\n this.endian = \"be\";\n this.initialize();\n }\n\n initialize() {\n this.addPrimitiveType();\n this.addBitType();\n }\n\n addPrimitiveType() {\n Object.keys(PRIMITIVE_TYPES).forEach(type => {\n this[type.toLowerCase()] = (varName, options) =>\n this.setNextParser(type.toLowerCase(), varName, options);\n const typeWithoutEndian = type.replace(/BE|LE/, \"\").toLowerCase();\n if (typeof this[typeWithoutEndian] !== \"function\") {\n this[typeWithoutEndian] = (varName, options) =>\n this.setNextParser(typeWithoutEndian + this.endian, varName, options);\n }\n });\n }\n\n addBitType() {\n BIT_RANGE.forEach(i => {\n this[`bit${i}`] = (varName, options) => {\n options = options || {};\n options = { ...options, length: i };\n return this.setNextParser(\"bit\", varName, options);\n };\n });\n }\n\n skip(length, options) {\n if (options && options.assert) {\n throw new Error(\"assert option on skip is not allowed.\");\n }\n if (options === undefined) {\n options = {};\n }\n options.length = length;\n return this.setNextParser(\"skip\", \"\", options);\n }\n\n string(varName, options) {\n if (!options.zeroTerminated && !options.length && !options.greedy) {\n throw new Error(\"Neither length, zeroTerminated, nor greedy is defined for string.\");\n }\n if ((options.zeroTerminated || options.length) && options.greedy) {\n throw new Error(\"Greedy is mutually exclusive with length and zeroTerminated for string.\");\n }\n if (options.stripNull && !(options.length || options.greedy)) {\n throw new Error(\"Length or greedy must be defined if stripNull is defined.\");\n }\n\n options.encoding = options.encoding || \"ascii\";\n\n return this.setNextParser(\"string\", varName, options);\n }\n\n array(varName, options) {\n if (!options.readUntil && !options.length && !options.lengthInBytes) {\n throw new Error(\"Length option of array is not defined.\");\n }\n if (!options.type) {\n throw new Error(\"Type option of array is not defined.\");\n }\n if (\n typeof options.type === \"string\" &&\n !(has.call(PRIMITIVE_TYPES, NAME_MAP[options.type]) || options.type === \"string\")\n ) {\n throw new Error(`Specified primitive type ${options.type} is not supported.`);\n }\n\n return this.setNextParser(\"array\", varName, options);\n }\n\n nest(varName, options) {\n if (arguments.length === 1 && typeof varName === \"object\") {\n options = varName;\n varName = null;\n }\n\n if (!options.type) {\n throw new Error(\"Type option of nest is not defined.\");\n }\n if (!(options.type instanceof Telegram) && !(typeof options.type === \"function\")) {\n throw new Error(\"Type option of nest must be a Telegram object.\");\n }\n\n return this.setNextParser(\"nest\", varName, options);\n }\n\n endianess(endianess) {\n switch (endianess.toLowerCase()) {\n case \"little\":\n this.endian = \"le\";\n break;\n case \"big\":\n this.endian = \"be\";\n break;\n default:\n throw new Error(\"Invalid endianess: \" + endianess);\n }\n\n return this;\n }\n\n setNextParser(type, varName, options) {\n if (type === \"bit\") {\n const lastParser = this.chain[this.chain.length - 1];\n if (lastParser && lastParser.type === \"bits\") {\n lastParser.bitChain.push({ varName, options });\n } else {\n this.chain.push({ type: \"bits\", bitChain: [{ varName, options }] });\n }\n } else {\n this.chain.push({ type, varName, options });\n }\n return this;\n }\n\n decompress(buffer, needLength = false) {\n const input = { buffer, offset: 0, bitOffset: 0 };\n const { buf, result } = this.parse(input, {});\n if (needLength) {\n const length = buf.offset;\n return { result, length };\n }\n return result;\n }\n\n parse(buf, result) {\n for (const item of this.chain) {\n const typeProcessor = new typeClasses[item.type]({ endian: this.endian });\n typeProcessor.parse(buf, result, item);\n }\n return { buf, result };\n }\n}\n\nlet typeClasses = {};\n\nclass Processor {\n constructor({ endian }) {\n this.endian = endian;\n this.buf = null;\n this.result = null;\n this.ownResult = null;\n this.item = null;\n }\n\n parse(buf, result, item) {\n this.buf = buf;\n this.result = result;\n this.item = item;\n this.initialize();\n this.realParse();\n this.assert();\n this.formatter();\n this.store();\n this.updateStatus();\n }\n\n initialize() {\n return;\n }\n\n realParse(buf, result, item) {\n return;\n }\n\n formatter(item) {\n const options = typeof item !== \"undefined\" ? item.options : this.item.options;\n if (options && typeof options.formatter === \"function\") {\n this.ownResult = options.formatter.call(this, this.ownResult);\n }\n return;\n }\n\n assert(item) {\n const options = typeof item !== \"undefined\" ? item.options : this.item.options;\n if (options && options.assert) {\n let isEqual = true;\n switch (typeof options.assert) {\n case \"function\":\n isEqual = options.assert.call(this, this.ownResult);\n break;\n case \"number\":\n case \"string\":\n isEqual = this.ownResult === options.assert;\n break;\n default:\n throw new Error(\"Assert option supports only numbers and string and assert functions.\");\n }\n if (!isEqual) {\n throw new Error(`Assert error: ${this.item.varName} is ${this.ownResult}`);\n }\n }\n return;\n }\n\n store() {\n const { varName } = this.item;\n this.result[varName] = this.ownResult;\n }\n\n updateStatus() {\n return;\n }\n\n getResult() {\n return { buf: this.buf, result: this.result };\n }\n\n calcBitOffset(bitLength) {\n const { bitOffset } = this.buf;\n this.buf.bitOffset = (bitOffset + bitLength) % 8;\n const carry = Math.floor((bitOffset + bitLength) / 8);\n this.buf.offset += carry;\n }\n\n generateLength(option) {\n let length;\n if (typeof option === \"number\") {\n length = option;\n } else if (typeof option === \"function\") {\n length = option.call(this, this.result);\n } else if (typeof option === \"string\") {\n length = this.result[option];\n }\n return length;\n }\n}\n\nObject.keys(PRIMITIVE_TYPES).forEach(type => {\n typeClasses[`${type.toLowerCase()}`] = class extends Processor {\n realParse() {\n const { buffer, offset } = this.buf;\n this.ownResult = buffer[`read${type}`](offset);\n }\n\n updateStatus() {\n this.buf.offset += PRIMITIVE_TYPES[type];\n }\n };\n});\n\nclass array extends Processor {\n constructor(options) {\n super(options);\n this.ownItemResult = null;\n this.type = null;\n this.typeName = null;\n }\n\n initialize() {\n this.ownResult = [];\n this.defineType();\n }\n\n defineType() {\n const {\n options: { type },\n } = this.item;\n if (typeof type === \"string\") {\n if (Object.keys(PRIMITIVE_TYPES).includes(NAME_MAP[type])) {\n this.typeName = \"PRIMITIVE_TYPES\";\n } else {\n this.typeName = type;\n }\n this.type = NAME_MAP[type];\n } else if (type instanceof Telegram) {\n this.typeName = \"Telegram\";\n this.type = type;\n }\n }\n\n realParse() {\n let i = 0;\n const {\n options: { length, readUntil },\n } = this.item;\n if (length) {\n const arrayLength = this.generateLength(length);\n for (i = 0; i < arrayLength; i++) {\n this.parseItem();\n }\n } else if (readUntil === \"eof\") {\n while (this.buf.offset < this.buf.buffer.length) {\n this.parseItem();\n }\n } else if (typeof readUntil === \"number\") {\n while (this.buf.offset < this.buf.buffer.length - readUntil) {\n this.parseItem();\n }\n }\n }\n\n parseItem() {\n this.realParseItem();\n this.pushItem();\n this.updateItemStatus();\n }\n\n realParseItem() {\n const { buffer, offset } = this.buf;\n switch (this.typeName) {\n case \"PRIMITIVE_TYPES\":\n this.ownItemResult = buffer[`read${this.type}`](offset);\n break;\n case \"string\":\n const {\n options: { subOptions },\n } = this.item;\n if (subOptions.hasOwnProperty(\"length\")) {\n subOptions.length = this.generateLength(subOptions.length);\n }\n const stringParser = new Telegram().string(\"tmp\", subOptions);\n const { result: str_result } = stringParser.parse(this.buf, {});\n this.ownItemResult = str_result.tmp;\n break;\n case \"Telegram\":\n const { result: new_result } = this.type.parse(this.buf, {});\n this.ownItemResult = new_result;\n break;\n default:\n break;\n }\n }\n\n pushItem() {\n this.ownResult.push(this.ownItemResult);\n }\n\n updateItemStatus() {\n if (this.typeName === \"PRIMITIVE_TYPES\") {\n this.buf.offset += PRIMITIVE_TYPES[this.type];\n }\n }\n}\n\nclass bits extends Processor {\n constructor(options) {\n super(options);\n this.bitChain = null;\n this.bitItem = null;\n }\n\n swap(bitLength) {\n const length = Math.ceil(bitLength / 8);\n const { buffer, offset } = this.buf;\n const sliced = buffer.slice(offset, offset + length);\n const hexBuf = sliced.toString(\"hex\").match(/.{1,2}/g);\n let len = offset + length - 1;\n for (const hex of hexBuf) {\n buffer.write(hex, len--, 1, \"hex\");\n }\n this.buf.buffer = buffer;\n }\n\n initialize() {\n const { bitChain } = this.item;\n this.bitChain = bitChain;\n const bitLength = this.bitChain.reduce((sum, item) => sum + item.options.length, 0);\n const isBigEndian = this.endian === \"be\";\n if (!isBigEndian) {\n this.swap(bitLength);\n }\n }\n\n parse(buf, result, item) {\n this.buf = buf;\n this.result = result;\n this.item = item;\n this.initialize();\n this.realParse();\n }\n\n realParse() {\n for (const bitItem of this.bitChain) {\n this.bitItem = bitItem;\n this.parseBit();\n }\n }\n\n parseBit() {\n this.realParseBit();\n this.formatter(this.bitItem);\n this.assert(this.bitItem);\n this.store();\n this.updateStatus();\n }\n\n realParseBit() {\n const { buffer, offset, bitOffset } = this.buf;\n const {\n options: { length },\n } = this.bitItem;\n const byteToBeRead = Math.ceil((bitOffset + length) / 8);\n let tmp = 0;\n switch (byteToBeRead) {\n case 1:\n tmp = buffer.readUInt8(offset);\n break;\n case 2:\n tmp = buffer.readUInt16BE(offset);\n break;\n case 3:\n const tmp1 = buffer.readUInt16BE(offset);\n const tmp2 = buffer.readUInt8(offset + 2);\n tmp = (tmp1 << 8) | tmp2;\n break;\n case 4:\n tmp = buffer.readUInt32BE(offset);\n break;\n case 5:\n const tmp3 = buffer.readUInt32BE(offset);\n const tmp4 = buffer.readUInt8(offset + 4);\n tmp = (tmp3 << 8) | tmp4;\n break;\n default:\n break;\n }\n const rshift = (bitOffset + length) % 8 ? 8 * byteToBeRead - (bitOffset + length) : 0;\n const mask = (1 << length) - 1;\n this.ownResult = (tmp >> rshift) & mask;\n }\n\n store() {\n const { varName } = this.bitItem;\n this.result[varName] = this.ownResult;\n }\n\n updateStatus() {\n const {\n options: { length },\n } = this.bitItem;\n this.calcBitOffset(length);\n }\n}\n\nclass nest extends Processor {\n realParse() {\n const {\n options: { type },\n } = this.item;\n if (type instanceof Telegram) {\n const { result: new_result } = type.parse(this.buf, {});\n this.ownResult = new_result;\n } else if (typeof type === \"function\") {\n const subParser = type.call(this, this.result);\n if (subParser instanceof Telegram) {\n const { result: new_result } = subParser.parse(this.buf, {});\n this.ownResult = new_result;\n } else {\n throw new Error(\"Type option of nest must be a Telegram object.\");\n }\n }\n }\n\n store() {\n const { varName } = this.item;\n if (varName) {\n this.result[varName] = this.ownResult;\n } else {\n Object.assign(this.result, this.ownResult);\n }\n }\n}\n\nclass skip extends Processor {\n store() {\n return;\n }\n\n updateStatus() {\n const {\n options: { length, type },\n } = this.item;\n const skipLength = this.generateLength(length);\n if (type === \"bit\") {\n this.calcBitOffset(skipLength);\n } else {\n this.buf.offset += skipLength;\n }\n }\n}\n\nclass string extends Processor {\n constructor(options) {\n super(options);\n this.stringLength = null;\n this.isZeroTerminated = false;\n }\n\n realParse() {\n const {\n options: { length, encoding, zeroTerminated, greedy, stripNull },\n } = this.item;\n const { buffer, offset } = this.buf;\n // calc the length of string\n const start = offset;\n if (length && zeroTerminated) {\n let i = start;\n const len = this.generateLength(length);\n for (i; i < start + len; i++) {\n if (buffer.readUInt8(i) === 0) {\n break;\n }\n }\n this.stringLength = i - start;\n this.isZeroTerminated = this.stringLength === len ? false : true;\n } else if (length) {\n this.stringLength = this.generateLength(length);\n } else if (zeroTerminated) {\n let i = start;\n for (i; i < buffer.length; i++) {\n if (buffer.readUInt8(i) === 0) {\n break;\n }\n }\n this.stringLength = i - start;\n this.isZeroTerminated = i === buffer.length ? false : true;\n } else if (greedy) {\n this.stringLength = buffer.length - start;\n }\n\n this.ownResult = buffer.toString(encoding, offset, offset + this.stringLength);\n if (stripNull) {\n this.ownResult = this.ownResult.replace(/\\0/g, \"\");\n }\n }\n\n store() {\n const { varName } = this.item;\n this.result[varName] = this.ownResult;\n }\n\n updateStatus() {\n this.buf.offset += this.isZeroTerminated ? this.stringLength + 1 : this.stringLength;\n }\n}\n\ntypeClasses.array = array;\ntypeClasses.bits = bits;\ntypeClasses.nest = nest;\ntypeClasses.skip = skip;\ntypeClasses.string = string;\n"],"names":["const","PRIMITIVE_TYPES","UInt8","UInt16LE","UInt16BE","UInt32LE","UInt32BE","Int8","Int16LE","Int16BE","Int32LE","Int32BE","FloatLE","FloatBE","DoubleLE","DoubleBE","BIT_RANGE","Array","from","val","index","NAME_MAP","Object","keys","Skip","Nest","Bit","String","forEach","type","toLowerCase","has","prototype","hasOwnProperty","Telegram","this","chain","bitChain","endian","initialize","addPrimitiveType","addBitType","varName","options","setNextParser","typeWithoutEndian","replace","i","length","skip","assert","Error","undefined","string","zeroTerminated","greedy","stripNull","encoding","array","readUntil","lengthInBytes","call","nest","arguments","endianess","lastParser","push","decompress","buffer","needLength","parse","result","offset","buf","item","typeClasses","let","Processor","ref","ownResult","realParse","formatter","store","updateStatus","isEqual","getResult","calcBitOffset","bitLength","bitOffset","carry","Math","floor","generateLength","option","super","ownItemResult","typeName","defineType","includes","arrayLength","parseItem","realParseItem","pushItem","updateItemStatus","subOptions","tmp","bits","bitItem","swap","ceil","len","slice","toString","match","write","reduce","sum","parseBit","realParseBit","byteToBeRead","readUInt8","readUInt16BE","readUInt32BE","subParser","assign","skipLength","stringLength","isZeroTerminated","start"],"mappings":"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"}
\No newline at end of file