diff --git a/src/common.ts b/src/common.ts index e996743..40650bb 100644 --- a/src/common.ts +++ b/src/common.ts @@ -82,4 +82,41 @@ export function assertSize(name: string, size: number, isDefined: boolean) { } // Return return out; +} +export function safeParseInt(str: string) { + const x = parseInt(str); + if (isNaN(x)) { + throw new Error('Invalid Integer: ' + str); + } + return x; +} +export function stripArrayData(propertyName: string) { + const index = propertyName.indexOf('['); + if (index !== -1) { + propertyName = propertyName.substring(0, index); + } + return propertyName; +} +export function getSizeMultiplierFromArrayData(propertyName: string) { + let multiplier = 1; + // Check If Array Data Is Present + const index = propertyName.indexOf('['); + if (index === -1) { + return multiplier; + } + propertyName = propertyName.substring(index + 1); + // Strip Last ] + if (!propertyName.endsWith(']')) { + syntaxError('Expecting ]'); + } else { + propertyName = propertyName.substring(0, propertyName.length - 1); + } + // Split + const parts = propertyName.split(']['); + // Calculate Multiplier + for (const part of parts) { + multiplier *= safeParseInt(part); + } + // Return + return multiplier; } \ No newline at end of file diff --git a/src/loader.ts b/src/loader.ts index f0d6025..af19d5f 100644 --- a/src/loader.ts +++ b/src/loader.ts @@ -1,17 +1,10 @@ -import { COMMENT, EXTENSION, parseTypeAndName, readDefinition, syntaxError } from './common'; +import { COMMENT, EXTENSION, parseTypeAndName, readDefinition, safeParseInt, syntaxError } from './common'; import { isCppAllowed } from './map'; import { Method } from './method'; import { SimpleProperty, StaticProperty } from './property'; import { Struct } from './struct'; // Error Handling -function safeParseInt(str: string) { - const x = parseInt(str); - if (isNaN(x)) { - throw new Error('Invalid Integer: ' + str); - } - return x; -} export class ErrorOnLine { readonly error: unknown; readonly file: string; diff --git a/src/property.ts b/src/property.ts index 28fa3da..cc35c85 100644 --- a/src/property.ts +++ b/src/property.ts @@ -1,4 +1,4 @@ -import { POINTER_SIZE } from './common'; +import { POINTER_SIZE, getSizeMultiplierFromArrayData } from './common'; import { getStructure } from './map'; export interface Property { @@ -13,12 +13,14 @@ export class SimpleProperty implements Property { readonly #offset: number; readonly #type: string; readonly #name: string; + readonly #arraySizeMultiplier: number; // Constructor constructor(offset: number, type: string, name: string) { this.#offset = offset; this.#type = type; this.#name = name; + this.#arraySizeMultiplier = getSizeMultiplierFromArrayData(this.#name); } // Getters @@ -33,7 +35,7 @@ export class SimpleProperty implements Property { } // Size - propertySize() { + #rawPropertySize() { if (this.#type.endsWith('*')) { // Pointer return POINTER_SIZE; @@ -64,6 +66,9 @@ export class SimpleProperty implements Property { return structure.getSize(true); } } + propertySize() { + return this.#arraySizeMultiplier * this.#rawPropertySize(); + } // Alignment propertyAlignment() { @@ -108,6 +113,9 @@ export class StaticProperty { // Constructor constructor(address: number, type: string, name: string, self: string, isArray: boolean) { + if (name.includes('[')) { + throw new Error('Use "static-property-array" For Arrays'); + } this.address = address; this.#type = type; this.#name = name; diff --git a/src/struct.ts b/src/struct.ts index 0abf1df..a27ea0f 100644 --- a/src/struct.ts +++ b/src/struct.ts @@ -1,4 +1,4 @@ -import { INDENT, MIN_SIZE, formatType, STRUCTURE_FILES, toHex, getAssertFunction, assertSize } from './common'; +import { INDENT, MIN_SIZE, formatType, STRUCTURE_FILES, toHex, getAssertFunction, assertSize, stripArrayData } from './common'; import { Method } from './method'; import { Property, StaticProperty } from './property'; import { VTable } from './vtable'; @@ -245,7 +245,7 @@ export class Struct { const assertFunction = getAssertFunction(); for (let i = 0; i < this.#properties.length; i++) { const property = this.#properties[i]!; - const name = property.propertyName(); + const name = stripArrayData(property.propertyName()); const offset = property.propertyOffset(); out += `${assertFunction}(offsetof(${this.#name}, ${name}) == ${toHex(offset)}, "Invalid Offset");\n`; }