UNPKG

node-custom-tlv

Version:
205 lines (161 loc) 4.65 kB
const { validateArgs, deleteWhiteSpaces, createLengthParams, makeToUpperCase, computeCustomByteLengths, makeStringFromBuffer, checkForParity, BYTE_FACTOR } = require("./helpers/helpers"); let finalJson = {}; class NestedContext { context; constructor(parentTag, length) { this.context = { parentTag, parentLength: length }; } get context() { return this.context; } } class NodeCustomTlv { dictionary = {}; baseTagLength = BYTE_FACTOR * 2; baseLengthTlvLength = BYTE_FACTOR * 1; customByteLengths = null; customByteLengthComputed = []; constructor(settings) { if (!validateArgs(settings)) { return; } this.dictionary = settings.dictionary; this.baseTagLength = BYTE_FACTOR * settings.baseTagLength; this.baseLengthTlvLength = BYTE_FACTOR * settings.baseLengthTlvLength; this.customByteLengths = settings.customByteLengths; finalJson = {}; } parseTlv(data, nestedContext = null) { let str; if (typeof data == "string") { str = data; } else if (Buffer.isBuffer(data)) { str = makeStringFromBuffer(buffer); } else { console.error("wrong first argument: " + data); return; } str = deleteWhiteSpaces(str); str = makeToUpperCase(str); let initialStr; if (!checkForParity(str.length)) { console.error("fail of string parity, length: " + str.length); return; } if (!nestedContext) { initialStr = str; if (this.customByteLengths && this.customByteLengths.length) { this.customByteLengthComputed = computeCustomByteLengths( this.customByteLengths, this.baseTagLength ); } } if (nestedContext && !(nestedContext instanceof NestedContext)) { console.error("wrong second argument: " + nestedContext); return; } const k = this.baseTagLength; let help_nested = {}; for (let i = 0; i < str.length; ) { const help_obj = {}; let tagObj; let value; let fullTag; let tagName; const tag = str.substr(i, k); if ( nestedContext && nestedContext.context && nestedContext.context.parentTag ) { fullTag = nestedContext.context.parentTag + tag; } else { fullTag = tag; } tagObj = this.dictionary[fullTag]; if (!tagObj) { tagName = fullTag; } else { tagName = tagObj.name; } const lenthByte = str.substring( i + this.baseTagLength, i + this.baseTagLength + this.baseLengthTlvLength ); const createLengthPayload = { baselengthByte: lenthByte, i, str, baseTagLength: this.baseTagLength, baseLengthTlvLength: this.baseLengthTlvLength, customByteLengthComputed: this.customByteLengthComputed ? this.customByteLengthComputed : null }; const { length, differ } = createLengthParams(createLengthPayload); if (tagObj && tagObj.nested) { value = str.substring(i + differ, i + differ + length); const parentTag = `${fullTag}-`; const nestedContext = new NestedContext(parentTag, length); help_obj[tagName] = this.parseTlv(value, nestedContext); } if ( (tagObj && !tagObj.nested && !nestedContext) || (!tagObj && !nestedContext) ) { value = str.substring(i + differ, i + differ + length); help_obj[tagName] = parseInt(value, 16); finalJson = { ...finalJson, ...help_obj }; } if ( nestedContext && nestedContext.context && nestedContext.context.parentTag && tagObj && !tagObj.nested ) { value = str.substring(i + differ, i + differ + length); help_obj[tagName] = parseInt(value, 16); help_nested = { ...help_nested, ...help_obj }; } if ( nestedContext && nestedContext.context && nestedContext.context.parentTag && tagObj && tagObj.nested ) { help_nested = { ...help_nested, ...help_obj }; } if (!nestedContext && tagObj && tagObj.nested) { finalJson = { ...finalJson, ...help_obj }; } if (!nestedContext && initialStr.length - 1 <= i + differ + length) { return finalJson; } i = i + differ + length; } if ( nestedContext && nestedContext.context && nestedContext.context.parentTag && nestedContext.context.parentLength ) { return help_nested; } } } module.exports = NodeCustomTlv;