From 1d3d4e1b4ad24b72623190ed2b96e5029cedef16 Mon Sep 17 00:00:00 2001 From: Conor Stokes Date: Wed, 4 Oct 2023 21:47:04 +0800 Subject: [PATCH] Made parser/reference errors in nullable fields return null by default, but with an optional strict mode to enable the old behaviour --- src/ifc/ifc_command_line_main.ts | 10 +++++++++ src/step/step_entity_base.ts | 36 ++++++++++++++------------------ src/step/step_model_base.ts | 6 ++++++ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/ifc/ifc_command_line_main.ts b/src/ifc/ifc_command_line_main.ts index f8148faa..f1d2b918 100644 --- a/src/ifc/ifc_command_line_main.ts +++ b/src/ifc/ifc_command_line_main.ts @@ -72,6 +72,13 @@ function doWork() { alias: 'm', default: 128, }) + yargs2.option('strict', { + // eslint-disable-next-line max-len + describe: 'Makes parser/reference errors on nullable fields return null instead of an error', + type: 'boolean', + alias: 's', + default: false, + }) yargs2.positional('filename', { describe: 'IFC File Paths', type: 'string' }) }, async (argv) => { @@ -88,6 +95,7 @@ function doWork() { const geometry = (argv['geometry'] as boolean | undefined) const outputProperties = (argv['properties'] as boolean | undefined) + const strict = (argv['strict'] as boolean | undefined) ?? false try { indexIfcBuffer = fs.readFileSync(ifcFile) @@ -148,6 +156,8 @@ function doWork() { return } + model.nullOnErrors = !strict + if (geometry) { console.log(`Data parse time ${parseDataTimeEnd - parseDataTimeStart} ms`) // Get the filename with extension diff --git a/src/step/step_entity_base.ts b/src/step/step_entity_base.ts index d094b661..1b39099a 100644 --- a/src/step/step_entity_base.ts +++ b/src/step/step_entity_base.ts @@ -200,7 +200,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !this.model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null ) { throw new Error('Value in STEP was incorrectly typed') } @@ -240,7 +240,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !this.model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null) { throw new Error('Value in STEP was incorrectly typed') } @@ -279,7 +279,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !this.model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null) { throw new Error('Value in STEP was incorrectly typed') } @@ -319,7 +319,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !this.model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null) { throw new Error('Value in STEP was incorrectly typed') } @@ -435,16 +435,10 @@ export default abstract class StepEntityBase imple const value: Array = [] for (const address of stepExtractArray(buffer, cursor, endCursor)) { - value.push((() => { - const cursor = address - const value = this.extractBufferReference(buffer, cursor, endCursor) - /* if ( !( value instanceof IfcObjectDefinition ) ) { - throw new Error( 'Value in STEP was incorrectly typed for field' ) - }*/ + const itemValue = this.extractBufferReference(buffer, address, endCursor) - return value - })()) + value.push( itemValue ) } return value }, false) @@ -520,7 +514,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !this.model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null) { throw new Error('Value in STEP was incorrectly typed') } @@ -587,11 +581,12 @@ export default abstract class StepEntityBase imple const cursor = this.getOffsetCursor( offset ) const buffer = this.buffer const endCursor = buffer.length + const model = this.model const expressID = stepExtractReference(buffer, cursor, endCursor) const value = - expressID !== void 0 ? this.model.getElementByExpressID(expressID) : - this.model.getInlineElementByAddress( + expressID !== void 0 ? model.getElementByExpressID(expressID) : + model.getInlineElementByAddress( stepExtractInlineElemement(buffer, cursor, endCursor)) if (value === void 0) { @@ -599,7 +594,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null) { throw new Error('Value in STEP was incorrectly typed') } @@ -635,10 +630,11 @@ export default abstract class StepEntityBase imple entityConstructor: T ): InstanceType< T > | undefined { + const model = this.model const expressID = stepExtractReference( buffer, cursor, endCursor ) const value = - expressID !== void 0 ? this.model.getElementByExpressID( expressID ) : - this.model.getInlineElementByAddress( + expressID !== void 0 ? model.getElementByExpressID( expressID ) : + model.getInlineElementByAddress( stepExtractInlineElemement( buffer, cursor, endCursor ) ) if ( value === void 0 ) { @@ -680,7 +676,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !this.model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null) { throw new Error('Value in STEP was incorrectly typed') } @@ -752,7 +748,7 @@ export default abstract class StepEntityBase imple throw new Error('Value in STEP was incorrectly typed') } - if (stepExtractOptional(buffer, cursor, endCursor) !== null) { + if ( !this.model.nullOnErrors && stepExtractOptional(buffer, cursor, endCursor) !== null) { throw new Error('Value in STEP was incorrectly typed') } diff --git a/src/step/step_model_base.ts b/src/step/step_model_base.ts index 9eff1463..e619dc37 100644 --- a/src/step/step_model_base.ts +++ b/src/step/step_model_base.ts @@ -36,6 +36,12 @@ implements Iterable, Model { */ public elementMemoization: boolean = true + /** + * When an atribute is parsed from an entity in the model that causes a recoverable + * error, and the field is optional, return null instead of throwing an exception. + */ + public nullOnErrors: boolean = true + /** * Construct this step model with its matching schema, a buffer to read from and an element index. *