예제 #1
0
        private static void SerializeStructure(EdiWriter writer, Stack <EdiStructure> stack, EdiPathComparer structuralComparer = null)
        {
            structuralComparer = structuralComparer ?? new EdiPathComparer(writer.Grammar);
            var structure = stack.Peek();
            var properies = structure.GetOrderedProperties(structuralComparer);

            foreach (var property in properies)
            {
                var value = property.Info.GetValue(structure.Instance);
                if (property.ValueInfo != null)
                {
                    var path         = (EdiPath)writer.Path;
                    var propertyPath = property.PathInfo.PathInternal;
                    var container    = stack.Skip(1).FirstOrDefault();
                    if (propertyPath.Segment.IsWildcard)
                    {
                        if (container.Descriptor.Path.HasValue && !container.Descriptor.Path.Value.Segment.IsWildcard)
                        {
                            propertyPath = new EdiPath(container.Descriptor.Path.Value.Segment, propertyPath.Element, propertyPath.Component);
                        }
                    }
                    if (propertyPath.Element.IsWildcard)
                    {
                        propertyPath = new EdiPath(propertyPath.Segment, new EdiPathFragment(structure.Index.ToString()), propertyPath.Component);
                    }
                    if (path.Segment != propertyPath.Segment ||
                        structuralComparer.Compare(path, propertyPath) > 0)
                    {
                        writer.WriteSegmentName(propertyPath.Segment);
                        path = (EdiPath)writer.Path;
                    }
                    // the following loop handles the write of unmapped preceding elements/components to the one being writen
                    // so that path progression stays intact even though we do not have all properties present on the model.

                    while (structuralComparer.Compare(path, propertyPath) < 0)
                    {
                        if (!path.Element.Equals(propertyPath.Element))
                        {
                            if (path.ElementIndex == 0 && writer.WriteState != WriteState.Component && writer.WriteState != WriteState.Element)
                            {
                                writer.WriteToken(EdiToken.Null);
                            }
                            else
                            {
                                writer.WriteToken(EdiToken.ElementStart);
                            }
                        }
                        else if (!path.Component.Equals(propertyPath.Component))
                        {
                            if (path.ComponentIndex == 0 && writer.WriteState != WriteState.Component)
                            {
                                writer.WriteToken(EdiToken.Null);
                            }
                            else
                            {
                                writer.WriteToken(EdiToken.ComponentStart);
                            }
                        }
                        path = (EdiPath)writer.Path;
                    }
                    // handle auto generated values.
                    if (property.AutoGenerationInfo != null)
                    {
                        // do stuff.
                        // there should be plenty of things to work with inside the EdiWriter itself.
                        // We are already keeping keeping track of current position with an index.
                        // But it may need to track more stuff in order for this to happen.
                    }
                    writer.WriteValue(value, property.ValueInfo.Picture, property.ValueInfo.Format);
                }
                else
                {
                    // this is somekind of structure. Group/Message/Segment/SegmentGroup/Element
                    // is it a collection of some kind?
                    var container = property.Attributes.InferStructure();
                    if (property.Info.PropertyType.IsCollectionType())
                    {
                        var itemType   = default(Type);
                        var collection = (value ?? new object[0]) as IList;
                        if (property.Info.PropertyType.IsArray)
                        {
                            itemType = property.Info.PropertyType.GetElementType();
                        }
                        else
                        {
                            itemType = property.Info.PropertyType.GetGenericArguments().First();
                        }
                        for (var i = 0; i < collection.Count; i++)
                        {
                            var item = collection[i];
                            if (stack.Count == 0)
                            {
                                throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {itemType.Name}");
                            }
                            while (stack.Peek().StructureType >= container)
                            {
                                var previous = stack.Pop();
                            }
                            stack.Push(new EdiStructure(container, stack.Peek(), property, item, i, null));
                            SerializeStructure(writer, stack, structuralComparer);
                        }
                    }
                    else
                    {
                        // or a simple Container.
                        if (stack.Count == 0)
                        {
                            throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {property.Info.PropertyType.Name}");
                        }
                        while (stack.Peek().StructureType >= container)
                        {
                            var previous = stack.Pop();
                        }
                        if (value == null)
                        {
                            continue;
                        }
                        stack.Push(new EdiStructure(container, stack.Peek(), property, value));
                        SerializeStructure(writer, stack, structuralComparer);
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Serializes the structure.
        /// </summary>
        /// <param name="writer">Writer.</param>
        /// <param name="stack">Stack.</param>
        /// <param name="structuralComparer">Structural comparer.</param>
        private static void SerializeStructure(EdiWriter writer, Stack <EdiStructure> stack, EdiPathComparer structuralComparer = null)
        {
            structuralComparer = structuralComparer ?? new EdiPathComparer(writer.Grammar);
            var structure = stack.Peek();
            var properies = structure.GetOrderedProperties(structuralComparer);

            foreach (var property in properies)
            {
                var value = property.Info.GetValue(structure.Instance);
                if (property.ValueInfo != null)
                {
                    var path = (EdiPath)writer.Path;
                    if (path.Segment != property.PathInfo.Segment ||
                        structuralComparer.Compare(path, property.PathInfo.PathInternal) > 0)
                    {
                        writer.WriteSegmentName(property.PathInfo.Segment);
                    }

                    while (structuralComparer.Compare(path, property.PathInfo.PathInternal) < 0)
                    {
                        path = (EdiPath)writer.Path;
                        if (path.ElementIndex != property.PathInfo.ElementIndex)
                        {
                            writer.WriteToken(EdiToken.ElementStart);
                        }
                        else if (path.ComponentIndex != property.PathInfo.ComponentIndex)
                        {
                            writer.WriteToken(EdiToken.ComponentStart);
                        }
                    }
                    writer.WriteValue(value, property.ValueInfo.Picture, property.ValueInfo.Format);
                }
                else
                {
                    // this is somekind of structure. Group/Message/Segment/SegmentGroup/Element
                    // is it a collection of some kind?
                    var container = property.Attributes.InferStructure();
                    if (property.Info.PropertyType.IsCollectionType())
                    {
                        var itemType   = default(Type);
                        var collection = (value ?? new object[0]) as IList;
                        if (property.Info.PropertyType.IsArray)
                        {
                            itemType = property.Info.PropertyType.GetElementType();
                        }
                        else
                        {
                            itemType = property.Info.PropertyType.GetGenericArguments().First();
                        }
                        for (var i = 0; i < collection.Count; i++)
                        {
                            var item = collection[i];
                            if (stack.Count == 0)
                            {
                                throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {itemType.Name}");
                            }
                            while (stack.Peek().Container >= container)
                            {
                                var previous = stack.Pop();
                            }
                            stack.Push(new EdiStructure(container, item, i, null));
                            SerializeStructure(writer, stack, structuralComparer);
                        }
                    }
                    else
                    {
                        // or a simple Container.
                        if (stack.Count == 0)
                        {
                            throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {property.Info.PropertyType.Name}");
                        }
                        while (stack.Peek().Container >= container)
                        {
                            var previous = stack.Pop();
                        }
                        if (value == null)
                        {
                            continue;
                        }
                        stack.Push(new EdiStructure(container, value));
                        SerializeStructure(writer, stack, structuralComparer);
                    }
                }
            }
        }
예제 #3
0
        internal void PopulateValue(EdiReader reader, Stack <EdiStructure> stack, ref EdiPathComparer structuralComparer)
        {
            structuralComparer = new EdiPathComparer(reader.Grammar);
            var current     = stack.Peek();
            var maxLevelsUp = 0;
            var level       = 0;

            // stack always enumerates backwards so this is a search upwards :-)
            // we search only if we need to have more than one property populated with the value from the reader.
            // maxLevelsUp = zero means only the current level (quicker).
            foreach (var structure in stack)
            {
                if (level++ > maxLevelsUp)
                {
                    break;
                }
                var typeDescriptor = structure.Descriptor;
                var valueProps     = typeDescriptor.Properties
                                     .Where(p => p.ValueInfo != null &&
                                            p.Path != null &&
                                            (((EdiPath)p.Path).Equals(reader.Path) || structure.CachedReads.ContainsPath(p.Path))
                                            ).OrderBy(p => (EdiPath)p.Path, structuralComparer).ToArray();

                for (var i = 0; i < valueProps.Length; i++)
                {
                    var descriptor = valueProps[i];
                    // should I use the text reader?
                    // Values must be read only once on first pass!
                    // Otherwise the reader position moves forward
                    // and the serializer gets out of sync.
                    var useTheReader = current == structure && reader.TokenType == EdiToken.ComponentStart && ((EdiPath)descriptor.Path).Equals(reader.Path) && i == 0;
                    switch (ConvertUtils.GetTypeCode(descriptor.Info.PropertyType))
                    {
                    case PrimitiveTypeCode.Empty: break;

                    case PrimitiveTypeCode.Object:
                        PopulateObjectValue(reader, structure, descriptor, useTheReader);
                        break;

                    case PrimitiveTypeCode.Char:
                    case PrimitiveTypeCode.CharNullable:
                        PopulateCharValue(reader, structure, descriptor, useTheReader);
                        break;

                    case PrimitiveTypeCode.Boolean:
                    case PrimitiveTypeCode.BooleanNullable:
                        PopulateBooleanValue(reader, structure, descriptor, useTheReader);
                        break;

                    case PrimitiveTypeCode.SByte: break;

                    case PrimitiveTypeCode.SByteNullable: break;

                    case PrimitiveTypeCode.Int16: break;

                    case PrimitiveTypeCode.Int16Nullable: break;

                    case PrimitiveTypeCode.UInt16: break;

                    case PrimitiveTypeCode.UInt16Nullable: break;

                    case PrimitiveTypeCode.Int32:
                    case PrimitiveTypeCode.Int32Nullable:
                        PopulateInt32Value(reader, structure, descriptor, useTheReader);
                        break;

                    case PrimitiveTypeCode.Byte: break;

                    case PrimitiveTypeCode.ByteNullable: break;

                    case PrimitiveTypeCode.UInt32: break;

                    case PrimitiveTypeCode.UInt32Nullable: break;

                    case PrimitiveTypeCode.Int64: break;

                    case PrimitiveTypeCode.Int64Nullable: break;

                    case PrimitiveTypeCode.UInt64: break;

                    case PrimitiveTypeCode.UInt64Nullable: break;

                    case PrimitiveTypeCode.Single:
                    case PrimitiveTypeCode.SingleNullable:
                    case PrimitiveTypeCode.Double:
                    case PrimitiveTypeCode.DoubleNullable:
                    case PrimitiveTypeCode.Decimal:
                    case PrimitiveTypeCode.DecimalNullable:
                        PopulateDecimalValue(reader, structure, descriptor, useTheReader);
                        break;

                    case PrimitiveTypeCode.DateTime:
                    case PrimitiveTypeCode.DateTimeNullable:
                        PopulateDateTimeValue(reader, structure, descriptor, useTheReader);
                        break;

                    case PrimitiveTypeCode.DateTimeOffset: break;

                    case PrimitiveTypeCode.DateTimeOffsetNullable: break;

                    case PrimitiveTypeCode.Guid: break;

                    case PrimitiveTypeCode.GuidNullable: break;

                    case PrimitiveTypeCode.TimeSpan: break;

                    case PrimitiveTypeCode.TimeSpanNullable: break;

                    case PrimitiveTypeCode.BigInteger: break;

                    case PrimitiveTypeCode.BigIntegerNullable: break;

                    case PrimitiveTypeCode.Uri: break;

                    case PrimitiveTypeCode.String:
                        PopulateStringValue(reader, structure, descriptor, useTheReader);
                        break;

                    case PrimitiveTypeCode.Bytes: break;

                    case PrimitiveTypeCode.DBNull: break;
                    }
                }
            }
        }
예제 #4
0
        private static void SerializeStructure(EdiWriter writer, Stack <EdiStructure> stack, EdiPathComparer structuralComparer = null)
        {
            structuralComparer = structuralComparer ?? new EdiPathComparer(writer.Grammar);
            var structure = stack.Peek();
            var properies = structure.GetOrderedProperties(structuralComparer);

            foreach (var property in properies)
            {
                var value = property.Info.GetValue(structure.Instance);
                if (property.ValueInfo != null)
                {
                    var path = (EdiPath)writer.Path;
                    if (path.Segment != property.PathInfo.Segment ||
                        structuralComparer.Compare(path, property.PathInfo.PathInternal) > 0)
                    {
                        writer.WriteSegmentName(property.PathInfo.Segment);
                        path = (EdiPath)writer.Path;
                    }
                    // the following loop handles the write of unmapped preceding elements/components to the one being writen
                    // so that path progression stays intact even though we do not have all properties present on the model.
                    // TODO: Potentialy this is related to compression.

                    while (structuralComparer.Compare(path, property.PathInfo.PathInternal) < 0)
                    {
                        path = (EdiPath)writer.Path;
                        if (path.ElementIndex == 0 && writer.WriteState != WriteState.Component && writer.WriteState != WriteState.Element)
                        {
                            writer.WriteToken(EdiToken.Null);
                        }
                        else if (path.ElementIndex != property.PathInfo.ElementIndex)
                        {
                            writer.WriteToken(EdiToken.ElementStart);
                        }
                        else if (path.ComponentIndex == 0 && writer.WriteState != WriteState.Component && writer.WriteState != WriteState.Element)
                        {
                            writer.WriteToken(EdiToken.Null);
                        }
                        else if (path.ComponentIndex != property.PathInfo.ComponentIndex)
                        {
                            writer.WriteToken(EdiToken.ComponentStart);
                        }
                    }
                    writer.WriteValue(value, property.ValueInfo.Picture, property.ValueInfo.Format);
                }
                else
                {
                    // this is somekind of structure. Group/Message/Segment/SegmentGroup/Element
                    // is it a collection of some kind?
                    var container = property.Attributes.InferStructure();
                    if (property.Info.PropertyType.IsCollectionType())
                    {
                        var itemType   = default(Type);
                        var collection = (value ?? new object[0]) as IList;
                        if (property.Info.PropertyType.IsArray)
                        {
                            itemType = property.Info.PropertyType.GetElementType();
                        }
                        else
                        {
                            itemType = property.Info.PropertyType.GetGenericArguments().First();
                        }
                        for (var i = 0; i < collection.Count; i++)
                        {
                            var item = collection[i];
                            if (stack.Count == 0)
                            {
                                throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {itemType.Name}");
                            }
                            while (stack.Peek().StructureType >= container)
                            {
                                var previous = stack.Pop();
                            }
                            stack.Push(new EdiStructure(container, stack.Peek(), property, item, i, null));
                            SerializeStructure(writer, stack, structuralComparer);
                        }
                    }
                    else
                    {
                        // or a simple Container.
                        if (stack.Count == 0)
                        {
                            throw new EdiException($"Serialization stack empty while in the middle of proccessing a collection of {property.Info.PropertyType.Name}");
                        }
                        while (stack.Peek().StructureType >= container)
                        {
                            var previous = stack.Pop();
                        }
                        if (value == null)
                        {
                            continue;
                        }
                        stack.Push(new EdiStructure(container, stack.Peek(), property, value));
                        SerializeStructure(writer, stack, structuralComparer);
                    }
                }
            }
        }