Esempio n. 1
0
        private EdiPropertyDescriptor FindForCurrentSegment(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType)
        {
            var candidates = currentStructure.GetMatchingProperties(newContainerType);

            if (candidates.Length == 0)
            {
                return(null);
            }
            var property = default(EdiPropertyDescriptor);

            if (reader.TokenType == EdiToken.SegmentName || currentStructure.CachedReads.Count > 0)
            {
                var segmentName = reader.TokenType == EdiToken.SegmentName ? reader.Value : ((EdiPath)currentStructure.CachedReads.Peek().Path).Segment;
                var matches     = candidates.Where(p => segmentName.Equals(p.Segment)).ToArray();
                if (matches.Length == 0)
                {
                    property = null;
                }
                else if (matches.Length == 1 && matches[0].Conditions == null)
                {
                    property = matches[0];
                }
                else
                {
                    property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
                }
            }
            return(property);
        }
Esempio n. 2
0
        internal static void PopulateInt32Value(EdiReader reader, EdiStructure structure, EdiPropertyDescriptor descriptor, bool read)
        {
            var cache     = structure.CachedReads;
            var valueInfo = descriptor.ValueInfo;

            if (!descriptor.Info.PropertyType.IsEnum())
            {
                var integer = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsInt32(valueInfo.Path, reader.Culture) :
                              read?reader.ReadAsInt32() : (int?)reader.Value;

                if (integer.HasValue)
                {
                    descriptor.Info.SetValue(structure.Instance, ConvertUtils.ConvertOrCast(integer.Value, CultureInfo.InvariantCulture, descriptor.Info.PropertyType));
                }
            }
            else
            {
                var enumValueString = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsString(valueInfo.Path) :
                                      read?reader.ReadAsString() : (string)reader.Value;

                if (!string.IsNullOrEmpty(enumValueString))
                {
                    descriptor.Info.SetValue(structure.Instance, ConvertUtils.ConvertOrCast(enumValueString, CultureInfo.InvariantCulture, descriptor.Info.PropertyType));
                }
            }
        }
Esempio n. 3
0
        internal static void PopulateBooleanValue(EdiReader reader, EdiStructure structure, EdiPropertyDescriptor descriptor, bool read)
        {
            var cache     = structure.CachedReads;
            var valueInfo = descriptor.ValueInfo;
            var text      = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsString(valueInfo.Path) :
                            read?reader.ReadAsString() : (string)reader.Value;

            if (!string.IsNullOrEmpty(text))
            {
                var integerValue = default(int);
                var booleanValue = default(bool);
                if (int.TryParse(text, NumberStyles.Integer, reader.Culture, out integerValue))
                {
                    booleanValue = integerValue == 1;
                }
                else if (bool.TryParse(text, out booleanValue))
                {
                }
                else
                {
                    throw new EdiException("Unable to convert string '{0}' to boolean.".FormatWith(reader.Culture, text));
                }
                descriptor.Info.SetValue(structure.Instance, booleanValue);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Finds for current element.
        /// </summary>
        /// <returns>The for current element.</returns>
        /// <param name="reader">Reader.</param>
        /// <param name="currentStructure">Current structure.</param>
        /// <param name="newContainerType">New container type.</param>
        private EdiPropertyDescriptor FindForCurrentElement(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType)
        {
            var candidates = currentStructure.GetMatchingProperties(newContainerType);

            if (candidates.Length == 0)
            {
                return(null);
            }
            var property = default(EdiPropertyDescriptor);

            if (reader.TokenType == EdiToken.ElementStart)
            {
                var matches = candidates.Where(p => p.PathInfo.PathInternal.ToString("E").Equals(reader.Path)).ToArray();
                if (matches.Length == 0)
                {
                    property = null;
                }
                else if (matches.Length == 1 && matches[0].ConditionInfo == null)
                {
                    property = matches[0];
                }
                else
                {
                    property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
                }
            }
            return(property);
        }
Esempio n. 5
0
        /// <summary>
        /// Conditionals the match.
        /// </summary>
        /// <returns>The match.</returns>
        /// <param name="reader">Reader.</param>
        /// <param name="currentStructure">Current structure.</param>
        /// <param name="newContainerType">New container type.</param>
        /// <param name="matches">Matches.</param>
        private static EdiPropertyDescriptor ConditionalMatch(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, EdiPropertyDescriptor[] matches)
        {
            if (!matches.All(p => p.ConditionInfo != null))
            {
                throw new EdiException(
                          "More than one properties on type '{0}' have the '{1}' attribute. Please add a 'Condition' attribute to all properties in order to discriminate where each {2} will go."
                          .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType, newContainerType));
            }
            if (matches.Select(p => p.Path).Distinct().Count() != 1)
            {
                throw new EdiException("More than one properties on type '{0}' have the '{1}' attribute but the 'Condition' attribute has a different search path declared."
                                       .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType));
            }

            var readCache = currentStructure.CachedReads;
            var path      = string.Empty;

            do
            {
                reader.Read();
                path = reader.Path;
                readCache.Enqueue(new EdiEntry(path, reader.TokenType, reader.Value as string));
            } while (reader.TokenType != EdiToken.SegmentStart && matches[0].Path != path);

            var discriminator = reader.ReadAsString();
            var property      = matches.SingleOrDefault(p => p.ConditionInfo.MatchValue == discriminator);

            readCache.Enqueue(new EdiEntry(path, reader.TokenType, discriminator));
            return(property);
        }
Esempio n. 6
0
 internal static void PopulateObjectValue(EdiReader reader, EdiStructure structure, EdiPropertyDescriptor descriptor, bool read) {
     var cache = structure.CachedReads;
     var valueInfo = descriptor.ValueInfo;
     var text = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsString(valueInfo.Path) :
                                              read ? reader.ReadAsString() : (string)reader.Value;
     descriptor.Info.SetValue(structure.Instance, ConvertUtils.ConvertOrCast(text, reader.Culture, descriptor.Info.PropertyType));
 }
Esempio n. 7
0
 internal static void PopulateDateTimeValue(EdiReader reader, EdiStructure structure, EdiPropertyDescriptor descriptor, bool read) {
     var cache = structure.CachedReads;
     var valueInfo = descriptor.ValueInfo;
     var dateString = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsString(valueInfo.Path) :
                                                    read ? reader.ReadAsString() : (string)reader.Value;
     if (dateString != null) {
         dateString = dateString.Substring(0, valueInfo.Picture.Scale);
         var date = default(DateTime);
         if (dateString.TryParseEdiDate(valueInfo.Format, CultureInfo.InvariantCulture, out date)) {
             var existingDateObject = descriptor.Info.GetValue(structure.Instance);
             var existingDate = default(DateTime);
             if (existingDateObject != null && !existingDateObject.Equals(default(DateTime))) {
                 if (existingDateObject is DateTime?) {
                     existingDate = ((DateTime?)existingDateObject).Value;
                 } else {
                     existingDate = ((DateTime)existingDateObject);
                 }
                 if (date - date.Date == default(TimeSpan)) {
                     date = date.Date.Add(existingDate - existingDate.Date);
                 } else {
                     date = existingDate.Add(date - date.Date);
                 }
             }
             descriptor.Info.SetValue(structure.Instance, date);
         }
     }
 }
Esempio n. 8
0
 internal static void PopulateStringValue(EdiReader reader, EdiStructure structure, EdiPropertyDescriptor descriptor, bool read) {
     var cache = structure.CachedReads;
     var valueInfo = descriptor.ValueInfo;
     var text = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsString(valueInfo.Path) :
                                              read ? reader.ReadAsString() : (string)reader.Value;
     descriptor.Info.SetValue(structure.Instance, text);
 }
Esempio n. 9
0
        private static EdiPropertyDescriptor ConditionalMatch(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, EdiPropertyDescriptor[] candidates)
        {
            if (!candidates.All(p => p.Conditions != null))
            {
                throw new EdiException(
                          "More than one properties on type '{0}' have the '{1}' attribute. Please add a 'Condition' attribute to all properties in order to discriminate where each {2} will go."
                          .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType, newContainerType));
            }
            var conditionPaths = candidates.SelectMany(p => p.Conditions.Select(c => c.Path)).Distinct().ToArray();
            //if (conditionPaths.Length != 1) {
            //    throw new EdiException("More than one properties on type '{0}' have the '{1}' attribute but the 'Condition' attribute has a different search path declared."
            //        .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType));
            //}
            var cache           = currentStructure.CachedReads;
            var findingsPerPath = new Dictionary <string, string>();

            foreach (var path in conditionPaths)
            {
                // search the cache first.
                var value = default(string);
                var found = false;
                if (cache.Count > 0)
                {
                    var entry = cache.Where(r => r.Path == path).SingleOrDefault();
                    found = !default(EdiEntry).Equals(entry);
                }
                if (!found)
                {
                    // if nothing found search the reader (arvance forward).
                    do
                    {
                        if (reader.Path == path)
                        {
                            value = reader.ReadAsString();
                            cache.Enqueue(new EdiEntry(reader.Path, reader.TokenType, value));
                            found = true;
                            value = reader.Value as string; // if found break;
                            break;
                        }
                        else
                        {
                            reader.Read();
                            cache.Enqueue(new EdiEntry(reader.Path, reader.TokenType, reader.Value as string));
                        }
                    } while (!found || reader.TokenType != EdiToken.SegmentStart);
                }

                if (found)
                {
                    var property = candidates.SingleOrDefault(p => p.PathInfo.PathInternal == path && p.Conditions.Any(c => c.SatisfiedBy(value)));
                    if (property != null)
                    {
                        return(property);
                    }
                }
            }

            return(null);
        }
Esempio n. 10
0
 internal static void PopulateDecimalValue(EdiReader reader, EdiStructure structure, EdiPropertyDescriptor descriptor, bool read) {
     var cache = structure.CachedReads;
     var valueInfo = descriptor.ValueInfo;
     var numberFloat = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsDecimal(valueInfo.Path, descriptor.ValueInfo.Picture, reader.Grammar.DecimalMark) :
                                                     read ? reader.ReadAsDecimal(descriptor.ValueInfo.Picture) : (decimal?)reader.Value;
     if (numberFloat != null) {
         descriptor.Info.SetValue(structure.Instance, numberFloat);
     }
 }
Esempio n. 11
0
        internal static void PopulateCharValue(EdiReader reader, EdiStructure structure, EdiPropertyDescriptor descriptor, bool read) {
            var cache = structure.CachedReads;
            var valueInfo = descriptor.ValueInfo;
            var text = cache.ContainsPath(valueInfo.Path) ? cache.ReadAsString(valueInfo.Path) :
                                                     read ? reader.ReadAsString() : (string)reader.Value;

            if (!string.IsNullOrEmpty(text)) {
                if (text.Length > 1)
                    throw new EdiException("Unable to convert string '{0}' to char. It is more than 1 character long.".FormatWith(reader.Culture, text));
                descriptor.Info.SetValue(structure.Instance, text[0]);
            }
        }
Esempio n. 12
0
        private EdiPropertyDescriptor FindForCurrentElement(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, out Queue <EdiEntry> elementReads)
        {
            elementReads = null;
            var candidates = currentStructure.GetMatchingProperties(newContainerType);

            if (candidates.Length == 0)
            {
                return(null);
            }
            var property = default(EdiPropertyDescriptor);

            if (reader.TokenType == EdiToken.ElementStart || currentStructure.CachedReads.Count > 0)
            {
                var elementPath = reader.TokenType == EdiToken.ElementStart ? reader.Path : ((EdiPath)currentStructure.CachedReads.Peek().Path).ToString("E");
                var matches     = candidates.Where(p => p.PathInfo.PathInternal.Equals(elementPath)).ToArray();
                if (matches.Length == 0)
                {
                    property = null;
                }
                else if (matches.Length == 1 && matches[0].Conditions == null)
                {
                    property = matches[0];
                }
                else
                {
                    property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
                }
                if (property != null)
                {
                    elementReads = new Queue <EdiEntry>();
                    var parentCache = currentStructure.CachedReads;
                    while (parentCache.Count > 0 && elementPath == ((EdiPath)parentCache.Peek().Path).ToString("E"))
                    {
                        elementReads.Enqueue(parentCache.Dequeue());
                    }
                    //foreach (var item in currentStructure.CachedReads) {
                    //    if (elementPath == ((EdiPath)item.Path).ToString("E")) {
                    //        elementReads.Enqueue(item);
                    //    }
                    //}
                }
            }
            return(property);
        }
Esempio n. 13
0
 private EdiPropertyDescriptor FindForCurrentSegment(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType) {
     currentStructure.CachedReads.Clear();
     var candidates = currentStructure.GetMatchingProperties(newContainerType);
     if (candidates.Length == 0) {
         return null;
     }
     var property = default(EdiPropertyDescriptor);
     if (reader.TokenType == EdiToken.SegmentName) {
         var matches = candidates.Where(p => p.Segment.Equals(reader.Value)).ToArray();
         if (matches.Length == 0) {
             property = null;
         } else if (matches.Length == 1 && matches[0].Conditions == null) {
             property = matches[0];
         } else {
             property = ConditionalMatch(reader, currentStructure, newContainerType, matches);
         }
     }
     return property;
 }
Esempio n. 14
0
        private static bool PositionMatchesStructure(EdiReader reader, EdiStructure structure, string segmentName)
        {
            if (structure.Conditions == null || structure.Conditions.Length == 0)
            {
                return(true); // cannot determine.
            }
            var searchResults = SearchForward(reader, structure.CachedReads, structure.Conditions.Select(c => c.Path));

            var result = structure.ConditionStackMode == EdiConditionStackMode.All ? structure.Conditions.All(c => c.SatisfiedBy(searchResults[c.PathInternal]))
                                                                                   : structure.Conditions.Any(c => c.SatisfiedBy(searchResults[c.PathInternal]));

            if (result)
            {
                return(true);
            }

            // search siblings on the same level before returning.
            var matchingProperties = structure.Container.GetMatchingProperties(segmentName);

            if (matchingProperties == null || matchingProperties.Length == 0)
            {
                return(false);
            }
            foreach (var prop in matchingProperties)
            {
                // if there is simply a matching sibling with no conditions return ok.
                if (prop.Conditions == null)
                {
                    return(true);
                }
                searchResults = SearchForward(reader, structure.Container.CachedReads, prop.Conditions.Select(c => c.Path));

                var check = prop.ConditionStackMode == EdiConditionStackMode.All ? prop.Conditions.All(c => c.SatisfiedBy(searchResults[c.PathInternal]))
                                                                                 : prop.Conditions.Any(c => c.SatisfiedBy(searchResults[c.PathInternal]));
                if (check)
                {
                    return(true);
                }
            }
            return(false);
        }
Esempio n. 15
0
        private static EdiPropertyDescriptor ConditionalMatch(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType, params EdiPropertyDescriptor[] candidates)
        {
            if (!candidates.All(p => p.Conditions != null))
            {
                throw new EdiException(
                          "More than one properties on type '{0}' have the '{1}' attribute. Please add a 'Condition' attribute to all properties in order to discriminate where each {2} will go."
                          .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType, newContainerType));
            }

            var searchResults = SearchForward(reader, currentStructure.CachedReads, candidates.SelectMany(p => p.Conditions.Select(c => c.Path)));
            //if (searchResults.Length != 1) {
            //    throw new EdiException("More than one properties on type '{0}' have the '{1}' attribute but the 'Condition' attribute has a different search path declared."
            //        .FormatWith(CultureInfo.InvariantCulture, currentStructure.Descriptor.ClrType.Name, newContainerType));
            //}
            var property = candidates.SingleOrDefault(p => p.ConditionStackMode == EdiConditionStackMode.All ? p.Conditions.All(c => c.SatisfiedBy(searchResults[c.PathInternal]))
                                                                                                             : p.Conditions.Any(c => c.SatisfiedBy(searchResults[c.PathInternal])));

            if (property != null)
            {
                return(property);
            }
            return(null);
        }
Esempio n. 16
0
        private EdiPropertyDescriptor FindForCurrentLogicalStructure(EdiReader reader, EdiStructure currentStructure, EdiStructureType newContainerType)
        {
            var candidates = currentStructure.GetMatchingProperties(newContainerType);
            var property   = default(EdiPropertyDescriptor);

            if (candidates.Length == 0)
            {
                return(null);
            }
            if (candidates.Length == 1 && candidates[0].Conditions == null)
            {
                property = candidates[0];
            }
            else
            {
                property = ConditionalMatch(reader, currentStructure, newContainerType, candidates);
            }
            return(property);
        }