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); } }
/// <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); }
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)); } } }
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)); }
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); } } }
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); }
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); }
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]); } }
private static Dictionary <string, string> SearchForward(EdiReader reader, Queue <EdiEntry> cache, IEnumerable <string> pathsToSeekForValues) { var searchResults = pathsToSeekForValues.Distinct().ToDictionary(x => x, x => (string)null); foreach (var path in searchResults.Keys.ToArray()) { // search the cache first. var value = default(string); var found = false; if (cache.Count > 0) { var entry = cache.Where(r => r.Path == path && r.Token.IsPrimitiveToken()).SingleOrDefault(); if (!default(EdiEntry).Equals(entry)) { found = true; value = entry.Value; } } 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) { searchResults[path] = value; } } return(searchResults); }