@mrhiden/cstruct
Version:
For packing and unpacking bytes (C like structures) in/from Buffer based on Object/Array type for parsing.
105 lines (104 loc) • 4.01 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Read = void 0;
const types_1 = require("./types");
const read_write_base_1 = require("./read-write-base");
class Read extends read_write_base_1.ReadWriteBase {
recursion(struct) {
const entries = Object.entries(struct);
for (const [modelKey, modelType] of entries) {
// Catch dynamic key
const keyDynamicGroups = this.getDynamicTypeLengthGroupsMatch(modelKey);
// Dynamic key
if (keyDynamicGroups) {
delete struct[modelKey];
const { dynamicType, dynamicLength } = keyDynamicGroups;
this.readDynamicOrStatic(struct, modelType, dynamicType, dynamicLength, modelType, dynamicType);
continue;
}
// Dynamic type
if (typeof modelType === 'string') {
// Catch dynamic type
const typeDynamicGroups = this.getDynamicTypeLengthGroupsMatch(modelType);
if (typeDynamicGroups) {
const { dynamicType, dynamicLength } = typeDynamicGroups;
this.readDynamicOrStatic(struct, dynamicType, dynamicType, dynamicLength, dynamicType, modelKey);
continue;
}
}
// Static item
this.read(struct, modelKey, modelType);
}
}
readDynamicOrStatic(struct, modelType, dynamicType, dynamicLength, readType, structKey) {
// Dynamic key
// 1 (some.i16: u8)
// 2 (some.5 : u8)
// Dynamic type
// 1 (u8.i16) (<dynamicType>.<dynamicLength>)
// 2 (u8.5) (<dynamicType>.<dynamicLength>)
const { specialType, isStatic, staticSize } = this.extractTypeAndSize(modelType, dynamicLength);
// Size, get or read
const size = isStatic
? staticSize
: this._reader.read(dynamicLength);
if (size === 0 && specialType === types_1.SpecialType.Buffer) {
throw new Error(`Buffer size can not be 0.`);
}
// Read string or wstring or buffer or json
if (specialType) {
const value = this._reader.read(readType, size);
struct[structKey] = specialType === types_1.SpecialType.Json ? JSON.parse(value) : value;
}
// Read array of itemsType
else {
this.readArray(readType, struct, structKey, size);
}
}
read(struct, modelKey, modelType) {
let structValues;
switch (typeof modelType) {
case 'object':
this.recursion(struct[modelKey]);
break;
case 'string':
if (modelType === 'buf0') {
throw new Error(`Buffer size can not be 0. (read)`);
}
structValues = this._reader.read(modelType);
if (modelType === 'j0') {
structValues = JSON.parse(structValues);
}
struct[modelKey] = structValues;
break;
default:
throw TypeError(`Unknown type "${modelType}"`);
}
}
readArray(itemsType, struct, dynamicKey, size) {
switch (typeof itemsType) {
case 'object': {
const json = JSON.stringify(itemsType);
struct[dynamicKey] = Array(size).fill(0).map(() => JSON.parse(json));
this.recursion(struct[dynamicKey]);
break;
}
case 'string':
struct[dynamicKey] = Array(size).fill(itemsType);
this.recursion(struct[dynamicKey]);
break;
default:
throw TypeError(`Unknown type "${itemsType}"`);
}
}
toStruct() {
return this._struct;
}
get size() {
return this._reader.size;
}
get offset() {
return this._reader.offset;
}
}
exports.Read = Read;