UNPKG

@mrhiden/cstruct

Version:

For packing and unpacking bytes (C like structures) in/from Buffer based on Object/Array type for parsing.

117 lines (116 loc) 4.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Make = void 0; const types_1 = require("./types"); const read_write_base_1 = require("./read-write-base"); class Make extends read_write_base_1.ReadWriteBase { recursion(model, struct) { const entries = Object.entries(model); for (const [modelKey, modelType] of entries) { // Catch key.length const keyLengthGroups = this.getDynamicTypeLengthGroupsMatch(modelKey); // Dynamic key if (keyLengthGroups) { const { dynamicType, dynamicLength } = keyLengthGroups; this.writDynamicOrStatic(struct, modelType, dynamicLength, dynamicType, modelType); continue; } // Dynamic type if (typeof modelType === 'string') { // Catch dynamic type const typeDynamicGroups = this.getDynamicTypeLengthGroupsMatch(modelType); if (typeDynamicGroups) { const { dynamicType, dynamicLength } = typeDynamicGroups; this.writDynamicOrStatic(struct, dynamicType, dynamicLength, modelKey, dynamicType); continue; } } // Static item this.write(model, struct, modelKey, modelType); } } writDynamicOrStatic(struct, modelType, dynamicLength, structKey, writeType) { // Dynamic key // Dyn (some.i16: u8) (<dynamicType>.<dynamicLength>: <modelType>) data = {abc: 'j[i8]'} modelType = u8 // Sta (some.5 : u8) (<dynamicType>.<dynamicLength>: <modelType>) data = {abc: 'j[9]'} modelType = u8 // Dynamic type // Dyn (u8.i16) (<dynamicType>.<dynamicLength>) data = ['j[i8]'] modelType = u8 // Sta (u8.5) (<dynamicType>.<dynamicLength>) data = ['j[9]'] modelType = u8 const { specialType, isStatic, staticSize } = this.extractTypeAndSize(modelType, dynamicLength); let structValues = struct[structKey]; if (specialType === types_1.SpecialType.Json) { structValues = JSON.stringify(structValues); } if (isStatic && staticSize !== 0 && structValues.length > staticSize && specialType !== types_1.SpecialType.String) { throw new Error(`Size of value ${structValues.length} is greater than ${staticSize}.`); } const size = isStatic ? staticSize : structValues.length; if (size === 0 && specialType === types_1.SpecialType.Buffer) { throw new Error(`Buffer size can not be 0.`); } // Dynamic, write size before value if (!isStatic) { this._writer.write(dynamicLength, size); } // Write string or buffer or json if (specialType) { // this._writer.write(writeType, structValues, isStatic && (passSize || size === 0) ? size : undefined); this._writer.write(writeType, structValues, isStatic ? size : undefined); } // Write array of writeType else { this.writeArray(writeType, structValues); } } write(model, struct, modelKey, modelType) { let structValues; switch (typeof modelType) { case 'object': this.recursion(model[modelKey], struct[modelKey]); break; case 'string': if (modelType === 'buf0') { throw new Error(`Buffer size can not be 0. (make)`); } structValues = struct[modelKey]; if (modelType === 'j0') { structValues = JSON.stringify(structValues); } this._writer.write(modelType, structValues); break; default: throw TypeError(`Unknown type "${modelType}"`); } } writeArray(itemsType, structValues) { switch (typeof itemsType) { case 'object': for (const structValue of structValues) { this.recursion(itemsType, structValue); } break; case 'string': for (const structValue of structValues) { this._writer.write(itemsType, structValue); } break; default: throw TypeError(`Unknown type "${itemsType}"`); } } toBuffer() { return this._writer.toBuffer(); } get offset() { return this._writer.size; } get size() { return this._writer.size; } getBufferAndOffset() { return [this.toBuffer(), this.offset]; } } exports.Make = Make;