/// <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);
        }
Exemple #2
0
        /*
         * 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);
        }