Beispiel #1
0
        /// ///////////////////////////////////////////////////////////////////////
        /// ReadObject
        ///
        /// <summary>
        /// Creates an object of type T from the data in row and returns that object.
        ///
        /// </summary>
        /// <param name="row"></param>
        /// <param name="firstRow"></param>
        /// <returns></returns>
        public T ReadObject(List <DataRowItem> row, AggregatedException ae)
        {
            if (row.Count > m_IndexToInfo.Length)
            {
                // Too many fields
                throw new TooManyDataFieldsException(typeof(T).ToString(), row[0].LineNbr, m_fileName);
            }

            // -----

            T obj = new T();

            for (int i = 0; i < row.Count; i++)
            {
                TypeFieldInfo tfi = m_IndexToInfo[i];

                if (m_fileDescription.EnforceDLColumnAttribute &&
                    (!tfi._bHasColumnAttribute))
                {
                    // enforcing column attr, but this field/prop has no column attr.
                    // So there are too many fields in this record.
                    throw new TooManyNonDLColumnDataFieldsException(typeof(T).ToString(), row[i].LineNbr, m_fileName);
                }

                // -----

                if ((!m_fileDescription.FirstLineHasColumnNames) &&
                    (tfi._index == DLColumnAttribute._defaultFieldIndex))
                {
                    // First line in the file does not have field names, so we're
                    // depending on the FieldIndex of each field in the type
                    // to ensure each value is placed in the correct field.
                    // However, now hit a field where there is no FieldIndex.
                    throw new MissingFieldIndexException(typeof(T).ToString(), row[i].LineNbr, m_fileName);
                }

                // -----

                // value to put in the object
                string value = row[i].Value;

                if (value == null)
                {
                    if (!tfi._canBeNull)
                    {
                        ae.AddException(
                            new MissingRequiredFieldException(
                                typeof(T).ToString(),
                                tfi._name,
                                row[i].LineNbr,
                                m_fileName));
                    }
                }
                else
                {
                    try
                    {
                        Object objValue = null;

                        // Normally, either tfi.typeConverter is not null,
                        // or tfi.parseNumberMethod is not null.
                        //
                        if (tfi.typeConverter != null)
                        {
                            objValue = tfi.typeConverter.ConvertFromString(
                                null,
                                m_fileDescription.FileCultureInfo,
                                value);
                        }
                        else if (tfi.parseNumberMethod != null)
                        {
                            objValue =
                                tfi.parseNumberMethod.Invoke(
                                    tfi._fieldType,
                                    new Object[] {
                                value,
                                tfi._inputNumberStyle,
                                m_fileDescription.FileCultureInfo
                            });
                        }
                        else
                        {
                            // No TypeConverter and no Parse method available.
                            // Try direct approach.
                            objValue = value;
                        }

                        if (tfi._memberInfo is PropertyInfo)
                        {
                            ((PropertyInfo)tfi._memberInfo).SetValue(obj, objValue, null);
                        }
                        else
                        {
                            ((FieldInfo)tfi._memberInfo).SetValue(obj, objValue);
                        }
                    }
                    catch (Exception e)
                    {
                        if (e is TargetInvocationException)
                        {
                            e = e.InnerException;
                        }

                        if (e is FormatException)
                        {
                            e = new WrongDataFormatException(
                                typeof(T).ToString(),
                                tfi._name,
                                value,
                                row[i].LineNbr,
                                m_fileName,
                                e);
                        }

                        ae.AddException(e);
                    }
                }
            }

            // Visit any remaining fields in the type for which no value was given
            // in the data row, to see whether any of those was required.
            // If only looking at fields with DLColumn attribute, do ignore
            // fields that don't have that attribute.

            for (int i = row.Count; i < m_IndexToInfo.Length; i++)
            {
                TypeFieldInfo tfi = m_IndexToInfo[i];

                if (((!m_fileDescription.EnforceDLColumnAttribute) ||
                     tfi._bHasColumnAttribute) &&
                    (!tfi._canBeNull))
                {
                    ae.AddException(
                        new MissingRequiredFieldException(
                            typeof(T).ToString(),
                            tfi._name,
                            row[row.Count - 1].LineNbr,
                            m_fileName));
                }
            }

            return(obj);
        }
Beispiel #2
0
        /// ///////////////////////////////////////////////////////////////////////
        /// ReadData
        /// <summary>
        ///
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="fileName">
        /// Name of the file associated with the stream.
        /// null if there is no such file.
        /// Used solely when throwing an exception.
        /// </param>
        /// <param name="stream">
        /// All data is read from this stream.
        ///
        /// This is a StreamReader rather then a TextReader,
        /// because we need to be able to seek back to the start of the
        /// stream, and you can't do that with a TextReader (or s StringReader).
        /// </param>
        /// <param name="fileDescription"></param>
        /// <returns></returns>
        private IEnumerable <T> ReadData <T>(
            string fileName,
            StreamReader stream,
            DLFileDescription fileDescription) where T : new()
        {
            // The constructor for FieldMapper_Reading will throw an exception if there is something
            // wrong with type T. So invoke that constructor before you open the file, because if there
            // is an exception, the file will not be closed.
            FieldMapper_Reading <T> fm = new FieldMapper_Reading <T>(fileDescription, fileName, false);

            // -------
            // Each time the IEnumerable<T> that is returned from this method is
            // accessed in a foreach, ReadData is called again (not the original Read overload!)
            //
            // So, open the file here, or rewind the stream.

            bool readingFile = !string.IsNullOrEmpty(fileName);

            if (readingFile)
            {
                stream = new StreamReader(
                    fileName,
                    fileDescription.TextEncoding,
                    fileDescription.DetectEncodingFromByteOrderMarks);
            }
            else
            {
                // Rewind the stream

                if ((stream == null) || (!stream.BaseStream.CanSeek))
                {
                    throw new BadStreamException();
                }

                stream.BaseStream.Seek(0, SeekOrigin.Begin);
            }

            // ----------

            DLStream            cs  = new DLStream(stream, null, fileDescription.SeparatorChar);
            List <DataRowItem>  row = new List <DataRowItem>();
            AggregatedException ae  =
                new AggregatedException(typeof(T).ToString(), fileName, fileDescription.MaximumNbrExceptions);

            try
            {
                bool firstRow = true;
                while (cs.ReadRow(ref row))
                {
                    // Skip empty lines.
                    // Important. If there is a newline at the end of the last data line, the code
                    // thinks there is an empty line after that last data line.
                    if ((row.Count == 1) &&
                        ((row[0].Value == null) ||
                         (string.IsNullOrEmpty(row[0].Value.Trim()))))
                    {
                        continue;
                    }

                    if (firstRow && fileDescription.FirstLineHasColumnNames)
                    {
                        fm.ReadNames(row);
                    }
                    else
                    {
                        T obj = default(T);
                        try
                        {
                            obj = fm.ReadObject(row, ae);
                        }
                        catch (AggregatedException ae2)
                        {
                            // Seeing that the AggregatedException was thrown, maximum number of exceptions
                            // must have been reached, so rethrow.
                            // Catch here, so you don't add an AggregatedException to an AggregatedException
                            throw ae2;
                        }
                        catch (Exception e)
                        {
                            // Store the exception in the AggregatedException ae.
                            // That way, if a file has many errors leading to exceptions,
                            // you get them all in one go, packaged in a single aggregated exception.
                            ae.AddException(e);
                        }

                        yield return(obj);
                    }
                    firstRow = false;
                }
            }
            finally
            {
                if (readingFile)
                {
                    stream.Close();
                }

                // If any exceptions were raised while reading the data from the file,
                // they will have been stored in the AggregatedException ae.
                // In that case, time to throw ae.
                ae.ThrowIfExceptionsStored();
            }
        }