Example #1
0
        public void Reset()
        {
            currentEntityLabel = 0;
            currentModelIndex  = 0;
            XbimModel first = models.FirstOrDefault();

            if (first != null)
            {
                cache       = first.Cache;
                this.cursor = cache.GetEntityTable();
                cursor.MoveBeforeFirst();
            }
        }
Example #2
0
 internal P21toIndexParser(Stream inputP21, XbimEntityCursor table, IfcPersistedInstanceCache cache, int codePageOverride = -1)
     : base(inputP21)
 {
     this.table = table;
     //  this.transaction = transaction;
     this.modelCache = cache;
     _entityCount    = 0;
     if (inputP21.CanSeek)
     {
         _streamSize = inputP21.Length;
     }
     _codePageOverride = codePageOverride;
 }
Example #3
0
        bool IEnumerator.MoveNext()
        {
            int label;

            if (cursor.TryMoveNextLabel(out label))
            {
                currentEntityLabel = label;
                return(true);
            }
            else if (currentModelIndex < models.Count - 1) //we have more models to process
            {
                currentModelIndex++;                       //go to next model
                cache.FreeTable(cursor);
                cache       = models[currentModelIndex].Cache;
                this.cursor = cache.GetEntityTable();
                cursor.MoveBeforeFirst();
                if (cursor.TryMoveNextLabel(out label))
                {
                    currentEntityLabel = label;
                    return(true);
                }
            }
            return(false);
        }
 internal XbimInstanceCollection(XbimModel xbimModel)
 {
     this.xbimModel = xbimModel;
     cache          = xbimModel.Cache;
 }
        /// <summary>
        /// Populates an entites properties from the binary stream
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cache"></param>
        /// <param name="br"></param>
        /// <param name="unCached">If true instances inside the properties are not added to the cache</param>
        /// <param name="fromCache"> If true the instance is read from the cache if not present it is created, used during parsing
        public static void ReadEntityProperties(this IPersistIfcEntity entity, IfcPersistedInstanceCache cache, BinaryReader br, bool unCached = false,bool fromCache = false)
        {
            P21ParseAction action = (P21ParseAction)br.ReadByte();

            XbimParserState parserState = new XbimParserState(entity);
            while (action != P21ParseAction.EndEntity)
            {
                switch (action)
                {
                    case P21ParseAction.BeginList:
                        parserState.BeginList();
                        break;
                    case P21ParseAction.EndList:
                        parserState.EndList();
                        break;
                    case P21ParseAction.BeginComplex:
                        break;
                    case P21ParseAction.EndComplex:
                        break;
                    case P21ParseAction.SetIntegerValue:
                        parserState.SetIntegerValue(br.ReadInt64());
                        break;
                    case P21ParseAction.SetHexValue:
                        parserState.SetHexValue(br.ReadInt64());
                        break;
                    case P21ParseAction.SetFloatValue:
                        parserState.SetFloatValue(br.ReadDouble());
                        break;
                    case P21ParseAction.SetStringValue:
                        parserState.SetStringValue(br.ReadString());
                        break;
                    case P21ParseAction.SetEnumValue:
                        parserState.SetEnumValue(br.ReadString());
                        break;
                    case P21ParseAction.SetBooleanValue:
                        parserState.SetBooleanValue(br.ReadBoolean());
                        break;
                    case P21ParseAction.SetNonDefinedValue:
                        parserState.SetNonDefinedValue();
                        break;
                    case P21ParseAction.SetOverrideValue:
                        parserState.SetOverrideValue();
                        break;
                    case P21ParseAction.SetObjectValueUInt16:
                        if (fromCache)
                        {
                            int label = br.ReadUInt16();
                            IPersistIfcEntity refEntity;
                            if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity)) //if we are in a list then make a forward reference anyway to make sure we maintain list order
                                parserState.SetObjectValue(refEntity);
                            else
                            {
                                cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                                parserState.SkipProperty();
                            }
                        }
                        else
                            parserState.SetObjectValue(cache.GetInstance(br.ReadUInt16(), false, unCached));
                        break;
                    case P21ParseAction.SetObjectValueInt32:
                        if (fromCache)
                        {
                            int label = br.ReadInt32();
                            IPersistIfcEntity refEntity;
                            if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity)) //if we are in a list then make a forward reference anyway to make sure we maintain list order
                                parserState.SetObjectValue(refEntity);
                            else
                            {
                                cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                                parserState.SkipProperty();
                            }
                        }
                        else
                            parserState.SetObjectValue(cache.GetInstance(br.ReadInt32(), false, unCached));
                        break;
                    case P21ParseAction.SetObjectValueInt64:
                        throw new XbimException("Entity Label is int64, this is not currently supported");
                        //parserState.SetObjectValue(cache.GetInstance(br.ReadInt64(), false, unCached));
                        //break;
                    case P21ParseAction.BeginNestedType:
                        parserState.BeginNestedType(br.ReadString());
                        break;
                    case P21ParseAction.EndNestedType:
                        parserState.EndNestedType();
                        break;
                    case P21ParseAction.EndEntity:
                        parserState.EndEntity();
                        break;
                    case P21ParseAction.NewEntity:
                        parserState = new XbimParserState(entity);
                        break;
                    default:
                        throw new XbimException("Invalid Property Record #" + entity.EntityLabel + " EntityType: " + entity.GetType().Name);
                }
                action = (P21ParseAction)br.ReadByte();
            }
        }
Example #6
0
        internal IfcFileHeader Read(IfcPersistedInstanceCache instanceCache, XbimEntityCursor entityTable, XmlReader input)
        {
            // Read until end of file
            idMap           = new Dictionary <string, int>();
            lastId          = 0;
            _entitiesParsed = 0;
            bool          foundHeader = false;
            IfcFileHeader header      = new IfcFileHeader(IfcFileHeader.HeaderCreationMode.LeaveEmpty);
            string        headerId    = "";

            while (_currentNode == null && input.Read()) //read through to UOS
            {
                switch (input.NodeType)
                {
                case XmlNodeType.Element:
                    if (string.Compare(input.LocalName, "uos", true) == 0)
                    {
                        _currentNode = new XmlUosCollection();
                    }
                    else if (string.Compare(input.LocalName, "iso_10303_28", true) == 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;

                    default:
                        break;
                    }
                    break;

                default:
                    break;
                }
            }
            if (!foundHeader)
            {
                throw new Exception("Invalid XML format, iso_10303_28 tag not found");
            }

            XmlNodeType prevInputType = XmlNodeType.None;
            string      prevInputName = "";

            // set counter for start of every element that is not empty, and reduce it on every end of that element



            try
            {
                using (var transaction = entityTable.BeginLazyTransaction())
                {
                    // this will create id of each element
                    Dictionary <string, int> ids = new Dictionary <string, int>();
                    while (input.Read())
                    {
                        switch (input.NodeType)
                        {
                        case XmlNodeType.Element:
                            StartElement(instanceCache, input, entityTable, transaction);
                            break;

                        case XmlNodeType.EndElement:
                            IPersistIfcEntity toWrite;
                            //if toWrite has a value we have completed an Ifc Entity
                            EndElement(input, prevInputType, prevInputName, out toWrite);
                            if (toWrite != null)
                            {
                                _entitiesParsed++;
                                //now write the entity to the database
                                entityTable.AddEntity(toWrite);
                                if (_entitiesParsed % _transactionBatchSize == (_transactionBatchSize - 1))
                                {
                                    transaction.Commit();
                                    transaction.Begin();
                                }
                            }
                            break;

                        case XmlNodeType.Whitespace:
                            SetValue(input, prevInputType, prevInputName);
                            break;

                        case XmlNodeType.Text:
                            SetValue(input, prevInputType, prevInputName);
                            break;

                        default:
                            break;
                        }
                        prevInputType = input.NodeType;
                        prevInputName = input.LocalName;
                    }
                    transaction.Commit();
                }
            }
            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);
            }
            return(header);
        }
Example #7
0
        private void StartElement(IfcPersistedInstanceCache cache, XmlReader input, XbimEntityCursor entityTable, XbimLazyDBTransaction transaction)
        {
            string elementName = input.LocalName;
            bool   isRefType;
            int?   id = GetId(input, out isRefType);

            IfcType ifcType;

            IfcParserType   parserType;
            IfcMetaProperty prop;
            int             propIndex;


            if (id.HasValue && IsIfcEntity(elementName, out ifcType)) //we have an element which is an Ifc Entity
            {
                IPersistIfcEntity ent;
                if (!cache.Contains(id.Value))
                {
                    // not been declared in a ref yet
                    // model.New creates an instance uisng type and id
                    ent = cache.CreateNew(ifcType.Type, id.Value);
                }
                else
                {
                    ent = cache.GetInstance(id.Value, false, true);
                }

                XmlEntity xmlEnt = new XmlEntity(_currentNode, ent);

                //if we have a completely empty element that is not a ref we need to make sure it is written to the database as EndElement will not be called
                if (input.IsEmptyElement && !isRefType)
                {
                    _entitiesParsed++;
                    //now write the entity to the database
                    entityTable.AddEntity(xmlEnt.Entity);
                    if (_entitiesParsed % _transactionBatchSize == (_transactionBatchSize - 1))
                    {
                        transaction.Commit();
                        transaction.Begin();
                    }
                }


                string pos = input.GetAttribute(_posAttribute);
                if (string.IsNullOrEmpty(pos))
                {
                    pos = input.GetAttribute("pos");                            //try without namespace
                }
                if (!string.IsNullOrEmpty(pos))
                {
                    xmlEnt.Position = Convert.ToInt32(pos);
                }
                if (!input.IsEmptyElement)
                {
                    // add the entity to its parent if its parent is a list
                    //if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    //    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);

                    _currentNode = xmlEnt;
                }
                else if (_currentNode is XmlProperty)
                {
                    // if it is a ref then it will be empty element and wont have an end tag
                    // so nither SetValue nor EndElement will be called, so set the value of ref here e.g. #3
                    ((XmlProperty)(_currentNode)).SetValue(ent);
                }
                else if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);
                }
            }
            else if (input.IsEmptyElement)
            {
                if (IsIfcProperty(elementName, out propIndex, out prop))
                {
                    XmlProperty   node    = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);;
                    PropertyValue propVal = new PropertyValue();
                    Type          t       = node.Property.PropertyType;

                    if (!typeof(ExpressEnumerable).IsAssignableFrom(t)) // if its a empty collection then dont do anything
                    {
                        if (t != null && t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable <>)))
                        {
                            t = Nullable.GetUnderlyingType(t);
                        }
                        ExpressType et = null;
                        if (t != null && typeof(ExpressType).IsAssignableFrom(t))
                        {
                            et = (ExpressType)(Activator.CreateInstance(t));
                        }

                        IfcParserType pt;
                        if (et != null)
                        {
                            pt = primitives[et.UnderlyingSystemType.Name];
                        }
                        else
                        {
                            if (t.IsEnum)
                            {
                                pt = IfcParserType.Enum;
                            }
                            else
                            {
                                pt = primitives[t.Name];
                            }
                        }

                        if (pt.ToString().ToLower() == "string")
                        {
                            propVal.Init("'" + input.Value + "'", pt);
                        }
                        else
                        {
                            if (pt.ToString().ToLower() == "boolean")
                            {
                                propVal.Init(Convert.ToBoolean(input.Value) ? ".T." : ".F", pt);
                            }
                            else
                            {
                                propVal.Init(input.Value, pt);
                            }
                        }
                        ((XmlEntity)node.Parent).Entity.IfcParse(node.PropertyIndex - 1, propVal);
                    }
                }
                else if (IsIfcType(elementName, out ifcType))
                {
                    IPersistIfc ent;
                    object[]    param = new object[1];
                    param[0] = ""; // empty element
                    ent      = (IPersistIfc)Activator.CreateInstance(ifcType.Type, param);

                    ((XmlProperty)_currentNode).SetValue(ent);
                }

                return;
            }
            else if (!id.HasValue && IsIfcProperty(elementName, out propIndex, out prop)) //we have an element which is a property
            {
                string cType = input.GetAttribute(_cTypeAttribute);
                if (string.IsNullOrEmpty(cType))
                {
                    cType = input.GetAttribute("cType"); //in case namespace omitted
                }
                if (IsCollection(prop))                  //the property is a collection
                {
                    XmlCollectionProperty xmlColl = new XmlCollectionProperty(_currentNode, prop.PropertyInfo, propIndex);
                    switch (cType)
                    {
                    case "list":
                        xmlColl.CType = CollectionType.List;
                        break;

                    case "list-unique":
                        xmlColl.CType = CollectionType.ListUnique;
                        break;

                    case "set":
                        xmlColl.CType = CollectionType.Set;
                        break;

                    default:
                        xmlColl.CType = CollectionType.List;
                        break;
                    }

                    _currentNode = xmlColl;
                }
                else //it is a simple value property;
                {
                    // its parent can be a collection, if yes then this property needs to be added to parent
                    XmlNode n = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);
                    if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    {
                        ((XmlCollectionProperty)_currentNode).Entities.Add(n);
                    }

                    if (!input.IsEmptyElement)
                    {
                        _currentNode = n;
                    }
                }
            }
            else if (!id.HasValue && IsIfcType(elementName, out ifcType)) // we have an Ifc ExpressType
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlExpressType(_currentNode, ifcType.Type);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);
                }

                if (!input.IsEmptyElement)
                {
                    _currentNode = n;
                }
            }
            else if (!id.HasValue && IsPrimitiveType(elementName, out parserType)) // we have an basic type i.e. double, bool etc
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlBasicType(_currentNode, parserType);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);
                }

                if (!input.IsEmptyElement)
                {
                    _currentNode = n;
                }
            }
            else
            {
                throw new Exception("Illegal XML element tag");
            }
        }
 internal P21toIndexParser(Stream inputP21,  XbimEntityCursor table,  IfcPersistedInstanceCache cache, int codePageOverride = -1)
     : base(inputP21)
 {
     this.table = table;
       //  this.transaction = transaction;
     this.modelCache = cache;
     _entityCount = 0;
     if (inputP21.CanSeek)
         _streamSize = inputP21.Length;
     _codePageOverride = codePageOverride;
 }
Example #9
0
 public XbimInstancesEntityEnumerator(IfcPersistedInstanceCache cache)
 {
     this.cache  = cache;
     this.cursor = cache.GetEntityTable();
     Reset();
 }
Example #10
0
        internal IfcFileHeader Read(IfcPersistedInstanceCache instanceCache, XbimEntityCursor entityTable,  XmlReader input)
        {
           
            // Read until end of file
            idMap = new Dictionary<string, int>();
            lastId = 0;
            _entitiesParsed = 0;
            bool foundHeader = false;
            IfcFileHeader header = new IfcFileHeader(IfcFileHeader.HeaderCreationMode.LeaveEmpty);
            string headerId="";
            while (_currentNode == null && input.Read()) //read through to UOS
            {
                switch (input.NodeType)
                {
                    case XmlNodeType.Element:
                        if (string.Compare(input.LocalName, "uos", true) == 0)
                        {
                            _currentNode = new XmlUosCollection();
                           
                        }
                        else if (string.Compare(input.LocalName, "iso_10303_28", true) == 0)
                        {
                            foundHeader = true;
                            if (!string.IsNullOrWhiteSpace(input.Prefix))
                            {
                                _expressNamespace = input.Prefix;
                                _cTypeAttribute = _expressNamespace + ":cType";
                                _posAttribute = _expressNamespace + ":pos";
                                _expressNamespace += ":";
                            }
                            else
                            {
                                _cTypeAttribute = "cType";
                                _posAttribute = "pos";
                            }
                                
                        }
                        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;
                            default:
                                break;
                        }
                        break;
                    default:
                        break;
                }
               
            }
            if (!foundHeader)
                throw new Exception("Invalid XML format, iso_10303_28 tag not found");
            XmlNodeType prevInputType = XmlNodeType.None;
            string prevInputName = "";

            // set counter for start of every element that is not empty, and reduce it on every end of that element


           
            try
            {
                using (var transaction = entityTable.BeginLazyTransaction())
                {


                    // this will create id of each element
                    Dictionary<string, int> ids = new Dictionary<string, int>();
                    while (input.Read())
                    {
                        switch (input.NodeType)
                        {
                            case XmlNodeType.Element:
                                StartElement(instanceCache, input, entityTable, transaction);
                                break;
                            case XmlNodeType.EndElement:
                                IPersistIfcEntity toWrite;
                                //if toWrite has a value we have completed an Ifc Entity
                                EndElement(input, prevInputType, prevInputName, out toWrite);
                                if (toWrite != null)
                                {
                                    _entitiesParsed++;
                                    //now write the entity to the database
                                    entityTable.AddEntity(toWrite);
                                    if (_entitiesParsed % _transactionBatchSize == (_transactionBatchSize - 1))
                                    {
                                        transaction.Commit();
                                        transaction.Begin();
                                    }
                                }
                                break;
                            case XmlNodeType.Whitespace:
                                SetValue(input, prevInputType, prevInputName);
                                break;
                            case XmlNodeType.Text:
                                SetValue(input, prevInputType, prevInputName);
                                break;
                            default:
                                break;
                        }
                        prevInputType = input.NodeType;
                        prevInputName = input.LocalName;
                    }
                    transaction.Commit();
                }
            }
            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);
            }
            return header;
        }
Example #11
0
        private void StartElement(IfcPersistedInstanceCache cache, XmlReader input, XbimEntityCursor entityTable, XbimLazyDBTransaction transaction)
        {
            string elementName = input.LocalName;
            bool isRefType;
            int id = GetId(input, out isRefType);

            IfcType ifcType;
            
            IfcParserType parserType;
            IfcMetaProperty prop;
            int propIndex;


            if (id > -1 && IsIfcEntity(elementName, out ifcType)) //we have an element which is an Ifc Entity
            {
                IPersistIfcEntity ent;
                if (!cache.Contains(id))
                {
                    // not been declared in a ref yet
                    // model.New creates an instance uisng type and id
                    ent = cache.CreateNew(ifcType.Type, id);
                   
                }
                else
                {
                    ent = cache.GetInstance(id, false, true);
                }

                XmlEntity xmlEnt = new XmlEntity(_currentNode, ent);
               
                //if we have a completely empty element that is not a ref we need to make sure it is written to the database as EndElement will not be called
                if (input.IsEmptyElement && !isRefType)
                {
                    _entitiesParsed++;
                    //now write the entity to the database
                    entityTable.AddEntity(xmlEnt.Entity);
                    if (_entitiesParsed % _transactionBatchSize == (_transactionBatchSize - 1))
                    {
                        transaction.Commit();
                        transaction.Begin();
                    }
                    

                }


                string pos = input.GetAttribute(_posAttribute);
                if (string.IsNullOrEmpty(pos)) pos = input.GetAttribute("pos"); //try without namespace
                if (!string.IsNullOrEmpty(pos))
                    xmlEnt.Position = Convert.ToInt32(pos);
                if (!input.IsEmptyElement)
                {
                    // add the entity to its parent if its parent is a list
                    //if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    //    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);

                    _currentNode = xmlEnt;
                }
                else if (_currentNode is XmlProperty)
                {
                    // if it is a ref then it will be empty element and wont have an end tag
                    // so nither SetValue nor EndElement will be called, so set the value of ref here e.g. #3
                    ((XmlProperty)(_currentNode)).SetValue(ent);
                }
                else if (!(_currentNode is XmlUosCollection) && _currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                {
                    ((XmlCollectionProperty)_currentNode).Entities.Add(xmlEnt);
                }
            }
            else if (input.IsEmptyElement)
            {
                if (IsIfcProperty(elementName, out propIndex, out prop))
                {
                    XmlProperty node = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex); ;
                    PropertyValue propVal = new PropertyValue();
                    Type t = node.Property.PropertyType;

                    if (!typeof(ExpressEnumerable).IsAssignableFrom(t)) // if its a empty collection then dont do anything
                    {
                        if (t != null && t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
                            t = Nullable.GetUnderlyingType(t);
                        ExpressType et = null;
                        if (t != null && typeof(ExpressType).IsAssignableFrom(t))
                            et = (ExpressType)(Activator.CreateInstance(t));

                        IfcParserType pt;
                        if (et != null)
                            pt = primitives[et.UnderlyingSystemType.Name];
                        else
                        {
                            if (t.IsEnum)
                            {
                                pt = IfcParserType.Enum;
                            }
                            else
                                pt = primitives[t.Name];
                        }

                        if (pt.ToString().ToLower() == "string")
                            propVal.Init("'" + input.Value + "'", pt);
                        else
                        {
                            if (pt.ToString().ToLower() == "boolean")
                                propVal.Init(Convert.ToBoolean(input.Value) ? ".T." : ".F", pt);
                            else
                                propVal.Init(input.Value, pt);
                        }
                        ((XmlEntity)node.Parent).Entity.IfcParse(node.PropertyIndex - 1, propVal);
                    }

                }
                else if (IsIfcType(elementName, out ifcType))
                {
                    IPersistIfc ent;
                    object[] param = new object[1];
                    param[0] = ""; // empty element
                    ent = (IPersistIfc)Activator.CreateInstance(ifcType.Type, param);

                    ((XmlProperty)_currentNode).SetValue(ent);
                }

                return;
            }
            else if (id == -1 && IsIfcProperty(elementName, out propIndex, out prop)) //we have an element which is a property
            {

                string cType = input.GetAttribute(_cTypeAttribute);
                if (string.IsNullOrEmpty(cType)) cType = input.GetAttribute("cType"); //in case namespace omitted
                if (IsCollection(prop)) //the property is a collection
                {
                    XmlCollectionProperty xmlColl = new XmlCollectionProperty(_currentNode, prop.PropertyInfo, propIndex);
                    switch (cType)
                    {
                        case "list":
                            xmlColl.CType = CollectionType.List;
                            break;
                        case "list-unique":
                            xmlColl.CType = CollectionType.ListUnique;
                            break;
                        case "set":
                            xmlColl.CType = CollectionType.Set;
                            break;
                        default:
                            xmlColl.CType = CollectionType.List;
                            break;
                    }

                    _currentNode = xmlColl;
                }
                else //it is a simple value property;
                {


                    // its parent can be a collection, if yes then this property needs to be added to parent
                    XmlNode n = new XmlProperty(_currentNode, prop.PropertyInfo, propIndex);
                    if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                        ((XmlCollectionProperty)_currentNode).Entities.Add(n);

                    if (!input.IsEmptyElement) _currentNode = n;
                }
            }
            else if (id == -1 && IsIfcType(elementName, out ifcType)) // we have an Ifc ExpressType
            {


                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlExpressType(_currentNode, ifcType.Type);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);

                if (!input.IsEmptyElement) _currentNode = n;
            }
            else if (id == -1 && IsPrimitiveType(elementName, out parserType)) // we have an basic type i.e. double, bool etc
            {
                // its parent can be a collection, if yes then this property needs to be added to parent
                XmlNode n = new XmlBasicType(_currentNode, parserType);
                if (_currentNode is XmlCollectionProperty && !(_currentNode.Parent is XmlUosCollection))
                    ((XmlCollectionProperty)_currentNode).Entities.Add(n);

                if (!input.IsEmptyElement) _currentNode = n;
            }
            else
                throw new Exception("Illegal XML element tag");
        }
Example #12
0
        /// <summary>
        /// Populates an entites properties from the binary stream
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="cache"></param>
        /// <param name="br"></param>
        /// <param name="unCached">If true instances inside the properties are not added to the cache</param>
        /// <param name="fromCache"> If true the instance is read from the cache if not present it is created, used during parsing</param>
        public static void ReadEntityProperties(this IPersistIfcEntity entity, IfcPersistedInstanceCache cache, BinaryReader br, bool unCached = false, bool fromCache = false)
        {
            P21ParseAction action = (P21ParseAction)br.ReadByte();

            XbimParserState parserState = new XbimParserState(entity);

            while (action != P21ParseAction.EndEntity)
            {
                switch (action)
                {
                case P21ParseAction.BeginList:
                    parserState.BeginList();
                    break;

                case P21ParseAction.EndList:
                    parserState.EndList();
                    break;

                case P21ParseAction.BeginComplex:
                    break;

                case P21ParseAction.EndComplex:
                    break;

                case P21ParseAction.SetIntegerValue:
                    parserState.SetIntegerValue(br.ReadInt64());
                    break;

                case P21ParseAction.SetHexValue:
                    parserState.SetHexValue(br.ReadInt64());
                    break;

                case P21ParseAction.SetFloatValue:
                    parserState.SetFloatValue(br.ReadDouble());
                    break;

                case P21ParseAction.SetStringValue:
                    parserState.SetStringValue(br.ReadString());
                    break;

                case P21ParseAction.SetEnumValue:
                    parserState.SetEnumValue(br.ReadString());
                    break;

                case P21ParseAction.SetBooleanValue:
                    parserState.SetBooleanValue(br.ReadBoolean());
                    break;

                case P21ParseAction.SetNonDefinedValue:
                    parserState.SetNonDefinedValue();
                    break;

                case P21ParseAction.SetOverrideValue:
                    parserState.SetOverrideValue();
                    break;

                case P21ParseAction.SetObjectValueUInt16:
                    if (fromCache)
                    {
                        int label = br.ReadUInt16();
                        IPersistIfcEntity refEntity;
                        if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity))     //if we are in a list then make a forward reference anyway to make sure we maintain list order
                        {
                            parserState.SetObjectValue(refEntity);
                        }
                        else
                        {
                            cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                            parserState.SkipProperty();
                        }
                    }
                    else
                    {
                        parserState.SetObjectValue(cache.GetInstance(br.ReadUInt16(), false, unCached));
                    }
                    break;

                case P21ParseAction.SetObjectValueInt32:
                    if (fromCache)
                    {
                        int label = br.ReadInt32();
                        IPersistIfcEntity refEntity;
                        if (!parserState.InList && cache.Read.TryGetValue(label, out refEntity))     //if we are in a list then make a forward reference anyway to make sure we maintain list order
                        {
                            parserState.SetObjectValue(refEntity);
                        }
                        else
                        {
                            cache.AddForwardReference(new IfcForwardReference(label, parserState.CurrentPropertyId, entity));
                            parserState.SkipProperty();
                        }
                    }
                    else
                    {
                        parserState.SetObjectValue(cache.GetInstance(br.ReadInt32(), false, unCached));
                    }
                    break;

                case P21ParseAction.SetObjectValueInt64:
                    throw new XbimException("Entity Label is int64, this is not currently supported");

                //parserState.SetObjectValue(cache.GetInstance(br.ReadInt64(), false, unCached));
                //break;
                case P21ParseAction.BeginNestedType:
                    parserState.BeginNestedType(br.ReadString());
                    break;

                case P21ParseAction.EndNestedType:
                    parserState.EndNestedType();
                    break;

                case P21ParseAction.EndEntity:
                    parserState.EndEntity();
                    break;

                case P21ParseAction.NewEntity:
                    parserState = new XbimParserState(entity);
                    break;

                default:
                    throw new XbimException("Invalid Property Record #" + entity.EntityLabel + " EntityType: " + entity.GetType().Name);
                }
                action = (P21ParseAction)br.ReadByte();
            }
        }