/// <summary> /// Check the Attributes on the field and return a structure containing /// the settings for this file. /// </summary> /// <param name="fi">Information about this field</param> /// <param name="recordAttribute">Type of record we are reading</param> /// <returns>Null if not used</returns> public static FieldBase CreateField(FieldInfo fi, TypedRecordAttribute recordAttribute) { // If ignored, return null #pragma warning disable 612,618 // disable obsole warning if (fi.IsDefined(typeof(FieldNotInFileAttribute), true) || fi.IsDefined(typeof(FieldIgnoredAttribute), true)) #pragma warning restore 612,618 { return(null); } FieldBase res = null; var attributes = (FieldAttribute[])fi.GetCustomAttributes(typeof(FieldAttribute), true); // CHECK USAGE ERRORS !!! // Fixed length record and no attributes at all if (recordAttribute is FixedLengthRecordAttribute && attributes.Length == 0) { throw new BadUsageException("The field: '" + fi.Name + "' must be marked the FieldFixedLength attribute because the record class is marked with FixedLengthRecord."); } if (attributes.Length > 1) { throw new BadUsageException("The field: '" + fi.Name + "' has a FieldFixedLength and a FieldDelimiter attribute."); } if (recordAttribute is DelimitedRecordAttribute && fi.IsDefined(typeof(FieldAlignAttribute), false)) { throw new BadUsageException("The field: '" + fi.Name + "' can't be marked with FieldAlign attribute, it is only valid for fixed length records and are used only for write purpose."); } if (fi.FieldType.IsArray == false && fi.IsDefined(typeof(FieldArrayLengthAttribute), false)) { throw new BadUsageException("The field: '" + fi.Name + "' can't be marked with FieldArrayLength attribute is only valid for array fields."); } // PROCESS IN NORMAL CONDITIONS if (attributes.Length > 0) { FieldAttribute fieldAttb = attributes[0]; if (fieldAttb is FieldFixedLengthAttribute) { // Fixed Field if (recordAttribute is DelimitedRecordAttribute) { throw new BadUsageException("The field: '" + fi.Name + "' can't be marked with FieldFixedLength attribute, it is only for the FixedLengthRecords not for delimited ones."); } var attbFixedLength = (FieldFixedLengthAttribute)fieldAttb; var attbAlign = Attributes.GetFirst <FieldAlignAttribute>(fi); res = new FixedLengthField(fi, attbFixedLength.Length, attbAlign); ((FixedLengthField)res).FixedMode = ((FixedLengthRecordAttribute)recordAttribute).FixedMode; } else if (fieldAttb is FieldDelimiterAttribute) { // Delimited Field if (recordAttribute is FixedLengthRecordAttribute) { throw new BadUsageException("The field: '" + fi.Name + "' can't be marked with FieldDelimiter attribute, it is only for DelimitedRecords not for fixed ones."); } res = new DelimitedField(fi, ((FieldDelimiterAttribute)fieldAttb).Delimiter); } else { throw new BadUsageException("Custom field attributes are not currently supported. Unknown attribute: " + fieldAttb.GetType().Name + " on field: " + fi.Name); } } else // attributes.Length == 0 { var delimitedRecordAttribute = recordAttribute as DelimitedRecordAttribute; if (delimitedRecordAttribute != null) { res = new DelimitedField(fi, delimitedRecordAttribute.Separator); } } if (res != null) { // FieldDiscarded res.Discarded = fi.IsDefined(typeof(FieldValueDiscardedAttribute), false); // FieldTrim Attributes.WorkWithFirst <FieldTrimAttribute>(fi, (x) => { res.TrimMode = x.TrimMode; res.TrimChars = x.TrimChars; }); // FieldQuoted Attributes.WorkWithFirst <FieldQuotedAttribute>(fi, (x) => { if (res is FixedLengthField) { throw new BadUsageException( "The field: '" + fi.Name + "' can't be marked with FieldQuoted attribute, it is only for the delimited records."); } ((DelimitedField)res).QuoteChar = x.QuoteChar; ((DelimitedField)res).QuoteMode = x.QuoteMode; ((DelimitedField)res).QuoteMultiline = x.QuoteMultiline; }); // FieldOrder Attributes.WorkWithFirst <FieldOrderAttribute>(fi, x => res.FieldOrder = x.Order); // FieldOptional res.IsOptional = fi.IsDefined(typeof(FieldOptionalAttribute), false); // FieldInNewLine res.InNewLine = fi.IsDefined(typeof(FieldInNewLineAttribute), false); // FieldArrayLength if (fi.FieldType.IsArray) { res.IsArray = true; res.ArrayType = fi.FieldType.GetElementType(); // MinValue indicates that there is no FieldArrayLength in the array res.ArrayMinLength = int.MinValue; res.ArrayMaxLength = int.MaxValue; Attributes.WorkWithFirst <FieldArrayLengthAttribute>(fi, (x) => { res.ArrayMinLength = x.mMinLength; res.ArrayMaxLength = x.mMaxLength; if (res.ArrayMaxLength < res.ArrayMinLength || res.ArrayMinLength < 0 || res.ArrayMaxLength <= 0) { throw new BadUsageException("The field: " + fi.Name + " has invalid length values in the [FieldArrayLength] attribute."); } }); } // NullFieldOnError res.NullFieldOnError = fi.IsDefined(typeof(FieldNullOnErrorAttribute), false); } if (fi.IsDefined(typeof(CompilerGeneratedAttribute), false)) { if (fi.Name.EndsWith("__BackingField") && fi.Name.StartsWith("<") && fi.Name.Contains(">")) { res.FieldFriendlyName = fi.Name.Substring(1, fi.Name.IndexOf(">") - 1); } } if (string.IsNullOrEmpty(res.FieldFriendlyName)) { res.FieldFriendlyName = res.FieldName; } return(res); }
/* * private static readonly char[] mWhitespaceChars = new[] { * '\t', '\n', '\v', '\f', '\r', ' ', '\x00a0', '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005', * '\u2006', '\u2007', '\u2008', * '\u2009', '\u200a', '\u200b', '\u3000', '\ufeff' */ #endregion #region " CreateField " /// <summary> /// Check the Attributes on the field and return a structure containing /// the settings for this file. /// </summary> /// <param name="fi">Information about this field</param> /// <param name="recordAttribute">Type of record we are reading</param> /// <returns>Null if not used</returns> public static FieldBase CreateField(FieldInfo fi, TypedRecordAttribute recordAttribute) { FieldBase res = null; MemberInfo mi = fi; var memberName = "The field: '" + fi.Name; Type fieldType = fi.FieldType; string fieldFriendlyName = AutoPropertyName(fi); if (string.IsNullOrEmpty(fieldFriendlyName) == false) { var prop = fi.DeclaringType.GetProperty(fieldFriendlyName); if (prop != null) { memberName = "The property: '" + prop.Name; mi = prop; } else { fieldFriendlyName = null; } } // If ignored, return null #pragma warning disable 612,618 // disable obsolete warning if (mi.IsDefined(typeof(FieldNotInFileAttribute), true) || mi.IsDefined(typeof(FieldIgnoredAttribute), true) || mi.IsDefined(typeof(FieldHiddenAttribute), true)) #pragma warning restore 612,618 { return(null); } var attributes = (FieldAttribute[])mi.GetCustomAttributes(typeof(FieldAttribute), true); // CHECK USAGE ERRORS !!! // Fixed length record and no attributes at all if (recordAttribute is FixedLengthRecordAttribute && attributes.Length == 0) { throw new BadUsageException(memberName + "' must be marked the FieldFixedLength attribute because the record class is marked with FixedLengthRecord."); } if (attributes.Length > 1) { throw new BadUsageException(memberName + "' has a FieldFixedLength and a FieldDelimiter attribute."); } if (recordAttribute is DelimitedRecordAttribute && mi.IsDefined(typeof(FieldAlignAttribute), false)) { throw new BadUsageException(memberName + "' can't be marked with FieldAlign attribute, it is only valid for fixed length records and are used only for write purpose."); } if (fieldType.IsArray == false && mi.IsDefined(typeof(FieldArrayLengthAttribute), false)) { throw new BadUsageException(memberName + "' can't be marked with FieldArrayLength attribute is only valid for array fields."); } // PROCESS IN NORMAL CONDITIONS if (attributes.Length > 0) { FieldAttribute fieldAttb = attributes[0]; if (fieldAttb is FieldFixedLengthAttribute) { // Fixed Field if (recordAttribute is DelimitedRecordAttribute) { throw new BadUsageException(memberName + "' can't be marked with FieldFixedLength attribute, it is only for the FixedLengthRecords not for delimited ones."); } var attbFixedLength = (FieldFixedLengthAttribute)fieldAttb; var attbAlign = Attributes.GetFirst <FieldAlignAttribute>(mi); res = new FixedLengthField(fi, attbFixedLength.Length, attbAlign); ((FixedLengthField)res).FixedMode = ((FixedLengthRecordAttribute)recordAttribute).FixedMode; } else if (fieldAttb is FieldDelimiterAttribute) { // Delimited Field if (recordAttribute is FixedLengthRecordAttribute) { throw new BadUsageException(memberName + "' can't be marked with FieldDelimiter attribute, it is only for DelimitedRecords not for fixed ones."); } res = new DelimitedField(fi, ((FieldDelimiterAttribute)fieldAttb).Delimiter); } else { throw new BadUsageException( "Custom field attributes are not currently supported. Unknown attribute: " + fieldAttb.GetType().Name + " on field: " + fi.Name); } } else // attributes.Length == 0 { var delimitedRecordAttribute = recordAttribute as DelimitedRecordAttribute; if (delimitedRecordAttribute != null) { res = new DelimitedField(fi, delimitedRecordAttribute.Separator); } } if (res != null) { // FieldDiscarded res.Discarded = mi.IsDefined(typeof(FieldValueDiscardedAttribute), false); // FieldTrim Attributes.WorkWithFirst <FieldTrimAttribute>(mi, (x) => { res.TrimMode = x.TrimMode; res.TrimChars = x.TrimChars; }); // FieldQuoted Attributes.WorkWithFirst <FieldQuotedAttribute>(mi, (x) => { if (res is FixedLengthField) { throw new BadUsageException( memberName + "' can't be marked with FieldQuoted attribute, it is only for the delimited records."); } ((DelimitedField)res).QuoteChar = x.QuoteChar; ((DelimitedField)res).QuoteMode = x.QuoteMode; ((DelimitedField)res).QuoteMultiline = x.QuoteMultiline; }); // FieldOrder Attributes.WorkWithFirst <FieldOrderAttribute>(mi, x => res.FieldOrder = x.Order); // FieldCaption Attributes.WorkWithFirst <FieldCaptionAttribute>(mi, x => res.FieldCaption = x.Caption); // FieldOptional res.IsOptional = mi.IsDefined(typeof(FieldOptionalAttribute), false); // FieldInNewLine res.InNewLine = mi.IsDefined(typeof(FieldInNewLineAttribute), false); // FieldValidatorAttributes - for use in custom validation of fields res.Validators = new List <Interfaces.IFieldValidate>((FieldValidateAttribute[])mi.GetCustomAttributes(typeof(FieldValidateAttribute), false)); // FieldArrayLength if (fieldType.IsArray) { res.IsArray = true; res.ArrayType = fieldType.GetElementType(); // MinValue indicates that there is no FieldArrayLength in the array res.ArrayMinLength = int.MinValue; res.ArrayMaxLength = int.MaxValue; Attributes.WorkWithFirst <FieldArrayLengthAttribute>(mi, (x) => { res.ArrayMinLength = x.MinLength; res.ArrayMaxLength = x.MaxLength; if (res.ArrayMaxLength < res.ArrayMinLength || res.ArrayMinLength < 0 || res.ArrayMaxLength <= 0) { throw new BadUsageException(memberName + " has invalid length values in the [FieldArrayLength] attribute."); } }); } } if (string.IsNullOrEmpty(res.FieldFriendlyName)) { res.FieldFriendlyName = res.FieldName; } return(res); }