/// <summary> /// Create a clone of the fixed length record ready to get updated by /// the base settings /// </summary> /// <returns>new fixed length field definition just like this one minus /// the base settings</returns> protected override FieldBase CreateClone() { var res = new FixedLengthField { Align = Align, FieldLength = FieldLength, FixedMode = FixedMode }; return(res); }
/// <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, ITypedRecordAttribute recordAttribute) { FieldBase res = null; MemberInfo mi = fi; var memberName = $"The field: '{ fi.Name}'"; var fieldType = fi.FieldType; var 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) { var fieldAttribute = attributes[0]; var fixedLengthAttribute = fieldAttribute as FieldFixedLengthAttribute; if (fixedLengthAttribute != null) { // 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 alignAttribute = mi.GetFirst <FieldAlignAttribute>(); res = new FixedLengthField(fi, fixedLengthAttribute.Length, alignAttribute); ((FixedLengthField)res).FixedMode = ((FixedLengthRecordAttribute)recordAttribute).FixedMode; } else if (fieldAttribute 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)fieldAttribute).Delimiter); } else { throw new BadUsageException( $"Custom field attributes are not currently supported. Unknown attribute: {fieldAttribute.GetType().Name} on field: { fi.Name}"); } } else // attributes.Length == 0 { var delimitedRecordAttribute = recordAttribute as DelimitedRecordAttribute; if (delimitedRecordAttribute != null) { res = new DelimitedField(fi, delimitedRecordAttribute.Delimiter); } } if (res != null) { // FieldDiscarded res.Discarded = mi.IsDefined(typeof(FieldValueDiscardedAttribute), false); // FieldTrim mi.WorkWithFirst <FieldTrimAttribute>((x) => { res.TrimMode = x.TrimMode; res.TrimChars = x.TrimChars; }); // FieldQuoted mi.WorkWithFirst <FieldQuotedAttribute>((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 mi.WorkWithFirst <FieldOrderAttribute>(x => res.FieldOrder = x.Order); // FieldCaption mi.WorkWithFirst <FieldCaptionAttribute>(x => res.FieldCaption = x.Caption); // FieldOptional res.IsOptional = mi.IsDefined(typeof(FieldOptionalAttribute), false); // FieldInNewLine res.InNewLine = mi.IsDefined(typeof(FieldInNewLineAttribute), false); // FieldNotEmpty res.IsNotEmpty = mi.IsDefined(typeof(FieldNotEmptyAttribute), 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; mi.WorkWithFirst <FieldArrayLengthAttribute>((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); }