protected virtual int LoadStep21(XbimP21Scanner parser)
{
if (Header == null)
{
Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty, this);
}
if (EntityFactory == null && _factoryResolver == null)
{
throw new XbimParserException("EntityFactory is not defined and no resolver is specified to create one. Data can't be created.");
}
parser.EntityCreate += (string name, long?label, bool header) =>
{
if (header)
{
switch (name)
{
case "FILE_DESCRIPTION":
return(Header.FileDescription);
case "FILE_NAME":
return(Header.FileName);
case "FILE_SCHEMA":
if (Header.FileSchema != null)
{
//set to new schema if it was set before from EntityFactory data
Header.FileSchema = new StepFileSchema();
}
return(Header.FileSchema);
default:
return(null);
}
}
if (EntityFactory == null)
{
EntityFactory = _factoryResolver(Header.FileSchema.Schemas);
if (EntityFactory == null)
{
throw new XbimParserException($"Entity factory resolver didn't resolve factory for schema '{string.Join(", ", Header.FileSchema.Schemas)}'");
}
InitFromEntityFactory(EntityFactory);
}
if (label == null)
{
return(EntityFactory.New(name));
}
var ent = EntityFactory.New(this, name, (int)label, true);
// if entity is null do not add so that the file load operation can survive an illegal entity
// e.g. an abstract class instantiation.
if (ent != null)
{
_instances.InternalAdd(ent);
}
else
{
var msg = $"Error in file at label {label} for type {name}.";
if (Metadata.ExpressType(name).Type.GetTypeInfo().IsAbstract)
{
msg = string.Format("Illegal element in file; cannot instantiate the abstract type {0} at label {1}.", name, label);
}
Logger?.LogError(msg);
}
//make sure that new added entities will have higher labels to avoid any clashes
if (label >= _instances.CurrentLabel)
{
_instances.CurrentLabel = (int)label;
}
return(ent);
};
try
{
parser.Parse();
//fix header with the schema if it was not a part of the data
if (Header.FileSchema.Schemas.Count == 0)
{
foreach (var s in EntityFactory.SchemasIds)
{
Header.FileSchema.Schemas.Add(s);
}
}
}
catch (Exception e)
{
var position = parser.CurrentPosition;
throw new XbimParserException(string.Format("Parser failed on line {0}, column {1}", position.EndLine, position.EndColumn), e);
}
// if the model is empty, having just a header, entity factory might still be empty
if (EntityFactory == null)
{
EntityFactory = _factoryResolver(Header.FileSchema.Schemas);
if (EntityFactory == null)
{
throw new XbimParserException($"Entity factory resolver didn't resolve factory for schema '{string.Join(", ", Header.FileSchema.Schemas)}'");
}
InitFromEntityFactory(EntityFactory);
}
//fix case if necessary
for (int i = 0; i < Header.FileSchema.Schemas.Count; i++)
{
var id = Header.FileSchema.Schemas[i];
var sid = EntityFactory.SchemasIds.FirstOrDefault(s => id.StartsWith(s, StringComparison.OrdinalIgnoreCase));
if (sid == null)
{
//add in a bit of flexibility for old Ifc models with weird schema names
var old2xSchemaNamesThatAreOK = new[] { "IFC2X2_FINAL", "IFC2X2" };
if (old2xSchemaNamesThatAreOK.FirstOrDefault(s => string.Equals(s, id, StringComparison.OrdinalIgnoreCase)) == null)
{
throw new XbimParserException("Mismatch between schema defined in the file and schemas available in the data model.");
}
else
{
sid = EntityFactory.SchemasIds.FirstOrDefault(s => string.Equals(s, "IFC2X3", StringComparison.OrdinalIgnoreCase));
}
}
//if the case is different set it to the one from entity factory
if (id != sid)
{
Header.FileSchema.Schemas[i] = sid;
}
}
return(parser.ErrorCount);
}