public static IStepFileHeader GetStepFileHeader(Stream stream) { var parser = new XbimP21Parser(stream, null, -1); var stepHeader = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty); parser.EntityCreate += (string name, long?label, bool header, out int[] ints) => { //allow all attributes to be parsed ints = null; if (header) { switch (name) { case "FILE_DESCRIPTION": return(stepHeader.FileDescription); case "FILE_NAME": return(stepHeader.FileName); case "FILE_SCHEMA": return(stepHeader.FileSchema); default: return(null); } } parser.Cancel = true; //done enough return(null); }; parser.Parse(); stream.Close(); return(stepHeader); }
public void StepFileHeaderVersionTest() { var model = new StepModel(new Ifc4.EntityFactoryIfc4()); var header = new StepFileHeader(StepFileHeader.HeaderCreationMode.InitWithXbimDefaults, model); Assert.IsTrue(header.FileName.OriginatingSystem == model.GetType().GetTypeInfo().Assembly.GetName().Name); Assert.IsTrue(header.FileName.PreprocessorVersion == string.Format("Processor version {0}", model.GetType().GetTypeInfo().Assembly.GetName().Version)); }
public StepModel(EntityFactoryResolverDelegate factoryResolver, ILogger logger = null, int labelFrom = 0) { Logger = logger ?? XbimLogging.CreateLogger <StepModel>(); _factoryResolver = factoryResolver; _instances = new EntityCollection(this, labelFrom); IsTransactional = true; Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty, this); ModelFactors = new XbimModelFactors(Math.PI / 180, 1e-3, 1e-5); }
private StepFileHeader ReadHeader(XmlReader input, StepFileHeader header) { var depth = input.Depth; while (input.Read()) { if (input.NodeType == XmlNodeType.EndElement && input.Depth == depth) { break; } if (input.NodeType != XmlNodeType.Element) { continue; } switch (input.LocalName.ToLowerInvariant()) { case "name": header.FileName.Name = input.ReadInnerXml(); break; case "time_stamp": header.FileName.TimeStamp = input.ReadInnerXml(); break; case "author": header.FileName.AuthorName.Add(input.ReadInnerXml()); break; case "organization": header.FileName.Organization.Add(input.ReadInnerXml()); break; case "preprocessor_version": header.FileName.PreprocessorVersion = input.ReadInnerXml(); break; case "originating_system": header.FileName.OriginatingSystem = input.ReadInnerXml(); break; case "authorization": header.FileName.AuthorizationName = input.ReadInnerXml(); break; case "documentation": header.FileDescription.Description.Add(input.ReadInnerXml()); break; } } return(header); }
public StepModel(IEntityFactory entityFactory, int labelFrom) { Logger = Logger ?? XbimLogging.CreateLogger<StepModel>(); InitFromEntityFactory(entityFactory); _instances = new EntityCollection(this, labelFrom); IsTransactional = true; ModelFactors = new XbimModelFactors(Math.PI / 180, 1e-3, 1e-5); Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.InitWithXbimDefaults, this); foreach (var schemasId in EntityFactory.SchemasIds) Header.FileSchema.Schemas.Add(schemasId); }
public static IStepFileHeader LoadStep21Header(Stream stream) { var header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty, null); var scanner = new XbimP21Scanner(stream, 1000); scanner.EntityCreate += (string name, long?label, bool inHeader) => { if (inHeader) { 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); } } else { return(null); } }; try { scanner.Parse(true); } catch (Exception e) { var position = scanner.CurrentPosition; throw new XbimParserException(string.Format("Parser failed on line {0}, column {1}", position.EndLine, position.EndColumn), e); } return(header); }
public MemoryModel(IEntityFactory entityFactory, int labelFrom = 0) { if (entityFactory == null) { throw new ArgumentNullException("entityFactory"); } _entityFactory = entityFactory; _instances = new EntityCollection(this, labelFrom); Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.InitWithXbimDefaults); foreach (var schemasId in _instances.Factory.SchemasIds) { Header.FileSchema.Schemas.Add(schemasId); } ModelFactors = new XbimModelFactors(Math.PI / 180, 1e-3, 1e-5); Metadata = ExpressMetaData.GetMetadata(entityFactory.GetType().Module); IsTransactional = true; }
internal IStepFileHeader ReadHeader() { if (Api.TryMoveFirst(Sesid, GlobalsTable)) { var hd = Api.RetrieveColumn(Sesid, GlobalsTable, IfcHeaderColumn); if (hd == null) { return(null); //there is nothing in at the moment } var br = new BinaryReader(new MemoryStream(hd)); var hdr = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty); hdr.Read(br); return(hdr); } else { return(null); } }
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); }
public StepFileHeader Read(Stream xmlStream) { // using (var xmlInStream = new StreamReader(inputStream, Encoding.GetEncoding("ISO-8859-9"))) //this is a work around to ensure latin character sets are read using (var input = XmlReader.Create(xmlStream)) { _streamSize = xmlStream.Length; // Read until end of file _idMap = new Dictionary <string, int>(); _lastId = 0; _entitiesParsed = 0; var foundHeader = false; var header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty); //IFC2x3 was the first IFC mapped to XML so IFC version wasn't explicit. So we need to put it in to keep the data complete header.FileSchema.Schemas.Add("IFC2X3"); var headerId = ""; while (_currentNode == null && input.Read()) //read through to UOS { switch (input.NodeType) { case XmlNodeType.Element: if (String.Compare(input.LocalName, "uos", StringComparison.OrdinalIgnoreCase) == 0) { _currentNode = new XmlUosCollection(); } else if ( String.Compare(input.LocalName, "iso_10303_28", StringComparison.OrdinalIgnoreCase) == 0) { foundHeader = true; if (!string.IsNullOrWhiteSpace(input.Prefix)) { _expressNamespace = input.Prefix; _cTypeAttribute = _expressNamespace + ":cType"; _posAttribute = _expressNamespace + ":pos"; _expressNamespace += ":"; } else { _cTypeAttribute = "cType"; _posAttribute = "pos"; } //correct the values if the namespace is defined correctly while (input.MoveToNextAttribute()) { if (input.Value == "urn:oid:1.0.10303.28.2.1.1" || input.Value == "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common") { _expressNamespace = input.LocalName; _cTypeAttribute = _expressNamespace + ":cType"; _posAttribute = _expressNamespace + ":pos"; _expressNamespace += ":"; break; } } } else { headerId = input.LocalName.ToLower(); } break; case XmlNodeType.Text: switch (headerId) { case "name": header.FileName.Name = input.Value; break; case "time_stamp": header.FileName.TimeStamp = input.Value; break; case "author": header.FileName.AuthorName.Add(input.Value); break; case "organization": header.FileName.Organization.Add(input.Value); break; case "preprocessor_version": header.FileName.PreprocessorVersion = input.Value; break; case "originating_system": header.FileName.OriginatingSystem = input.Value; break; case "authorization": header.FileName.AuthorizationName = input.Value; break; case "documentation": header.FileDescription.Description.Add(input.Value); break; } break; } } if (!foundHeader) { throw new Exception("Invalid XML format, iso_10303_28 tag not found"); } var prevInputType = XmlNodeType.None; var prevInputName = ""; // set counter for start of every element that is not empty, and reduce it on every end of that element try { while (input.Read()) { if (_streamSize != -1 && ProgressStatus != null) { double pos = xmlStream.Position; var newPercentage = Convert.ToInt32(pos / _streamSize * 100.0); if (newPercentage > _percentageParsed) { ProgressStatus(_percentageParsed, "Parsing"); _percentageParsed = newPercentage; } } switch (input.NodeType) { case XmlNodeType.Element: StartElement(input); break; case XmlNodeType.EndElement: IPersistEntity toWrite; //if toWrite has a value we have completed an Ifc Entity EndElement(input, prevInputType, prevInputName, out toWrite); if (toWrite != null) { _entitiesParsed++; _finish(toWrite); } break; case XmlNodeType.Whitespace: SetValue(input, prevInputType); break; case XmlNodeType.Text: SetValue(input, prevInputType); break; } prevInputType = input.NodeType; prevInputName = input.LocalName; } } catch (Exception e) { throw new Exception( String.Format("Error reading XML, Line={0}, Position={1}, Tag='{2}'", ((IXmlLineInfo)input).LineNumber, ((IXmlLineInfo)input).LinePosition, input.LocalName), e); } if (ProgressStatus != null) { ProgressStatus(100, "Parsing"); } return(header); } }
public StepFileHeader Read(Stream xmlStream, bool onlyHeader = false) { // using (var xmlInStream = new StreamReader(inputStream, Encoding.GetEncoding("ISO-8859-9"))) //this is a work around to ensure Latin character sets are read using (var input = XmlReader.Create(xmlStream)) { _streamSize = xmlStream.Length; _idMap = new Dictionary <string, int>(); var header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty); var rootElement = true; var headerElement = true; while (input.Read()) { //skip everything except for element nodes if (input.NodeType != XmlNodeType.Element) { continue; } if (rootElement) { ReadSchemaInHeader(input, header); rootElement = false; continue; } if (headerElement) { //header is the first inner node if defined (it is optional) var name = input.LocalName.ToLowerInvariant(); if ((name == "header" || name == "iso_10303_28_header") && !input.IsEmptyElement) { header = ReadHeader(input, header); } headerElement = false; continue; } //if this is IFC2x3 file and we only need the header we need to make sure we read schema information from "uos" element if (input.LocalName == "uos") { ReadSchemaInHeader(input, header); } if (onlyHeader) { return(header); } //process all root entities in the file (that has to be IPersistEntity) ReadEntity(input); if (_streamSize != -1 && ProgressStatus != null) { double pos = xmlStream.Position; var newPercentage = Convert.ToInt32(pos / _streamSize * 100.0); if (newPercentage > _percentageParsed) { ProgressStatus(_percentageParsed, "Parsing"); _percentageParsed = newPercentage; } } } if (ProgressStatus != null) { ProgressStatus(100, "Parsing"); } return(header); } }
/// <summary> /// Opens the model from STEP21 file. /// </summary> /// <param name="stream">Path to the file</param> /// <param name="streamSize"></param> /// <param name="progDelegate"></param> /// <returns>Number of errors in parsing. Always check this to be null or the model might be incomplete.</returns> public virtual int LoadStep21(Stream stream, long streamSize, ReportProgressDelegate progDelegate = null) { var parser = new XbimP21Parser(stream, Metadata, streamSize); if (progDelegate != null) { parser.ProgressStatus += progDelegate; } var first = true; Header = new StepFileHeader(StepFileHeader.HeaderCreationMode.LeaveEmpty); parser.EntityCreate += (string name, long?label, bool header, out int[] ints) => { //allow all attributes to be parsed ints = null; if (header) { switch (name) { case "FILE_DESCRIPTION": return(Header.FileDescription); case "FILE_NAME": return(Header.FileName); case "FILE_SCHEMA": return(Header.FileSchema); default: return(null); } } if (label == null) { return(_instances.Factory.New(name)); } //if this is a first non-header entity header is read completely by now. //So we should check if the schema declared in the file is the one declared in EntityFactory if (first) { first = false; if (!Header.FileSchema.Schemas.All(s => _instances.Factory.SchemasIds.Contains(s))) { throw new Exception("Mismatch between schema defined in the file and schemas available in the data model."); } } var typeId = Metadata.ExpressTypeId(name); var ent = _instances.Factory.New(this, typeId, (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(typeId).Type.IsAbstract) { msg = $"Illegal element in file; cannot instantiate the abstract type {name} at label {label}."; } Log.Error(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); }; parser.Parse(); if (progDelegate != null) { parser.ProgressStatus -= progDelegate; } return(parser.ErrorCount); }