public void UpdateContent(T data, int structureTypeId = 0) { StructureTypeId = structureTypeId; LoadNewDefaultConfig(data); var accessor = TypeAccessor.Create(typeof(T), true); var memberSet = accessor.GetMembers().Where(a => a.IsDefined(typeof(FixedWidthFileFieldAttribute))); var membersData = new List <Member>(); var attributesDict = new Dictionary <string, FixedWidthFileFieldAttribute>(); var memberNameTypeNameDict = new Dictionary <string, string>(); foreach (var member in memberSet) { var attribute = member.GetMemberAttributes <FixedWidthFileFieldAttribute>().SingleOrDefault(a => a.StructureTypeId == StructureTypeId); if (attribute != null) { membersData.Add(member); attributesDict.Add(member.Name, attribute); memberNameTypeNameDict.Add(member.Name, member.Type.Name); } } foreach (var propertyMember in membersData) { var attribute = attributesDict[propertyMember.Name]; var memberData = new FastMemberData() { Member = propertyMember, Accessor = accessor, Attribute = attribute, MemberNameTypeNameDict = memberNameTypeNameDict }; WriteData(data, memberData, FieldType.FileField); } }
public List <string> Write(List <T> data, int structureTypeId = 0) { StructureTypeId = structureTypeId; LoadNewDefaultConfig(new T()); var accessor = TypeAccessor.Create(typeof(T), true); var memberSet = accessor.GetMembers().Where(a => a.IsDefined(typeof(FixedWidthLineFieldAttribute))); var membersDict = new Dictionary <int, Member>(); var attributesDict = new Dictionary <string, FixedWidthLineFieldAttribute>(); var memberNameTypeNameDict = new Dictionary <string, string>(); foreach (var member in memberSet) { var attribute = member.GetMemberAttributes <FixedWidthLineFieldAttribute>().SingleOrDefault(a => a.StructureTypeId == StructureTypeId); if (attribute != null) { membersDict.Add(attribute.Start, member); attributesDict.Add(member.Name, attribute); memberNameTypeNameDict.Add(member.Name, member.Type.Name); } } var membersData = membersDict.OrderBy(a => a.Key).Select(a => a.Value); List <string> resultLines = new List <string>(); foreach (T element in data) { string line = String.Empty; int startPrev = 1; int lengthPrev = 0; foreach (var propertyMember in membersData) { var attribute = attributesDict[propertyMember.Name]; if (startPrev + lengthPrev != attribute.Start) { throw new InvalidOperationException($"Invalid Start or Length parameter, {attribute.Start} != {startPrev + lengthPrev}" + $", on FixedLineFieldAttribute (property {propertyMember.Name}) for StructureTypeId {StructureTypeId}"); } startPrev = attribute.Start; lengthPrev = attribute.Length; var memberData = new FastMemberData() { Member = propertyMember, Accessor = accessor, Attribute = attribute, MemberNameTypeNameDict = memberNameTypeNameDict }; line += WriteData(element, memberData, FieldType.LineField); } resultLines.Add(line); } return(resultLines); }
protected string WriteData <T>(T element, FastMemberData memberData, FieldType fieldType) { string memberName = memberData.Member.Name; var attribute = (FixedWidthAttribute)memberData.Attribute; //var value = property.GetValue(element); // With Reflection - DEPRECATED var value = memberData.Accessor[element, memberName]; string valueTypeName = memberData.MemberNameTypeNameDict[memberName]; if (attribute.PadSide == PadSide.Default) { bool isNumericType = (valueTypeName == nameof(Int32) || valueTypeName == nameof(Int64) || // IntegerNumbers valueTypeName == nameof(Decimal) || valueTypeName == nameof(Single) || valueTypeName == nameof(Double)); // or DecimalNumbers attribute.PadSide = isNumericType ? DefaultConfig.PadSideNumeric : DefaultConfig.PadSideNonNumeric; // Initial default Pad: PadNumeric-Left, PadNonNumeric-Right } char pad = ' '; string result = String.Empty; if (valueTypeName == nameof(String) || valueTypeName == nameof(Char)) { result = value?.ToString() ?? ""; } else { string format = attribute.Format; //format = format ?? DefaultFormat.GetFormat(valueTypeName); switch (valueTypeName) { case nameof(Int32): case nameof(Int64): format = format ?? DefaultConfig.FormatNumberInteger; pad = attribute.Pad != '\0' ? attribute.Pad : DefaultConfig.PadNumeric; break; case nameof(Decimal): case nameof(Single): case nameof(Double): format = format ?? DefaultConfig.FormatNumberDecimal; pad = attribute.Pad != '\0' ? attribute.Pad : DefaultConfig.PadNumeric; if (format.Contains(";")) //';' - Special custom Format that removes decimal separator ("0;00": 123.45 -> 12345) { double decimalFactor = Math.Pow(10, format.Length - 2); // "0;00".Length == 4 - 2 = 2 (10^2 = 100) switch (valueTypeName) { case nameof(Decimal): value = (decimal)value * (decimal)decimalFactor; break; case nameof(Single): value = (float)value * (float)decimalFactor; break; case nameof(Double): value = (double)value * decimalFactor; break; } } break; case nameof(Boolean): format = format ?? DefaultConfig.FormatBoolean; pad = attribute.Pad != '\0' ? attribute.Pad : DefaultConfig.PadNonNumeric; value = value.GetHashCode(); break; case nameof(DateTime): format = format ?? DefaultConfig.FormatDateTime; pad = attribute.Pad != '\0' ? attribute.Pad : DefaultConfig.PadNonNumeric; break; } value = value ?? ""; result = format != null?String.Format(CultureInfo.InvariantCulture, $"{{0:{format}}}", value) : value.ToString(); } if (result.Length > attribute.Length && attribute.Length > 0) // if too long cut it { result = result.Substring(0, attribute.Length); } else if (result.Length < attribute.Length) // if too short pad from one side { if (attribute.PadSide == PadSide.Right) { result = result.PadRight(attribute.Length, pad); } else if (attribute.PadSide == PadSide.Left) { result = result.PadLeft(attribute.Length, pad); } var numberTypesList = new List <string> { nameof(Int32), nameof(Int64), nameof(Decimal), nameof(Single), nameof(Double) }; bool isNumberType = numberTypesList.Contains(valueTypeName); if (isNumberType && result.Contains("-") && result.Substring(0, 1) == "0") // is negative Number with leading Zero { result = result.Replace("-", ""); result = "-" + result;// move sign '-'(minus) before pad } } if (fieldType == FieldType.FileField) { int lineIndex = ((FixedWidthFileFieldAttribute)attribute).LineIndex; var content = this.Content; if (lineIndex < 0) { lineIndex += content.Count + 1; } string clearString = String.Empty; clearString = attribute.Length > 0 ? content[lineIndex].Remove(attribute.StartIndex, attribute.Length) : content[lineIndex].Remove(attribute.StartIndex); content[lineIndex] = clearString.Insert(attribute.StartIndex, result); } return(result); }