Пример #1
0
        /// <summary>
        /// Returns all handles that are not of type to exclude
        /// </summary>
        /// <param name="exclude"></param>
        /// <returns></returns>
        public IEnumerable <XbimGeometryHandle> Exclude(params int[] exclude)
        {
            var excludeSet = new HashSet <int>(exclude);

            foreach (var ex in exclude)
            {
                var type = _metadata.ExpressType((short)ex);
                // bugfix here: loop did not use to include all implementations, but only first level down.
                foreach (var sub in type.NonAbstractSubTypes)
                {
                    excludeSet.Add(sub.TypeId);
                }
            }

            return(this.Where(h => !excludeSet.Contains(h.ExpressTypeId)));
        }
Пример #2
0
        internal void BeginNestedType(string typeName)
        {
            var type = _metadata.ExpressType(typeName);

            _currentInstance = new Part21Entity((IPersist)Activator.CreateInstance(type.Type));
            _processStack.Push(_currentInstance);
        }
        public bool Resolve(ConcurrentDictionary <int, IPersistEntity> references, ExpressMetaData metadata)
        {
            IPersistEntity entity;

            if (references.TryGetValue(ReferenceEntityLabel, out entity))
            {
                var pv = new PropertyValue();
                pv.Init(entity);
                try
                {
                    _referencingEntity.Parse(_referencingPropertyId, pv, _nestedIndex);
                    return(true);
                }
                catch (Exception)
                {
                    var expressType = metadata.ExpressType(_referencingEntity);
                    //TODO put a logger message here
                    //EsentModel.Logger.ErrorFormat("Data Error. Cannot set the property = {0} of entity #{1} = {2} to entity #{3}, schema violation. Ignored",
                    //    expressType.Properties[_referencingPropertyId+1].PropertyInfo.Name,
                    //    _referencingEntity.EntityLabel,
                    //    _referencingEntity.GetType().Name,
                    //    ReferenceEntityLabel);
                    return(false);
                }
            }
            else
            {
                return(false);
            }
        }
Пример #4
0
        private void WriteEntity(IPersistEntity entity, XmlWriter output, bool onlyOnce, int[] pos = null, string name = null)
        {
            var exists = _written.Contains(entity.EntityLabel);

            if (exists && onlyOnce) //we have already done it and nothing should be written out
            {
                return;
            }

            if (!exists)
            {
                _written.Add(entity.EntityLabel);
            }

            var expressType = _metadata.ExpressType(entity);
            var elementName = name ?? expressType.ExpressName;

            output.WriteStartElement(elementName);
            output.WriteAttributeString(exists ? "ref" : "id", string.Format("i{0}", entity.EntityLabel));

            if (pos != null) //we are writing out a list element
            {
                output.WriteAttributeString("pos", string.Join(" ", pos));
            }

            //specify type if it is different from the name of the element
            if (name != null && string.CompareOrdinal(name, expressType.ExpressName) != 0)
            {
                output.WriteAttributeString("type", Xsi, expressType.ExpressName);
            }

            //only write properties if this is the first occurence
            if (!exists)
            {
                WriteProperties(entity, output, expressType);
            }
            //specify this is an empty element refering to another one
            else
            {
                output.WriteAttributeString("nil", Xsi, "true");
            }


            output.WriteEndElement();
        }
Пример #5
0
        private void SetEntityParameter(string value)
        {
            try
            {
                if (CurrentInstance.Entity != null)
                {
                    CurrentInstance.ParameterSetter(CurrentInstance.CurrentParamIndex, PropertyValue, NestedIndex);
                }
            }
            catch (Exception)
            {
                if (ErrorCount > MaxErrorCount)
                {
                    throw new XbimParserException("Too many errors in file, parser execution terminated");
                }
                ErrorCount++;
                var mainEntity = _processStack.Last();
                if (mainEntity != null)
                {
                    var expressType = Metadata?.ExpressType(mainEntity.Entity);
                    if (expressType != null)
                    {
                        var propertyName = mainEntity.CurrentParamIndex + 1 > expressType.Properties.Count
                            ? "[UnknownProperty]"
                            : expressType.Properties[mainEntity.CurrentParamIndex + 1].PropertyInfo.Name;

                        Logger.ErrorFormat("Entity #{0,-5} {1}, error at parameter {2}-{3} value = {4}",
                                           mainEntity.EntityLabel,
                                           mainEntity.Entity.GetType().Name.ToUpper(),
                                           mainEntity.CurrentParamIndex + 1,
                                           propertyName,
                                           value);
                    }
                    else
                    {
                        Logger.ErrorFormat("Entity #{0,-5} {1}, error at parameter {2} value = {3}",
                                           mainEntity.EntityLabel,
                                           mainEntity.Entity.GetType().Name.ToUpper(),
                                           mainEntity.CurrentParamIndex + 1,
                                           value);
                    }
                }
                else
                {
                    Logger.Error("Unhandled Parser error, in Parser.cs SetEntityParameter");
                }
            }
            if (ListNestLevel == 0)
            {
                CurrentInstance.CurrentParamIndex++;
                _deferListItems = false;
            }
        }
Пример #6
0
 protected override void EndNestedType(string value)
 {
     try
     {
         PropertyValue.Init(_processStack.Pop().Entity);
         CurrentInstance = _processStack.Peek();
         if (CurrentInstance.Entity != null)
         {
             CurrentInstance.ParameterSetter(CurrentInstance.CurrentParamIndex, PropertyValue, NestedIndex);
         }
     }
     catch (Exception)
     {
         if (ErrorCount > MaxErrorCount)
         {
             throw new XbimParserException("Too many errors in file, parser execution terminated");
         }
         ErrorCount++;
         var mainEntity = _processStack.Last();
         if (mainEntity != null)
         {
             var expressType = Metadata.ExpressType(mainEntity.Entity);
             Logger.ErrorFormat("Entity #{0,-5} {1}, error at parameter {2}-{3} value = {4}",
                                mainEntity.EntityLabel, mainEntity.Entity.GetType().Name.ToUpper(),
                                mainEntity.CurrentParamIndex + 1,
                                expressType.Properties[mainEntity.CurrentParamIndex + 1].PropertyInfo.Name,
                                value);
         }
         else
         {
             Logger.Error("Unhandled Parser error, in Parser.cs EndNestedType");
         }
     }
     if (ListNestLevel == 0)
     {
         CurrentInstance.CurrentParamIndex++;
         _deferListItems = false;
     }
 }
Пример #7
0
        private ExpressType GetExpressType(ExpressMetaData schema, string classString)
        {
            var v = schema.ExpressType(classString.ToUpper());

            if (v != null)
            {
                return(v);
            }
            // warn once only;
            if (_failedLookupMessages.Contains(classString.ToUpper()))
            {
                return(null);
            }
            Log.Error($"{classString} is not a recognised class in {schema.Module.Name}.");
            _failedLookupMessages.Add(classString.ToUpper());
            return(null);
        }
Пример #8
0
        private void Write(IPersistEntity entity, XmlWriter output, int pos = -1)
        {
            if (_written.Contains(entity.EntityLabel)) //we have already done it
            {
                return;
            }
            _written.Add(entity.EntityLabel);

            var expressType = _metadata.ExpressType(entity);

            output.WriteStartElement(expressType.Type.Name);

            output.WriteAttributeString("id", string.Format("i{0}", entity.EntityLabel));
            if (pos > -1) //we are writing out a list element
            {
                output.WriteAttributeString("pos", pos.ToString());
            }

            IEnumerable <ExpressMetaProperty> toWrite;

            if (WriteInverses)
            {
                var l = new List <ExpressMetaProperty>(expressType.Properties.Values);
                l.AddRange(expressType.Inverses);
                toWrite = l;
            }
            else
            {
                toWrite = expressType.Properties.Values;
            }

            foreach (var ifcProperty in toWrite) //only write out persistent attributes, ignore inverses
            {
                if (ifcProperty.EntityAttribute.State != EntityAttributeState.DerivedOverride)
                {
                    var propType = ifcProperty.PropertyInfo.PropertyType;
                    var propVal  = ifcProperty.PropertyInfo.GetValue(entity, null);

                    WriteProperty(ifcProperty.PropertyInfo.Name, propType, propVal, entity, output, -1,
                                  ifcProperty.EntityAttribute);
                }
            }
            output.WriteEndElement();
        }
Пример #9
0
        private bool IsIfcProperty(string elementName, out int index, out ExpressMetaProperty prop)
        {
            ExpressType expressType;
            var         xmlEntity = _currentNode as XmlEntity;

            if (xmlEntity != null && !_metadata.TryGetExpressType(elementName.ToUpper(), out expressType))
            {
                var t = _metadata.ExpressType(xmlEntity.Entity);

                foreach (var p in t.Properties.Where(p => p.Value.PropertyInfo.Name == elementName))
                {
                    prop  = p.Value;
                    index = p.Key;
                    return(true);
                }
            }
            prop  = null;
            index = -1;
            return(false);
        }
Пример #10
0
        private static void WriteEntity(IPersistEntity entity, TextWriter output, ExpressMetaData metadata)
        {
            var expressType = metadata.ExpressType(entity);

            output.Write("#{0}={1}(", entity.EntityLabel, expressType.ExpressNameUpper);

            var first = true;

            foreach (var ifcProperty in expressType.Properties.Values)
            //only write out persistent attributes, ignore inverses
            {
                if (ifcProperty.EntityAttribute.State == EntityAttributeState.DerivedOverride)
                {
                    if (!first)
                    {
                        output.Write(',');
                    }
                    output.Write('*');
                    first = false;
                }
                else
                {
                    // workaround for IfcCartesianPointList3D from IFC4x1
                    if (entity is IfcCartesianPointList3D && ifcProperty.Name == "TagList")
                    {
                        continue;
                    }

                    var propType = ifcProperty.PropertyInfo.PropertyType;
                    var propVal  = ifcProperty.PropertyInfo.GetValue(entity, null);
                    if (!first)
                    {
                        output.Write(',');
                    }
                    Part21Writer.WriteProperty(propType, propVal, output, null, metadata);
                    first = false;
                }
            }
            output.Write(");");
        }
Пример #11
0
        /// <summary>
        /// Writes the entity to a TextWriter in the Part21 format
        /// </summary>
        /// <param name="output">The TextWriter</param>
        /// <param name="entity">The entity to write</param>
        /// <param name="metadata"></param>
        /// <param name="map"></param>
        public static void WriteEntity(IPersistEntity entity, TextWriter output, ExpressMetaData metadata, IDictionary <int, int> map = null)
        {
            var expressType = metadata.ExpressType(entity);

            if (map != null && map.Keys.Contains(entity.EntityLabel))
            {
                return;                                                       //if the entity is replaced in the map do not write it
            }
            output.Write("#{0}={1}(", entity.EntityLabel, expressType.ExpressNameUpper);

            var first = true;

            foreach (var ifcProperty in expressType.Properties.Values)
            //only write out persistent attributes, ignore inverses
            {
                if (ifcProperty.EntityAttribute.State == EntityAttributeState.DerivedOverride)
                {
                    if (!first)
                    {
                        output.Write(',');
                    }
                    output.Write('*');
                    first = false;
                }
                else
                {
                    var propType = ifcProperty.PropertyInfo.PropertyType;
                    var propVal  = ifcProperty.PropertyInfo.GetValue(entity, null);
                    if (!first)
                    {
                        output.Write(',');
                    }
                    WriteProperty(propType, propVal, output, map, metadata);
                    first = false;
                }
            }
            output.Write(");");
        }
        internal static void WriteEntity(this IPersistEntity entity, BinaryWriter entityWriter, ExpressMetaData metadata)
        {
            var expressType = metadata.ExpressType(entity);

            // entityWriter.Write(Convert.ToByte(P21ParseAction.NewEntity));
            entityWriter.Write(Convert.ToByte(P21ParseAction.BeginList));
            foreach (var ifcProperty in expressType.Properties.Values)
            //only write out persistent attributes, ignore inverses
            {
                if (ifcProperty.EntityAttribute.State == EntityAttributeState.DerivedOverride)
                {
                    entityWriter.Write(Convert.ToByte(P21ParseAction.SetOverrideValue));
                }
                else
                {
                    var propType = ifcProperty.PropertyInfo.PropertyType;
                    var propVal  = ifcProperty.PropertyInfo.GetValue(entity, null);
                    WriteProperty(propType, propVal, entityWriter, metadata);
                }
            }
            entityWriter.Write(Convert.ToByte(P21ParseAction.EndList));
            entityWriter.Write(Convert.ToByte(P21ParseAction.EndEntity));
        }
Пример #13
0
        private void SetPropertyFromString(ExpressMetaProperty property, IPersistEntity entity, string value, int[] pos, Type valueType = null)
        {
            var pIndex = property.EntityAttribute.Order - 1;
            var type   = valueType ?? property.PropertyInfo.PropertyType;

            type = GetNonNullableType(type);
            var propVal = new PropertyValue();

            if (type.IsValueType || type == typeof(string))
            {
                if (typeof(IExpressComplexType).IsAssignableFrom(type))
                {
                    var meta      = _metadata.ExpressType(type);
                    var values    = value.Split(_separator, StringSplitOptions.RemoveEmptyEntries);
                    var underType = meta.UnderlyingComplexType;
                    foreach (var v in values)
                    {
                        IPropertyValue pv;
                        if (InitPropertyValue(underType, v, out pv))
                        {
                            entity.Parse(pIndex, pv, pos);
                        }
                    }
                    return;
                }
                if (type.IsEnum)
                {
                    propVal.Init(value, StepParserType.Enum);
                    entity.Parse(pIndex, propVal, pos);
                    return;
                }

                //handle other value types
                if (typeof(IExpressValueType).IsAssignableFrom(type))
                {
                    var meta = _metadata.ExpressType(type);
                    type = meta.UnderlyingType;
                }
                IPropertyValue pVal;
                if (InitPropertyValue(type, value, out pVal))
                {
                    entity.Parse(pIndex, pVal, pos);
                }
                return;
            }

            //lists of value types will be serialized as lists. If this is not an IEnumerable this is not the case
            if (!typeof(IEnumerable).IsAssignableFrom(type) || !type.IsGenericType)
            {
                throw new XbimParserException("Unexpected enumerable type " + type.Name);
            }

            var genType = type.GetGenericArguments()[0];

            if (genType.IsValueType || genType == typeof(string))
            {
                //handle enumerable of value type and string
                var values = value.Split(_separator, StringSplitOptions.RemoveEmptyEntries);
                foreach (var v in values)
                {
                    SetPropertyFromString(property, entity, v, pos, genType);
                }
                return;
            }

            //rectangular nested lists can also be serialized as attribute if defined in configuration
            if (typeof(IEnumerable).IsAssignableFrom(genType))
            {
                //handle rectangular nested lists (like IfcPointList3D)
                var cardinality = property.EntityAttribute.MaxCardinality;
                if (cardinality != property.EntityAttribute.MinCardinality)
                {
                    throw new XbimParserException(property.Name + " is not rectangular so it can't be serialized as a simple text string");
                }

                var values  = value.Split(_separator, StringSplitOptions.RemoveEmptyEntries);
                var valType = GetNonGenericType(genType);
                if (typeof(IExpressValueType).IsAssignableFrom(valType))
                {
                    var expValType = _metadata.ExpressType(valType);
                    if (expValType == null)
                    {
                        throw new XbimParserException("Unexpected data type " + valType.Name);
                    }
                    valType = expValType.UnderlyingType;
                }

                for (var i = 0; i < values.Length; i++)
                {
                    IPropertyValue pValue;
                    InitPropertyValue(valType, values[i], out pValue);
                    var idx = i / cardinality;
                    entity.Parse(pIndex, pValue, new [] { idx });
                }
            }
        }
Пример #14
0
        private IPersistEntity ReadEntity(XmlReader input, Type suggestedType = null)
        {
            var expType = GetExpresType(input);

            if (expType == null && suggestedType != null && !suggestedType.IsAbstract)
            {
                expType = _metadata.ExpressType(suggestedType);
            }
            if (expType == null)
            {
                var typeName = input.GetAttribute("type") ?? input.LocalName;
                throw new XbimParserException(typeName + "is not an IPersistEntity type");
            }

            var id = GetId(input, expType, out bool isRef);

            if (!id.HasValue)
            {
                throw new XbimParserException("Wrong entity XML format");
            }

            var entity = _getOrCreate(id.Value, expType.Type);

            if (isRef)
            {
                if (!input.IsEmptyElement)
                {
                    // Consume anything until the end of the entity.
                    // this is usualy empty element but some people put data in there as well to indicate some of the
                    // content for humans reading the XML (as much as it is silly)
                    var depth      = input.Depth;
                    var hasContent = false;
                    while (input.Read())
                    {
                        if (input.NodeType == XmlNodeType.EndElement && input.Depth == depth)
                        {
                            break;
                        }
                        hasContent = true;
                    }
                    if (hasContent)
                    {
                        // Log a warning as it is a wrong practise to put content in ref elements
                        Logger.LogWarning("Reference to element {0}, ref='{1}' is not empty. This is a wrong practise.", entity.ExpressType.Name, id);
                    }
                }
                return(entity);
            }

            //read all attributes
            while (input.MoveToNextAttribute())
            {
                var pInfo = GetMetaProperty(expType, input.LocalName);
                if (pInfo == null)
                {
                    continue;
                }
                SetPropertyFromString(pInfo, entity, input.Value, null);
            }
            input.MoveToElement();

            if (input.IsEmptyElement)
            {
                _finish(entity);
                return(entity);
            }

            //read all element properties
            var pDepth = input.Depth;

            while (input.Read())
            {
                if (input.NodeType == XmlNodeType.EndElement && input.Depth == pDepth)
                {
                    break;
                }
                if (input.NodeType != XmlNodeType.Element)
                {
                    continue;
                }
                var pInfo = GetMetaProperty(expType, input.LocalName);
                if (pInfo == null)
                {
                    continue;
                }
                SetPropertyFromElement(pInfo, entity, input, null);
                if (input.NodeType == XmlNodeType.EndElement && input.Depth == pDepth)
                {
                    break;
                }
            }

            //finalize
            _finish(entity);
            return(entity);
        }
        private static void WriteProperty(Type propType, object propVal, BinaryWriter entityWriter, ExpressMetaData metadata)
        {
            Type itemType;

            if (propVal == null) //null or a value type that maybe null
            {
                entityWriter.Write(Convert.ToByte(P21ParseAction.SetNonDefinedValue));
            }
            else if (propVal is IOptionalItemSet && !((IOptionalItemSet)propVal).Initialized)
            {
                entityWriter.Write(Convert.ToByte(P21ParseAction.SetNonDefinedValue));
            }
            else if (propType.IsGenericType && propType.GetGenericTypeDefinition() == typeof(Nullable <>))
            //deal with undefined types (nullables)
            {
                var complexType = propVal as IExpressComplexType;
                if (complexType != null)
                {
                    entityWriter.Write(Convert.ToByte(P21ParseAction.BeginList));
                    foreach (var compVal in complexType.Properties)
                    {
                        WriteProperty(compVal.GetType(), compVal, entityWriter, metadata);
                    }
                    entityWriter.Write(Convert.ToByte(P21ParseAction.EndList));
                }
                else if ((propVal is IExpressValueType))
                {
                    var expressVal = (IExpressValueType)propVal;
                    WriteValueType(expressVal.UnderlyingSystemType, expressVal.Value, entityWriter);
                }
                else
                {
                    WriteValueType(propVal.GetType(), propVal, entityWriter);
                }
            }
            else if (typeof(IExpressComplexType).IsAssignableFrom(propType))
            {
                entityWriter.Write(Convert.ToByte(P21ParseAction.BeginList));
                foreach (var compVal in ((IExpressComplexType)propVal).Properties)
                {
                    WriteProperty(compVal.GetType(), compVal, entityWriter, metadata);
                }
                entityWriter.Write(Convert.ToByte(P21ParseAction.EndList));
            }
            else if (typeof(IExpressValueType).IsAssignableFrom(propType))
            //value types with a single property (IfcLabel, IfcInteger)
            {
                var realType = propVal.GetType();
                if (realType != propType)
                //we have a type but it is a select type use the actual value but write out explicitly
                {
                    entityWriter.Write(Convert.ToByte(P21ParseAction.BeginNestedType));
                    entityWriter.Write(realType.Name.ToUpper());
                    entityWriter.Write(Convert.ToByte(P21ParseAction.BeginList));
                    WriteProperty(realType, propVal, entityWriter, metadata);
                    entityWriter.Write(Convert.ToByte(P21ParseAction.EndList));
                    entityWriter.Write(Convert.ToByte(P21ParseAction.EndNestedType));
                }
                else //need to write out underlying property value
                {
                    var expressVal = (IExpressValueType)propVal;
                    WriteValueType(expressVal.UnderlyingSystemType, expressVal.Value, entityWriter);
                }
            }
            else if (typeof(IExpressEnumerable).IsAssignableFrom(propType) &&
                     (itemType = propType.GetItemTypeFromGenericType()) != null)
            //only process lists that are real lists, see cartesianpoint
            {
                entityWriter.Write(Convert.ToByte(P21ParseAction.BeginList));
                foreach (var item in ((IExpressEnumerable)propVal))
                {
                    WriteProperty(itemType, item, entityWriter, metadata);
                }
                entityWriter.Write(Convert.ToByte(P21ParseAction.EndList));
            }
            else if (typeof(IPersistEntity).IsAssignableFrom(propType))
            //all writable entities must support this interface and ExpressType have been handled so only entities left
            {
                var val = ((IPersistEntity)propVal).EntityLabel;
                if (val <= UInt16.MaxValue)
                {
                    entityWriter.Write((byte)P21ParseAction.SetObjectValueUInt16);
                    entityWriter.Write(Convert.ToUInt16(val));
                }
                else if (val <= Int32.MaxValue)
                {
                    entityWriter.Write((byte)P21ParseAction.SetObjectValueInt32);
                    entityWriter.Write(Convert.ToInt32(val));
                }
                //else if (val <= Int64.MaxValue)
                //{
                //    //This is a very large model and it is unlikely we will be able to handle this number of entities,
                //    //it is possible they have just created big labels and it needs to be renumbered
                //    //Entity Label could be redfined as a long bu this is a large overhead if never required, let's see...
                //    throw new XbimException("Entity Label is Init64, this is not currently supported");
                //    //entityWriter.Write((byte)P21ParseAction.SetObjectValueInt64);
                //    //entityWriter.Write(val);
                //}
                else
                {
                    throw new Exception("Entity Label exceeds maximim value for a an int32 long number");
                }
            }
            else if (propType.IsValueType || propType == typeof(string)) //it might be an in-built value type double, string etc
            {
                WriteValueType(propVal.GetType(), propVal, entityWriter);
            }
            else if (typeof(IExpressSelectType).IsAssignableFrom(propType))
            // a select type get the type of the actual value
            {
                if (propVal.GetType().IsValueType) //we have a value type, so write out explicitly
                {
                    var type = metadata.ExpressType(propVal.GetType());
                    entityWriter.Write(Convert.ToByte(P21ParseAction.BeginNestedType));
                    entityWriter.Write(type.ExpressNameUpper);
                    entityWriter.Write(Convert.ToByte(P21ParseAction.BeginList));
                    WriteProperty(propVal.GetType(), propVal, entityWriter, metadata);
                    entityWriter.Write(Convert.ToByte(P21ParseAction.EndList));
                    entityWriter.Write(Convert.ToByte(P21ParseAction.EndNestedType));
                }
                else //could be anything so re-evaluate actual type
                {
                    WriteProperty(propVal.GetType(), propVal, entityWriter, metadata);
                }
            }
            else
            {
                throw new Exception(string.Format("Entity  has illegal property {0} of type {1}",
                                                  propType.Name, propType.Name));
            }
        }
        internal static void WriteEntity(this IPersistEntity entity, TextWriter tw, byte[] propertyData, ExpressMetaData metadata)
        {
            var type = metadata.ExpressType(entity);

            tw.Write("#{0}={1}", entity.EntityLabel, type.ExpressNameUpper);
            var br     = new BinaryReader(new MemoryStream(propertyData));
            var action = (P21ParseAction)br.ReadByte();
            var comma  = false; //the first property

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

                case P21ParseAction.EndList:
                    tw.Write(")");
                    break;

                case P21ParseAction.BeginComplex:
                    tw.Write("&SCOPE");
                    break;

                case P21ParseAction.EndComplex:
                    tw.Write("ENDSCOPE");
                    break;

                case P21ParseAction.SetIntegerValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write(br.ReadInt64().ToString());
                    break;

                case P21ParseAction.SetHexValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write(Convert.ToString(br.ReadInt64(), 16));
                    break;

                case P21ParseAction.SetFloatValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write(br.ReadDouble().AsPart21());
                    break;

                case P21ParseAction.SetStringValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write(br.ReadString());
                    break;

                case P21ParseAction.SetEnumValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write("." + br.ReadString() + ".");
                    break;

                case P21ParseAction.SetBooleanValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write(br.ReadBoolean() ? ".T." : ".F.");
                    break;

                case P21ParseAction.SetNonDefinedValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write("$");
                    break;

                case P21ParseAction.SetOverrideValue:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write("*");
                    break;

                case P21ParseAction.SetObjectValueUInt16:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write("#" + br.ReadUInt16());
                    break;

                case P21ParseAction.SetObjectValueInt32:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write("#" + br.ReadInt32());
                    break;

                case P21ParseAction.SetObjectValueInt64:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = true;
                    tw.Write("#" + br.ReadInt64());
                    break;

                case P21ParseAction.BeginNestedType:
                    if (comma)
                    {
                        tw.Write(",");
                    }
                    comma = false;
                    tw.Write(br.ReadString() + "(");
                    break;

                case P21ParseAction.EndNestedType:
                    comma = true;
                    tw.Write(")");
                    break;

                case P21ParseAction.EndEntity:
                    tw.Write(");");
                    break;

                case P21ParseAction.NewEntity:
                    comma = false;
                    tw.Write("(");
                    break;

                default:
                    throw new Exception("Invalid Property Record #" + entity.EntityLabel + " EntityType: " + entity.GetType().Name);
                }
                action = (P21ParseAction)br.ReadByte();
            }
            tw.WriteLine();
        }
Пример #17
0
        /// <summary>
        /// Writes a property of an entity to the TextWriter in the Part21 format
        /// </summary>
        /// <param name="propType"></param>
        /// <param name="propVal"></param>
        /// <param name="output"></param>
        /// <param name="map"></param>
        /// <param name="metadata"></param>
        public static void WriteProperty(Type propType, object propVal, TextWriter output, IDictionary <int, int> map, ExpressMetaData metadata)
        {
            Type itemType;

            if (propVal == null) //null or a value type that maybe null
            {
                output.Write('$');
            }
            else if (propVal is IOptionalItemSet && !((IOptionalItemSet)propVal).Initialized)
            {
                output.Write('$');
            }
            else if (propType.GetTypeInfo().IsGenericType&& propType.GetGenericTypeDefinition() == typeof(Nullable <>))
            //deal with undefined types (nullables)
            {
                var complexType = propVal as IExpressComplexType;
                if (complexType != null)
                {
                    output.Write('(');
                    var first = true;
                    foreach (var compVal in complexType.Properties)
                    {
                        if (!first)
                        {
                            output.Write(',');
                        }
                        WriteProperty(compVal.GetType(), compVal, output, map, metadata);
                        first = false;
                    }
                    output.Write(')');
                }
                else if ((propVal is IExpressValueType))
                {
                    var expressVal = (IExpressValueType)propVal;
                    WriteValueType(expressVal.UnderlyingSystemType, expressVal.Value, output);
                }
                else // if (propVal.GetType().IsEnum)
                {
                    WriteValueType(propVal.GetType(), propVal, output);
                }
            }
            else if (typeof(IExpressComplexType).GetTypeInfo().IsAssignableFrom(propType))
            {
                output.Write('(');
                var first = true;
                foreach (var compVal in ((IExpressComplexType)propVal).Properties)
                {
                    if (!first)
                    {
                        output.Write(',');
                    }
                    WriteProperty(compVal.GetType(), compVal, output, map, metadata);
                    first = false;
                }
                output.Write(')');
            }
            else if (typeof(IExpressValueType).GetTypeInfo().IsAssignableFrom(propType))
            //value types with a single property (IfcLabel, IfcInteger)
            {
                var realType = propVal.GetType();
                if (realType != propType)
                //we have a type but it is a select type use the actual value but write out explicitly
                {
                    output.Write(realType.Name.ToUpper());
                    output.Write('(');
                    WriteProperty(realType, propVal, output, map, metadata);
                    output.Write(')');
                }
                else //need to write out underlying property value
                {
                    var expressVal = (IExpressValueType)propVal;
                    WriteValueType(expressVal.UnderlyingSystemType, expressVal.Value, output);
                }
            }
            else if (typeof(IExpressEnumerable).GetTypeInfo().IsAssignableFrom(propType) &&
                     (itemType = propType.GetItemTypeFromGenericType()) != null)
            //only process lists that are real lists, see Cartesian point
            {
                output.Write('(');
                var first = true;
                foreach (var item in ((IExpressEnumerable)propVal))
                {
                    if (!first)
                    {
                        output.Write(',');
                    }
                    WriteProperty(itemType, item, output, map, metadata);
                    first = false;
                }
                output.Write(')');
            }
            else if (typeof(IPersistEntity).GetTypeInfo().IsAssignableFrom(propType))
            //all writable entities must support this interface and ExpressType have been handled so only entities left
            {
                output.Write('#');
                var label = ((IPersistEntity)propVal).EntityLabel;
                int mapLabel;
                if (map != null && map.TryGetValue(label, out mapLabel))
                {
                    label = mapLabel;
                }
                output.Write(label);
            }
            else if (propType.GetTypeInfo().IsValueType || propVal is string || propVal is byte[]) //it might be an in-built value type double, string etc.
            {
                WriteValueType(propVal.GetType(), propVal, output);
            }
            else if (typeof(IExpressSelectType).GetTypeInfo().IsAssignableFrom(propType))
            // a select type get the type of the actual value
            {
                if (propVal.GetType().GetTypeInfo().IsValueType) //we have a value type, so write out explicitly
                {
                    var type = metadata.ExpressType(propVal.GetType());
                    output.Write(type.ExpressNameUpper);
                    output.Write('(');
                    WriteProperty(propVal.GetType(), propVal, output, map, metadata);
                    output.Write(')');
                }
                else //could be anything so re-evaluate actual type
                {
                    WriteProperty(propVal.GetType(), propVal, output, map, metadata);
                }
            }
            else
            {
                throw new Exception(string.Format("Entity  has illegal property {0} of type {1}",
                                                  propType.Name, propType.Name));
            }
        }
 public ExpressType Resolve(ExpressType abstractType, ReferenceContext context, ExpressMetaData metaData)
 {
     return(metaData.ExpressType(typeof(StringValue)));
 }