public void UpdateAttributes() { _index = ColumnAttribute.McDefaultFieldIndex; Name = _memberInfo.Name; _inputNumberStyle = NumberStyles.Any; OutputFormat = ""; HasColumnAttribute = false; CharLength = 0; foreach (Object attribute in _memberInfo.GetCustomAttributes(typeof(CsvColumnAttribute), true)) { CsvColumnAttribute cca = (CsvColumnAttribute)attribute; if (!string.IsNullOrEmpty(cca.Name)) { Name = cca.Name; } _index = cca.FieldIndex; HasColumnAttribute = true; _canBeNull = cca.CanBeNull; OutputFormat = cca.OutputFormat; _inputNumberStyle = cca.NumberStyle; CharLength = cca.CharLength; } }
public void Header_SetValue_ResultAreEqual(String expected) { CsvColumnAttribute attribute = new CsvColumnAttribute(); attribute.Header = expected; Assert.AreEqual(expected, attribute.Header); }
public void Offset_SetValue_ResultAreEqual(Int32 expected) { CsvColumnAttribute attribute = new CsvColumnAttribute(); attribute.Offset = expected; Assert.AreEqual(expected, attribute.Offset); }
/// <summary> /// Tの情報をロードします。 /// setterには列番号をキーとしたsetメソッドが格納されます。 /// </summary> private void LoadType() { Type type = typeof(T); // Field, Property のみを対象とする var memberTypes = new MemberTypes[] { MemberTypes.Field, MemberTypes.Property }; // インスタンスメンバーを対象とする BindingFlags flag = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; foreach (MemberInfo member in type.GetMembers(flag).Where((member) => memberTypes.Contains(member.MemberType))) { CsvColumnAttribute csvColumn = GetCsvColumnAttribute(member); if (csvColumn == null) { continue; } int columnIndex = csvColumn.ColumnIndex; object defaultValue = csvColumn.DefaultValue; if (member.MemberType == MemberTypes.Field) { // field FieldInfo fieldInfo = type.GetField(member.Name, flag); setters [columnIndex] = (target, value) => fieldInfo.SetValue(target, GetConvertedValue(fieldInfo, value, defaultValue)); } else { // property PropertyInfo propertyInfo = type.GetProperty(member.Name, flag); setters [columnIndex] = (target, value) => propertyInfo.SetValue(target, GetConvertedValue(propertyInfo, value, defaultValue), null); } } }
public void Construction_ItemDescriptor_ResultIsColumnAreEqual() { CsvColumnAttribute column = new CsvColumnAttribute(); ItemDescriptor actual = new ItemDescriptor(column, new PropertyInfoTest()); Assert.AreEqual(column, actual.Column); }
public void CanDeserializeUsingCustomDateFormat() { DateTimeConverter converter = new DateTimeConverter(); string text = "2019/May/04 3:02:01"; CsvColumnAttribute attribute = new CsvColumnAttribute("Date") { DateFormat = "yyyy/MMM/dd H:mm:ss" }; DateTime date = converter.Deserialize(text.AsMemory(), CultureInfo.InvariantCulture, attribute); date.Should().Be(new DateTime(2019, 5, 4, 3, 2, 1)); }
public void CanSerializeUsingCustomDateFormat() { DateTimeConverter converter = new DateTimeConverter(); DateTime date = new DateTime(2019, 5, 4, 3, 2, 1); StringBuilder stringBuilder = new StringBuilder(); CsvColumnAttribute attribute = new CsvColumnAttribute("Date") { DateFormat = "yyyy/MMM/dd H:mm:ss" }; converter.AppendToStringBuilder(stringBuilder, CultureInfo.InvariantCulture, date, attribute, ','); string serialized = stringBuilder.ToString(); serialized.Should().Be("2019/May/04 3:02:01"); }
public void CsvColumnAttributeTest() { CsvColumnAttribute a = new CsvColumnAttribute(0) { Name = "foo" }; Assert.AreEqual(a.Index, 0); Assert.AreEqual(a.Name, "foo"); }
/// <summary> /// CsvReaderAttributeを読み込む /// </summary> /// <param name="info"></param> private void GetCsvReaderAttributes(MemberInfo info) { Attribute[] attrs = Attribute.GetCustomAttributes(info, typeof(CsvColumnAttribute)); foreach (Attribute attr in attrs) { CsvColumnAttribute csvattr = attr as CsvColumnAttribute; if (csvattr != null) { csvattr.PropertyName = info.Name; ReaderAttributes.Add(csvattr.columnIndex, csvattr); } } }
public void CanEmitDeserializerWithCustomDateFormat() { DateTimeConverter converter = new DateTimeConverter(); string text = "2019/May/04 3:02:01"; CsvColumnAttribute attribute = new CsvColumnAttribute("Date") { DateFormat = "yyyy/MMM/dd H:mm:ss" }; DynamicMethod deserialize = new DynamicMethod("Deserialize", typeof(DateTime), new Type[] { typeof(ReadOnlyMemory<char>), typeof(IFormatProvider) }, typeof(DateTimeConverterTests)); deserialize.GetILGenerator() .DeclareLocal<DateTime>(out LocalBuilder local) .Ldarga_S(0) .Emit(gen => converter.EmitDeserialize(gen, local, null, attribute)) .Ret(); object deserialized = deserialize.Invoke(this, new object?[] { text.AsMemory(), CultureInfo.InvariantCulture })!; deserialized.Should().Be(new DateTime(2019, 5, 4, 3, 2, 1)); }
public void ToString_ItemDescriptor_ResultAreEqual(String originName, String headerName, Int32 offsetValue) { headerName = String.IsNullOrWhiteSpace(headerName) ? "<null>" : headerName; PropertyInfoTest origin = new PropertyInfoTest { name = $"{originName}", }; CsvColumnAttribute column = new CsvColumnAttribute { Header = $"{headerName}", Offset = offsetValue, }; String expected = $"Offset: \"{offsetValue}\", Header: \"{headerName}\", Origin: \"{originName}\""; ItemDescriptor actual = new ItemDescriptor(column, origin); Assert.AreEqual(expected, actual.ToString()); }
public void CanEmitSerializerWithCustomDateFormat() { DateTimeConverter converter = new DateTimeConverter(); DateTime date = new DateTime(2019, 5, 4, 3, 2, 1); CsvColumnAttribute attribute = new CsvColumnAttribute("Date") { DateFormat = "yyyy/MMM/dd H:mm:ss" }; DynamicMethod serialize = new DynamicMethod("Serialize", typeof(string), new Type[] { typeof(DateTime), typeof(IFormatProvider), typeof(char) }, typeof(DateTimeConverterTests)); serialize.GetILGenerator() .DeclareLocal<DateTime>(out LocalBuilder local) .Newobj<StringBuilder>() .Ldarg_0() .Emit(gen => converter.EmitAppendToStringBuilder(gen, local, null, attribute)) .Callvirt<StringBuilder>("ToString") .Ret(); string serialized = (string)serialize.Invoke(null, new object?[] { date, CultureInfo.InvariantCulture, ',' })!; serialized.Should().Be("2019/May/04 3:02:01"); }
public void Construction_DefaultConstructor_ResultIsTrue() { CsvColumnAttribute attribute = new CsvColumnAttribute(); Assert.IsTrue(attribute.Header == String.Empty && attribute.Offset == -1); }
// ----------------------------- // AnalyzeTypeField // private TypeFieldInfo AnalyzeTypeField( MemberInfo mi, bool allRequiredFieldsMustHaveFieldIndex, bool allCsvColumnFieldsMustHaveFieldIndex) { TypeFieldInfo tfi = new TypeFieldInfo(); tfi.memberInfo = mi; if (mi is PropertyInfo) { tfi.fieldType = ((PropertyInfo)mi).PropertyType; } else { tfi.fieldType = ((FieldInfo)mi).FieldType; } // parseNumberMethod will remain null if the property is not a numeric type. // This would be the case for DateTime, Boolean, String and custom types. // In those cases, just use a TypeConverter. // // DateTime and Boolean also have Parse methods, but they don't provide // functionality that TypeConverter doesn't give you. tfi.parseNumberMethod = tfi.fieldType.GetMethod("Parse", new Type[] { typeof(String), typeof(NumberStyles), typeof(IFormatProvider) }); if (tfi.parseNumberMethod == null) { if (m_fileDescription.UseOutputFormatForParsingCsvValue) { tfi.parseExactMethod = tfi.fieldType.GetMethod("ParseExact", new Type[] { typeof(string), typeof(string), typeof(IFormatProvider) }); } tfi.typeConverter = null; if (tfi.parseExactMethod == null) { tfi.typeConverter = TypeDescriptor.GetConverter(tfi.fieldType); } } // ----- // Process the attributes tfi.index = Int32.MaxValue; tfi.name = mi.Name; tfi.inputNumberStyle = NumberStyles.Any; tfi.outputFormat = ""; tfi.hasColumnAttribute = false; tfi.charLength = 0; foreach (Object attribute in mi.GetCustomAttributes(typeof(CsvColumnAttribute), true)) { CsvColumnAttribute cca = (CsvColumnAttribute)attribute; if (!string.IsNullOrEmpty(cca.Name)) { tfi.name = cca.Name; } tfi.index = cca.FieldIndex; tfi.hasColumnAttribute = true; tfi.canBeNull = cca.CanBeNull; tfi.outputFormat = cca.OutputFormat; tfi.inputNumberStyle = cca.NumberStyle; tfi.charLength = cca.CharLength; } // ----- if (allCsvColumnFieldsMustHaveFieldIndex && tfi.hasColumnAttribute && tfi.index == Int32.MaxValue) { throw new ToBeWrittenButMissingFieldIndexException( typeof(T).ToString(), tfi.name); } if (allRequiredFieldsMustHaveFieldIndex && (!tfi.canBeNull) && (tfi.index == Int32.MaxValue)) { throw new RequiredButMissingFieldIndexException( typeof(T).ToString(), tfi.name); } // ----- return(tfi); }
/// <summary> /// Erstellt eine neue Instanz für eine gefundene Eigenschaft /// </summary> /// <param name="initCsvAttribute">CsvAttribut, dass in der Klasse angegeben wurde</param> /// <param name="initPropertyInfo">PropertyInfo für die Eigenschaft der Klasse</param> public CsvFieldInfo(CsvColumnAttribute initCsvAttribute, System.Reflection.PropertyInfo initPropertyInfo) : base() { csvColumnAttribute = initCsvAttribute; propertyInfo = initPropertyInfo; }
/// <summary> /// The parameterized class constructor. /// </summary> /// <remarks> /// This constructor initializes an instance of this class with the /// characteristics of a CSV file column. /// </remarks> /// <param name="column"> /// An instance of class <see cref="CsvColumnAttribute"/> that describes /// the characteristics of a CSV column. /// </param> /// <param name="origin"> /// An instance of class <see cref="PropertyInfo"/> that describes /// the characteristics of the corresponding property. /// </param> /// <exception cref="ArgumentNullException"> /// This exception is thrown if one of the parameters is <null>. /// </exception> public ItemDescriptor(CsvColumnAttribute column, PropertyInfo origin) : base() { this.Column = column ?? throw new ArgumentNullException(nameof(column)); this.Origin = origin ?? throw new ArgumentNullException(nameof(origin)); }