/// <summary> /// Confirm all fields are either ordered or unordered /// </summary> /// <param name="currentField">Newest field</param> /// <param name="resFields">Other fields we have found</param> private static void CheckForOrderProblems(FieldBase currentField, List <FieldBase> resFields) { if (currentField.FieldOrder.HasValue) { // If one field has order number set, all others must also have an order number var fieldWithoutOrder = resFields.Find(x => x.FieldOrder.HasValue == false); if (fieldWithoutOrder != null) { throw new BadUsageException(Messages.Errors.PartialFieldOrder .FieldName(fieldWithoutOrder.FieldInfo.Name) .Text); } // No other field should have the same order number var fieldWithSameOrder = resFields.Find(x => x != currentField && x.FieldOrder == currentField.FieldOrder); if (fieldWithSameOrder != null) { throw new BadUsageException(Messages.Errors.SameFieldOrder .FieldName1(currentField.FieldInfo.Name) .FieldName2(fieldWithSameOrder.FieldInfo.Name) .Text); } } else { // No other field should have order number set var fieldWithOrder = resFields.Find(x => x.FieldOrder.HasValue); if (fieldWithOrder != null) { var autoPropertyName = FieldBase.AutoPropertyName(currentField.FieldInfo); if (string.IsNullOrEmpty(autoPropertyName)) { throw new BadUsageException(Messages.Errors.PartialFieldOrder .FieldName(currentField.FieldInfo.Name) .Text); } else { throw new BadUsageException(Messages.Errors.PartialFieldOrderInAutoProperty .PropertyName(autoPropertyName) .Text); } } } }
/// <summary> /// Check that once one field is optional all following fields are optional /// <para/> /// Check that arrays in the middle of a record are of fixed length /// </summary> /// <param name="resFields">List of fields to extract</param> private static void CheckForOptionalAndArrayProblems(List <FieldBase> resFields) { for (int i = 0; i < resFields.Count; i++) { var currentField = resFields[i]; // Dont check the first field if (i < 1) { continue; } FieldBase prevField = resFields[i - 1]; prevField.NextIsOptional = currentField.IsOptional; // Check for optional problems. Previous is optional but current is not if (prevField.IsOptional && currentField.IsOptional == false && currentField.InNewLine == false) { throw new BadUsageException(Messages.Errors.ExpectingFieldOptional .FieldName(prevField.FieldInfo.Name) .Text); } // Check for an array array in the middle of a record that is not a fixed length if (prevField.IsArray) { if (prevField.ArrayMinLength == Int32.MinValue) { throw new BadUsageException(Messages.Errors.MissingFieldArrayLenghtInNotLastField .FieldName(prevField.FieldInfo.Name) .Text); } if (prevField.ArrayMinLength != prevField.ArrayMaxLength) { throw new BadUsageException(Messages.Errors.SameMinMaxLengthForArrayNotLastField .FieldName(prevField.FieldInfo.Name) .Text); } } } }
private void CreateAssingMethods() { if (mCreateHandler != null) { return; } DynamicMethod dm = new DynamicMethod("_CreateAndAssing_FH_RT_", MethodAttributes.Static | MethodAttributes.Public, CallingConventions.Standard, typeof(object), new Type[] { typeof(object[]) }, mRecordType, true); //dm.InitLocals = false; ILGenerator generator = dm.GetILGenerator(); generator.DeclareLocal(mRecordType); //generator.DeclareLocal(typeof(object)); generator.Emit(OpCodes.Newobj, mRecordConstructor); generator.Emit(OpCodes.Stloc_0); for (int i = 0; i < mFieldCount; i++) { FieldBase field = mFields[i]; generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldc_I4, i); generator.Emit(OpCodes.Ldelem_Ref); if (field.FieldType.IsValueType) { generator.Emit(OpCodes.Unbox_Any, field.FieldType); } else { generator.Emit(OpCodes.Castclass, field.FieldType); } generator.Emit(OpCodes.Stfld, field.mFieldInfo); //generator.EmitCall(); } // return the value generator.Emit(OpCodes.Ldloc_0); generator.Emit(OpCodes.Ret); mCreateHandler = (CreateAndAssignCallback)dm.CreateDelegate(typeof(CreateAndAssignCallback)); }
/// <summary> /// Confirm all fields are either ordered or unordered /// </summary> /// <param name="currentField">Newest field</param> /// <param name="resFields">Other fields we have found</param> private static void CheckForOrderProblems(FieldBase currentField, List <FieldBase> resFields) { if (currentField.FieldOrder.HasValue) { // If one field has order number set, all others must also have an order number var fieldWithoutOrder = resFields.Find(x => x.FieldOrder.HasValue == false); if (fieldWithoutOrder != null) { throw new BadUsageException($"The field: {fieldWithoutOrder.FieldInfo.Name} must be marked with FieldOrder because if you use this attribute in one field you must also use it on all of them."); } // No other field should have the same order number var fieldWithSameOrder = resFields.Find(x => x != currentField && x.FieldOrder == currentField.FieldOrder); if (fieldWithSameOrder != null) { throw new BadUsageException($"The field: {currentField.FieldInfo.Name} has the same FieldOrder as: {fieldWithSameOrder.FieldInfo.Name}. You must use different values"); } } else { // No other field should have order number set var fieldWithOrder = resFields.Find(x => x.FieldOrder.HasValue); if (fieldWithOrder != null) { var autoPropertyName = FieldBase.AutoPropertyName(currentField.FieldInfo); if (string.IsNullOrEmpty(autoPropertyName)) { throw new BadUsageException($"The field: {currentField.FieldInfo.Name} must be marked with FieldOrder because if you use this attribute in one field you must also use it on all of them."); } else { throw new BadUsageException( $"The auto property: {autoPropertyName} must be marked with FieldOrder because if you use this attribute in one field you must also use it on all of them."); } } } }
/// <summary> /// Check that once one field is optional all following fields are optional /// <para/> /// Check that arrays in the middle of a record are of fixed length /// </summary> /// <param name="resFields">List of fields to extract</param> private static void CheckForOptionalAndArrayProblems(List <FieldBase> resFields) { for (int i = 0; i < resFields.Count; i++) { var currentField = resFields[i]; // Dont check the first field if (i < 1) { continue; } FieldBase prevField = resFields[i - 1]; // Check for optional problems. Previous is optional but current is not if (prevField.IsOptional && currentField.IsOptional == false && currentField.InNewLine == false) { throw new BadUsageException($"The field: {prevField.FieldInfo.Name} must be marked as optional because the previous field is marked as optional. (Try adding [FieldOptional] to {prevField.FieldInfo.Name})"); } // Check for an array array in the middle of a record that is not a fixed length if (prevField.IsArray) { if (prevField.ArrayMinLength == int.MinValue) { throw new BadUsageException($"The field: {prevField.FieldInfo.Name} is of an array type and must contain a [FieldArrayLength] attribute because it is not the last field"); } if (prevField.ArrayMinLength != prevField.ArrayMaxLength) { throw new BadUsageException($"The array field: {prevField.FieldInfo.Name} must be of a fixed length because it is not the last field of the class, i.e. the min and max length of the [FieldArrayLength] attribute must be the same."); } } } }
/// <summary> /// Confirm all fields are either ordered or unordered /// </summary> /// <param name="currentField">Newest field</param> /// <param name="resFields">Other fields we have found</param> private static void CheckForOrderProblems(FieldBase currentField, List<FieldBase> resFields) { if (currentField.FieldOrder.HasValue) { var othersWithoutOrder = resFields.FindAll(x => x.FieldOrder.HasValue == false); if (othersWithoutOrder.Count > 0) { throw new BadUsageException(Messages.Errors.PartialFieldOrder .FieldName(othersWithoutOrder[0].FieldInfo.Name) .Text); } // Same Number var otherWithSameOrder = resFields.FindAll(x => x != currentField && x.FieldOrder == currentField.FieldOrder); if (otherWithSameOrder.Count > 0) { throw new BadUsageException(Messages.Errors.SameFieldOrder .FieldName1(currentField.FieldInfo.Name) .FieldName2(otherWithSameOrder[0].FieldInfo.Name) .Text); } } else { var othersWithOrder = resFields.FindAll(x => x.FieldOrder.HasValue).Count; if (othersWithOrder > 0) { throw new BadUsageException(Messages.Errors.PartialFieldOrder .FieldName(currentField.FieldInfo.Name) .Text); } } }
/// <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); }
public static FieldBase CreateField(FieldInfo fi, TypedRecordAttribute recordAttribute, bool someOptional) { // If ignored, return null if (fi.IsDefined(typeof(FieldIgnoredAttribute), true)) { return(null); } FieldBase res = null; FieldAttribute[] attributes; FieldAttribute fieldAttb; attributes = (FieldAttribute[])fi.GetCustomAttributes(typeof(FieldAttribute), true); // CHECK USAGE ERRORS !!! if (attributes.Length > 1) { throw new BadUsageException("The field: " + fi.Name + " has more than one FieldAttribute (left only one or none)"); } if (attributes.Length == 0 && recordAttribute is FixedLengthRecordAttribute) { throw new BadUsageException("The record class marked with the FixedLengthRecord attribute must include a FixedLength attribute in each field."); } if (recordAttribute is DelimitedRecordAttribute && fi.IsDefined(typeof(FieldAlignAttribute), true)) { throw new BadUsageException("The AlignAttribute is only valid for fixed length records and are used only for write purpouse."); } // PROCESS IN NORMAL CONDITIONS if (attributes.Length > 0) { fieldAttb = attributes[0]; if (fieldAttb is FieldFixedLengthAttribute) { if (recordAttribute is DelimitedRecordAttribute) { throw new BadUsageException("The FieldFixedLengthAttribute is only for the FixedLengthRecords not for the delimited ones."); } FieldFixedLengthAttribute attb = ((FieldFixedLengthAttribute)fieldAttb); FieldAlignAttribute[] alignAttbs = (FieldAlignAttribute[])fi.GetCustomAttributes(typeof(FieldAlignAttribute), true); FieldAlignAttribute align = null; if (alignAttbs.Length > 0) { align = alignAttbs[0]; } res = new FixedLengthField(fi, attb.Length, align); } else if (fieldAttb is FieldDelimiterAttribute) { if (recordAttribute is FixedLengthRecordAttribute) { throw new BadUsageException("The DelimitedAttribute is only for DelimitedRecords not for the fixed ones."); } res = new DelimitedField(fi, ((FieldDelimiterAttribute)fieldAttb).Separator); } else { throw new BadUsageException("Custom TypedRecords not currently supported."); } } else // attributes.Length == 0 { if (recordAttribute is DelimitedRecordAttribute) { res = new DelimitedField(fi, ((DelimitedRecordAttribute)recordAttribute).Separator); } } //----- TRIMMING if (res != null) { FieldTrimAttribute[] trim = (FieldTrimAttribute[])fi.GetCustomAttributes(typeof(FieldTrimAttribute), true); if (trim.Length > 0) { res.mTrimMode = trim[0].TrimMode; res.mTrimChars = trim[0].TrimChars; } FieldQuotedAttribute[] quotedAttributes = (FieldQuotedAttribute[])fi.GetCustomAttributes(typeof(FieldQuotedAttribute), true); if (quotedAttributes.Length > 0) { if (res is FixedLengthField) { throw new BadUsageException("The QuotedAttribute can't be used in FixedLength fields."); } ((DelimitedField)res).mQuoteChar = quotedAttributes[0].QuoteChar; ((DelimitedField)res).mQuoteMode = quotedAttributes[0].QuoteMode; ((DelimitedField)res).mQuoteMultiline = quotedAttributes[0].QuoteMultiline; } FieldOptionalAttribute[] optionalAttribs = (FieldOptionalAttribute[])fi.GetCustomAttributes(typeof(FieldOptionalAttribute), true); if (optionalAttribs.Length > 0) { res.mIsOptional = true; } else if (someOptional) { throw new BadUsageException("When you define a field as FieldOptional, the next fields must be marked with the same attribute. ( Try adding [FieldOptional] to " + res.mFieldInfo.Name + " )"); } res.mInNewLine = fi.IsDefined(typeof(FieldInNewLineAttribute), true); } return(res); }
/// <summary> /// Confirm all fields are either ordered or unordered /// </summary> /// <param name="currentField">Newest field</param> /// <param name="resFields">Other fields we have found</param> private static void CheckForOrderProblems(FieldBase currentField, List<FieldBase> resFields) { if (currentField.FieldOrder.HasValue) { // If one field has order number set, all others must also have an order number var fieldWithoutOrder = resFields.Find(x => x.FieldOrder.HasValue == false); if (fieldWithoutOrder != null) { throw new BadUsageException(Messages.Errors.PartialFieldOrder .FieldName(fieldWithoutOrder.FieldInfo.Name) .Text); } // No other field should have the same order number var fieldWithSameOrder = resFields.Find(x => x != currentField && x.FieldOrder == currentField.FieldOrder); if (fieldWithSameOrder != null) { throw new BadUsageException(Messages.Errors.SameFieldOrder .FieldName1(currentField.FieldInfo.Name) .FieldName2(fieldWithSameOrder.FieldInfo.Name) .Text); } } else { // No other field should have order number set var fieldWithOrder = resFields.Find(x => x.FieldOrder.HasValue); if (fieldWithOrder != null) { var autoPropertyName = FieldBase.AutoPropertyName(currentField.FieldInfo); if (string.IsNullOrEmpty(autoPropertyName)) throw new BadUsageException(Messages.Errors.PartialFieldOrder .FieldName(currentField.FieldInfo.Name) .Text); else throw new BadUsageException(Messages.Errors.PartialFieldOrderInAutoProperty .PropertyName(autoPropertyName) .Text); } } }
public static FieldBase CreateField(FieldInfo fi, TypedRecordAttribute recordAttribute) { // If ignored, return null if (fi.IsDefined(typeof(FieldIgnoredAttribute), true)) { return(null); } FieldBase res = null; FieldAttribute[] attributes; FieldAttribute fieldAttb; attributes = (FieldAttribute[])fi.GetCustomAttributes(typeof(FieldAttribute), true); // CHECK USAGE ERRORS !!! 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 purpouse."); } 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) { 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."); } FieldFixedLengthAttribute attb = ((FieldFixedLengthAttribute)fieldAttb); FieldAlignAttribute[] alignAttbs = (FieldAlignAttribute[])fi.GetCustomAttributes(typeof(FieldAlignAttribute), false); FieldAlignAttribute align = null; if (alignAttbs.Length > 0) { align = alignAttbs[0]; } res = new FixedLengthField(fi, attb.Length, align); ((FixedLengthField)res).mFixedMode = ((FixedLengthRecordAttribute)recordAttribute).mFixedMode; } 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).mSeparator); } else { throw new BadUsageException("Custom Record Types are not currently supported. And sure will never be :P (You must not be here)"); } } else // attributes.Length == 0 { if (recordAttribute is DelimitedRecordAttribute) { res = new DelimitedField(fi, ((DelimitedRecordAttribute)recordAttribute).Separator); } } if (res != null) { // Trim Related FieldTrimAttribute[] trim = (FieldTrimAttribute[])fi.GetCustomAttributes(typeof(FieldTrimAttribute), false); if (trim.Length > 0) { res.mTrimMode = trim[0].TrimMode; res.mTrimChars = trim[0].TrimChars; } // Quote Related FieldQuotedAttribute[] quotedAttributes = (FieldQuotedAttribute[])fi.GetCustomAttributes(typeof(FieldQuotedAttribute), false); if (quotedAttributes.Length > 0) { 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).mQuoteChar = quotedAttributes[0].QuoteChar; ((DelimitedField)res).mQuoteMode = quotedAttributes[0].QuoteMode; ((DelimitedField)res).mQuoteMultiline = quotedAttributes[0].QuoteMultiline; } // Optional Related FieldOptionalAttribute[] optionalAttribs = (FieldOptionalAttribute[])fi.GetCustomAttributes(typeof(FieldOptionalAttribute), false); if (optionalAttribs.Length > 0) { res.mIsOptional = true; } // NewLine Related res.mInNewLine = fi.IsDefined(typeof(FieldInNewLineAttribute), true); // Array Related if (fi.FieldType.IsArray) { res.mIsArray = true; res.mArrayType = fi.FieldType.GetElementType(); FieldArrayLengthAttribute[] arrayAttribs = (FieldArrayLengthAttribute[])fi.GetCustomAttributes(typeof(FieldArrayLengthAttribute), false); if (arrayAttribs.Length > 0) { res.mArrayMinLength = arrayAttribs[0].mMinLength; res.mArrayMaxLength = arrayAttribs[0].mMaxLength; if (res.mArrayMaxLength < res.mArrayMinLength || res.mArrayMinLength < 0 || res.mArrayMaxLength <= 0) { throw new BadUsageException("The field: " + fi.Name + " has invalid length values in the [FieldArrayLength] attribute."); } } else { // MinValue indicates that there is no FieldArrayLength in the array res.mArrayMinLength = int.MinValue; res.mArrayMaxLength = int.MaxValue; } } } return(res); }