Skip to content

Commit

Permalink
Fix Nested Arrays Parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
beachtom committed Apr 28, 2023
1 parent 88e83bb commit f2c680c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 97 deletions.
1 change: 1 addition & 0 deletions src/ifc-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1166,6 +1166,7 @@ export const TypeInitialisers: any = {};
/** @ignore */
export const SchemaNames: Array<string> = [];
function TypeInitialiser(schema:number,tapeItem:any) {
if (Array.isArray(tapeItem)) tapeItem.map((p:any) => TypeInitialiser(schema,p));
if (tapeItem.typecode) return TypeInitialisers[schema][tapeItem.typecode](tapeItem.value); else return tapeItem.value;
}
function Labelise(tapeItem:any) {
Expand Down
1 change: 1 addition & 0 deletions src/schema-generator/gen_functional_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ tsSchema.push(`export const SchemaNames: Array<string> = [];`);


tsSchema.push('function TypeInitialiser(schema:number,tapeItem:any) {');
tsSchema.push('\tif (Array.isArray(tapeItem)) tapeItem.map((p:any) => TypeInitialiser(schema,p));');
tsSchema.push('\tif (tapeItem.typecode) return TypeInitialisers[schema][tapeItem.typecode](tapeItem.value); else return tapeItem.value;');
tsSchema.push('}');
tsSchema.push('function Labelise(tapeItem:any) {');
Expand Down
4 changes: 2 additions & 2 deletions src/wasm/schema/schema-functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ namespace webifc::schema {
_schemas.push_back(IFC4);
_schemaNames.push_back("IFC4X3");
_schemas.push_back(IFC4X3);
};
}
std::string IfcSchemaManager::IfcTypeCodeToType(uint32_t typeCode) const {
switch(typeCode) {
case schema::FILE_SCHEMA: return "FILE_SCHEMA";
Expand Down Expand Up @@ -1390,4 +1390,4 @@ namespace webifc::schema {
default: return "<web-ifc-type-unknown>";
}
}
};
}
147 changes: 55 additions & 92 deletions src/wasm/web-ifc-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -704,109 +704,75 @@ emscripten::val ReadValue(uint32_t modelID, webifc::parsing::IfcTokenType t)
}
}

emscripten::val& GetArgs(uint32_t modelID, emscripten::val& arguments)
emscripten::val GetArgs(uint32_t modelID, bool inObject=false)
{
auto loader = models[modelID].GetLoader();
std::stack<emscripten::val> valueStack;
std::stack<int> valuePosition;

valueStack.push(arguments);
valuePosition.push(0);

auto arguments = emscripten::val::array();
size_t size = 0;
bool endOfLine = false;
while (!loader->IsAtEnd() && !endOfLine)
{
webifc::parsing::IfcTokenType t = loader->GetTokenType();

auto& topValue = valueStack.top();
auto& topPosition = valuePosition.top();

switch (t)
{
case webifc::parsing::IfcTokenType::LINE_END:
{
endOfLine = true;
break;
}
case webifc::parsing::IfcTokenType::EMPTY:
{
topValue.set(topPosition++, emscripten::val::null());

break;
}
case webifc::parsing::IfcTokenType::SET_BEGIN:
{
auto newValue = emscripten::val::array();

valueStack.push(newValue);
valuePosition.push(0);

break;
}
case webifc::parsing::IfcTokenType::SET_END:
{
if (valueStack.size() == 1)
case webifc::parsing::IfcTokenType::LINE_END:
{
// this is a pop just before endline, so ignore
endOfLine = true;
break;
}
else
case webifc::parsing::IfcTokenType::EMPTY:
{
auto topCopy = valueStack.top();

valueStack.pop();
valuePosition.pop();
auto& parent = valueStack.top();
int& parentCount = valuePosition.top();
parent.set(parentCount++, topCopy);
arguments.set(size++,emscripten::val::null());
break;
}

break;
}
case webifc::parsing::IfcTokenType::LABEL:
{
// read label
auto obj = emscripten::val::object();
obj.set("type", emscripten::val(static_cast<uint32_t>(webifc::parsing::IfcTokenType::LABEL)));
loader->StepBack();
auto s=loader->GetStringArgument();
auto typeCode = schemaManager.IfcTypeToTypeCode(s);
obj.set("typecode", emscripten::val(typeCode));
// read set open
loader->GetTokenType();

// read value following label
webifc::parsing::IfcTokenType t = loader->GetTokenType();
loader->StepBack();
obj.set("value", ReadValue(modelID,t));

// read set close
loader->GetTokenType();

topValue.set(topPosition++, obj);

break;
}
case webifc::parsing::IfcTokenType::STRING:
case webifc::parsing::IfcTokenType::ENUM:
case webifc::parsing::IfcTokenType::REAL:
case webifc::parsing::IfcTokenType::REF:
{

auto obj = emscripten::val::object();
loader->StepBack();
obj.set("type", emscripten::val(static_cast<uint32_t>(t)));
obj.set("value", ReadValue(modelID,t));

topValue.set(topPosition++, obj);

break;
}
default:
break;
case webifc::parsing::IfcTokenType::SET_BEGIN:
{
arguments.set(size++,GetArgs(modelID));
break;
}
case webifc::parsing::IfcTokenType::SET_END:
{
endOfLine = true;
break;
}
case webifc::parsing::IfcTokenType::LABEL:
{
// read label
auto obj = emscripten::val::object();
obj.set("type", emscripten::val(static_cast<uint32_t>(webifc::parsing::IfcTokenType::LABEL)));
loader->StepBack();
auto s=loader->GetStringArgument();
auto typeCode = schemaManager.IfcTypeToTypeCode(s);
obj.set("typecode", emscripten::val(typeCode));
// read set open
loader->GetTokenType();
obj.set("value", GetArgs(modelID,true));
arguments.set(size++, obj);
break;
}
case webifc::parsing::IfcTokenType::STRING:
case webifc::parsing::IfcTokenType::ENUM:
case webifc::parsing::IfcTokenType::REAL:
case webifc::parsing::IfcTokenType::REF:
{
loader->StepBack();
emscripten::val obj;
if (inObject) obj = ReadValue(modelID,t);
else {
obj = emscripten::val::object();
obj.set("type", emscripten::val(static_cast<uint32_t>(t)));
obj.set("value", ReadValue(modelID,t));
}
arguments.set(size++, obj);
break;
}
default:
break;
}
}

if (size == 0) return emscripten::val::null();
if (size == 1 && inObject) return arguments[0];
return arguments;
}

Expand All @@ -825,9 +791,8 @@ emscripten::val GetHeaderLine(uint32_t modelID, uint32_t headerType)
auto line = lines[0];
loader->MoveToHeaderLineArgument(line.lineIndex, 0);

auto arguments = emscripten::val::array();
std::string s(schemaManager.IfcTypeCodeToType(line.ifcType));
GetArgs(modelID, arguments);
auto arguments = GetArgs(modelID);
auto retVal = emscripten::val::object();
retVal.set("ID", line.lineIndex);
retVal.set("type", s);
Expand All @@ -847,9 +812,7 @@ emscripten::val GetLine(uint32_t modelID, uint32_t expressID)

loader->MoveToArgumentOffset(line, 0);

auto arguments = emscripten::val::array();

GetArgs(modelID, arguments);
auto arguments = GetArgs(modelID);

auto retVal = emscripten::val::object();
retVal.set(emscripten::val("ID"), line.expressID);
Expand Down
7 changes: 4 additions & 3 deletions src/web-ifc-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,15 @@ export class IfcAPI {
dest.set(src);
return srcSize;
});
this.modelSchemaList[result] = SchemaNames.indexOf(this.GetHeaderLine(result, FILE_SCHEMA).arguments[0][0].value);
var schemaName = this.GetHeaderLine(result, FILE_SCHEMA).arguments[0][0].value;
this.modelSchemaList[result] = SchemaNames.indexOf(schemaName);
if (this.modelSchemaList[result] == -1)
{
Log.error("Unsupported Schema:"+this.GetHeaderLine(result, FILE_SCHEMA).arguments[0][0].value);
Log.error("Unsupported Schema:"+schemaName);
this.CloseModel(result)
return -1;
}
Log.info("Parsing Model using " + this.GetHeaderLine(result, FILE_SCHEMA).arguments[0][0].value + " Schema");
Log.info("Parsing Model using " + schemaName + " Schema");
return result;
}

Expand Down

0 comments on commit f2c680c

Please sign in to comment.