Beispiel #1
0
        /// <summary>
        /// Appends a single object to a StringBuilder in CSV format as a single line
        /// </summary>
        /// <param name="sb">The stringbuilder to append data</param>
        /// <param name="obj">The single object to append in CSV-line format</param>
        /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
        /// <typeparam name="T">The 1st type parameter.</typeparam>
        public static void AppendAsCSV <T>(this StringBuilder sb, T obj, CSVSettings settings = null) where T : class, new()
        {
            // Skip any null objects
            if (obj == null)
            {
                return;
            }

            // Use CSV as default.
            if (settings == null)
            {
                settings = CSVSettings.CSV;
            }

            // Retrieve reflection information
            var type   = typeof(T);
            var filist = type.GetFields();
            var pilist = type.GetProperties();

            // Retrieve all the fields and properties
            List <object> values = new List <object>();

            foreach (var fi in filist)
            {
                values.Add(fi.GetValue(obj));
            }
            foreach (var pi in pilist)
            {
                values.Add(pi.GetValue(obj, null));
            }

            // Output one line of CSV
            AppendCSVRow(sb, values, settings);
        }
Beispiel #2
0
        /// <summary>
        /// Add a CSV Header line to a StringBuilder
        /// </summary>
        /// <param name="sb">The stringbuilder to append data</param>
        /// <param name="type">The type of data to emit a header</param>
        /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
        public static void AppendCSVHeader(this StringBuilder sb, Type type, CSVSettings settings = null)
        {
            // Use CSV as default.
            if (settings == null)
            {
                settings = CSVSettings.CSV;
            }

            // Retrieve reflection information
            var filist = type.GetFields();
            var pilist = type.GetProperties();

            // Gather information about headers
            var headers = new List <object>();

            foreach (var fi in filist)
            {
                headers.Add(fi.Name);
            }
            foreach (var pi in pilist)
            {
                headers.Add(pi.Name);
            }
            AppendCSVRow(sb, headers, settings);
        }
Beispiel #3
0
        /// <summary>
        /// Serialize an array of objects to CSV format
        /// </summary>
        /// <typeparam name="T">The type of objects to serialize from this CSV</typeparam>
        /// <param name="list">The array of objects to serialize</param>
        /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
        /// <returns>The completed CSV string representing one line per element in list</returns>
        public static string Serialize <T>(IEnumerable <T> list, CSVSettings settings = null) where T : class, new()
        {
            // Use CSV as default.
            if (settings == null)
            {
                settings = CSVSettings.CSV;
            }

            // Okay, let's begin
            StringBuilder sb = new StringBuilder();

            // Did the caller want the header row?
            if (settings.HeaderRowIncluded)
            {
                sb.AppendCSVHeader(typeof(T), settings);
                sb.Append(settings.LineSeparator);
            }

            // Let's go through the array of objects
            // Iterate through all the objects
            var values = new List <object>();

            foreach (T obj in list)
            {
                sb.AppendAsCSV <T>(obj, settings);
                sb.Append(settings.LineSeparator);
            }

            // Here's your data serialized in CSV format
            return(sb.ToString());
        }
Beispiel #4
0
        /// <summary>
        /// Serialize a sequence of objects into a CSV string
        /// </summary>
        /// <returns>A single line of CSV encoded data containing these values</returns>
        /// <param name="row">A list or array of objects to serialize</param>
        /// <param name="settings">The field delimiter character (Default: comma)</param>
        public static string ToCSVString(this IEnumerable <object> row, CSVSettings settings = null)
        {
            StringBuilder sb = new StringBuilder();

            AppendCSVRow(sb, row, settings);
            return(sb.ToString());
        }
Beispiel #5
0
        /// <summary>
        /// Parse a single row of data from a CSV line into an array of objects, while permitting embedded newlines
        /// </summary>
        /// <param name="inStream">The stream to read</param>
        /// <param name="settings">The CSV settings to use for this parsing operation (Default: CSV)</param>
        /// <returns>An array containing all fields in the next row of data, or null if it could not be parsed.</returns>
        public static string[] ParseMultiLine(StreamReader inStream, CSVSettings settings = null)
        {
            StringBuilder sb = new StringBuilder();

            string[] array = null;
            while (!inStream.EndOfStream)
            {
                // Read in a line
                sb.Append(inStream.ReadLine());

                // Does it parse?
                string s = sb.ToString();
                if (TryParseLine(s, out array, settings))
                {
                    return(array);
                }

                // We didn't succeed on the first try - our text must have an embedded newline in it.
                // Let's assume that we were in the middle of parsing a field when we encountered a newline,
                // and continue parsing.
                sb.Append(settings.LineSeparator);
            }

            // Fails to parse - return the best array we were able to get
            return(array);
        }
Beispiel #6
0
 /// <summary>
 /// Serialize an array of objects to CSV format
 /// </summary>
 /// <typeparam name="T">The type of objects to serialize from this CSV</typeparam>
 /// <param name="list">The array of objects to serialize</param>
 /// <param name="stream">The stream to which we will send this CSV text</param>
 /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
 /// <returns>The completed CSV string representing one line per element in list</returns>
 public static Task SerializeAsync <T>(IEnumerable <T> list, Stream stream, CSVSettings settings = null) where T : class, new()
 {
     using (var cw = new CSVWriter(stream, settings))
     {
         return(cw.SerializeAsync(list));
     }
 }
Beispiel #7
0
 /// <summary>
 /// Read in a single CSV file as an array of objects
 /// </summary>
 /// <typeparam name="T">The type of objects to deserialize from this CSV.</typeparam>
 /// <param name="stream">The stream to read.</param>
 /// <param name="settings">The CSV settings to use when loading this array (Default: CSV)</param>
 /// <returns>An array of objects that were retrieved from the CSV file.</returns>
 public static List <T> LoadArray <T>(StreamReader stream, CSVSettings settings) where T : class, new()
 {
     using (CSVReader cr = new CSVReader(stream, settings))
     {
         return(cr.Deserialize <T>());
     }
 }
 /// <summary>
 /// Write a data table to disk at the designated file name in CSV format
 /// </summary>
 /// <param name="dt"></param>
 /// <param name="filename"></param>
 /// <param name="settings">The CSV settings to use when exporting this DataTable (Default: CSV)</param>
 public static void WriteToFile(this DataTable dt, string filename, CSVSettings settings = null)
 {
     using (StreamWriter sw = new StreamWriter(filename))
     {
         WriteToStream(dt, sw, settings);
     }
 }
 /// <summary>
 /// Write the data table to a stream in CSV format
 /// </summary>
 /// <param name="dt">The data table to write</param>
 /// <param name="sw">The stream where the CSV text will be written</param>
 /// <param name="settings">The CSV settings to use when exporting this DataTable (Default: CSV)</param>
 public static void WriteToStream(this DataTable dt, StreamWriter sw, CSVSettings settings = null)
 {
     using (CSVWriter cw = new CSVWriter(sw, settings))
     {
         cw.Write(dt);
     }
 }
 /// <summary>
 /// Read in a single CSV file into a datatable in memory
 /// </summary>
 /// <param name="stream">The stream source from which to load the datatable.</param>
 /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
 /// <returns>An data table of strings that were retrieved from the CSV file.</returns>
 public static DataTable FromStream(StreamReader stream, CSVSettings settings = null)
 {
     using (CSVReader cr = new CSVReader(stream, settings))
     {
         return(cr.ReadAsDataTable());
     }
 }
Beispiel #11
0
        /// <summary>
        /// Constructs a serialization helper object separate from I/O
        /// </summary>
        /// <param name="settings"></param>
        /// <param name="riskyChars"></param>
        /// <param name="forceQualifierTypes"></param>
        public SerializationHelper(CSVSettings settings, char[] riskyChars, Dictionary <Type, int> forceQualifierTypes)
        {
            _settings = settings;
            if (_settings == null)
            {
                _settings = CSVSettings.CSV;
            }

            // Extract properties and fields that are not excluded
            var excluded = new ExcludedColumnHelper(_settings);
            var props    = new List <PropertyInfo>();

            foreach (var prop in typeof(T).GetProperties())
            {
                if (!excluded.IsExcluded(prop.Name))
                {
                    props.Add(prop);
                }
            }

            var fields = new List <FieldInfo>();

            foreach (var field in typeof(T).GetFields())
            {
                if (!excluded.IsExcluded(field.Name))
                {
                    fields.Add(field);
                }
            }

            _properties          = props.ToArray();
            _fields              = fields.ToArray();
            _riskyChars          = riskyChars;
            _forceQualifierTypes = forceQualifierTypes;
        }
Beispiel #12
0
        public static void AppendCSVHeader <T>(this StringBuilder sb, CSVSettings settings = null) where T : class, new()
#endif
        {
            var header = Serialize(new T[] { }, settings);

            sb.Append(header);
        }
Beispiel #13
0
 /// <summary>
 /// Serialize an array of objects to CSV format
 /// </summary>
 /// <typeparam name="T">The type of objects to serialize from this CSV</typeparam>
 /// <param name="list">The array of objects to serialize</param>
 /// <param name="stream">The stream to which we will send this CSV text</param>
 /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
 /// <returns>The completed CSV string representing one line per element in list</returns>
 public static void Serialize <T>(IEnumerable <T> list, Stream stream, CSVSettings settings = null) where T : class, new()
 {
     using (var cw = new CSVWriter(stream, settings))
     {
         cw.Serialize(list);
     }
 }
Beispiel #14
0
        /// <summary>
        /// Construct a new CSV reader off a streamed source
        /// </summary>
        /// <param name="source">The stream source. Note that when disposed, the CSV Reader will dispose the stream reader.</param>
        /// <param name="settings">The CSV settings to use for this reader (Default: CSV)</param>
        public CSVReader(Stream source, CSVSettings settings = null)
        {
            _settings = settings;
            if (_settings == null)
            {
                _settings = CSVSettings.CSV;
            }
            _stream = new StreamReader(source, _settings.Encoding);

            // Do we need to parse headers?
            if (_settings.HeaderRowIncluded)
            {
                var line = _stream.ReadLine();
                if (_settings.AllowSepLine)
                {
                    var newDelimiter = CSV.ParseSepLine(line);
                    if (newDelimiter != null)
                    {
                        // We don't want to change the original settings, since they may be a singleton
                        _settings = _settings.CloneWithNewDelimiter(newDelimiter.Value);
                        line      = _stream.ReadLine();
                    }
                }

                Headers = CSV.ParseLine(line, _settings);
            }
            else
            {
                Headers = _settings.AssumedHeaders;
            }
        }
 /// <summary>
 /// Read in a single CSV file into a datatable in memory
 /// </summary>
 /// <param name="filename"></param>
 /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
 /// <returns>An data table of strings that were retrieved from the CSV file.</returns>
 public static DataTable FromFile(string filename, CSVSettings settings = null)
 {
     using (var sr = new StreamReader(filename))
     {
         return(FromStream(sr, settings));
     }
 }
Beispiel #16
0
        /// <summary>
        /// Deserialize a single row using precomputed converters
        /// </summary>
        /// <param name="line"></param>
        /// <param name="row_num"></param>
        /// <param name="settings"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public T Deserialize(string[] line, int row_num, CSVSettings settings)
        {
            // If this line is completely empty, do our settings permit us to ignore the empty line?
            if (line.Length == 0 || (line.Length == 1 && line[0] == string.Empty) && settings.IgnoreEmptyLineForDeserialization)
            {
                return(null);
            }

            // Does this line match the length of the first line?  Does the caller want us to complain?
            if (line.Length != _numColumns && !settings.IgnoreHeaderErrors)
            {
                throw new Exception($"Line #{row_num} contains {line.Length} columns; expected {_numColumns}");
            }

            // Construct a new object and execute each column on it
            var obj = new T();

            for (var i = 0; i < Math.Min(line.Length, _numColumns); i++)
            {
                if (_converters[i] == null)
                {
                    continue;
                }

                // Attempt to convert this to the specified type
                object value = null;
                if (settings.AllowNull && (line[i] == null || line[i] == settings.NullToken))
                {
                    value = null;
                }
                else if (_converters[i].IsValid(line[i]))
                {
                    value = _converters[i].ConvertFromString(line[i]);
                }
                else if (!settings.IgnoreHeaderErrors)
                {
                    throw new Exception(
                              $"The value '{line[i]}' cannot be converted to the type {_columnTypes[i]}.");
                }

                // Can we set this value to the object as a property?
                if (_properties[i] != null)
                {
                    _properties[i].SetValue(obj, value, null);
                }
                else if (_fields[i] != null)
                {
                    _fields[i].SetValue(obj, value);
                }
                else if (_methods[i] != null)
                {
                    _methods[i].Invoke(obj, new object[] { value });
                }
            }

            return(obj);
        }
 /// <summary>
 /// Construct a new CSV writer to produce output on the enclosed StreamWriter
 /// </summary>
 /// <param name="dest">The stream where this CSV will be outputted</param>
 /// <param name="settings">The CSV settings to use when writing to the stream (Default: CSV)</param>
 public CSVWriter(StreamWriter dest, CSVSettings settings = null)
 {
     _outstream = dest;
     _settings  = settings;
     if (_settings == null)
     {
         _settings = CSVSettings.CSV;
     }
 }
Beispiel #18
0
        /// <summary>
        /// Convenience function to read from a file on disk
        /// </summary>
        /// <param name="filename">The file to read</param>
        /// <param name="settings">The CSV settings to use for this reader (Default: CSV)</param>
        /// <param name="encoding">The string encoding to use for the reader (Default: UTF8)</param>
        /// <returns></returns>
        public static CSVReader FromFile(string filename, CSVSettings settings = null, Encoding encoding = null)
        {
            if (encoding == null)
            {
                encoding = Encoding.UTF8;
            }
            var sr = new StreamReader(filename, encoding);

            return(new CSVReader(sr, settings));
        }
Beispiel #19
0
 /// <summary>
 /// Construct a new CSV writer to produce output on the enclosed stream
 /// </summary>
 /// <param name="dest">The stream where this CSV will be outputted</param>
 /// <param name="settings">The CSV settings to use when writing to the stream (Default: CSV)</param>
 public CSVWriter(Stream dest, CSVSettings settings = null)
 {
     _settings = settings;
     if (_settings == null)
     {
         _settings = CSVSettings.CSV;
     }
     _writer              = new StreamWriter(dest, _settings.Encoding);
     _riskyChars          = _settings.GetRiskyChars();
     _forceQualifierTypes = _settings.GetForceQualifierTypes();
 }
Beispiel #20
0
 /// <summary>
 /// Deserialize a CSV string into a list of typed objects
 /// </summary>
 /// <typeparam name="T">The type of objects to deserialize</typeparam>
 /// <param name="settings">The CSV settings to use when parsing the source (Default: CSV)</param>
 /// <param name="source">The source CSV to deserialize</param>
 /// <returns></returns>
 public static List <T> Deserialize <T>(string source, CSVSettings settings = null) where T : class, new()
 {
     byte[] byteArray = Encoding.UTF8.GetBytes(source);
     using (var stream = new MemoryStream(byteArray))
     {
         using (CSVReader cr = new CSVReader(new StreamReader(stream), settings))
         {
             return(cr.Deserialize <T>());
         }
     }
 }
Beispiel #21
0
        /// <summary>
        /// Convenience function to read from a string
        /// </summary>
        /// <param name="source">The string to read</param>
        /// <param name="settings">The CSV settings to use for this reader (Default: CSV)</param>
        /// <returns></returns>
        public static CSVReader FromString(string source, CSVSettings settings = null)
        {
            if (settings == null)
            {
                settings = CSVSettings.CSV;
            }
            var byteArray = settings.Encoding.GetBytes(source);
            var stream    = new MemoryStream(byteArray);

            return(new CSVReader(stream, settings));
        }
Beispiel #22
0
 /// <summary>
 /// Construct a new CSV writer to produce output on the enclosed StreamWriter
 /// </summary>
 /// <param name="dest">The stream where this CSV will be outputted</param>
 /// <param name="settings">The CSV settings to use when writing to the stream (Default: CSV)</param>
 public CSVWriter(StreamWriter dest, CSVSettings settings = null)
 {
     _writer   = dest;
     _settings = settings;
     if (_settings == null)
     {
         _settings = CSVSettings.CSV;
     }
     _riskyChars          = _settings.GetRiskyChars();
     _forceQualifierTypes = _settings.GetForceQualifierTypes();
 }
 /// <summary>
 /// Convert a CSV file (in string form) into a data table
 /// </summary>
 /// <param name="source"></param>
 /// <param name="settings">The CSV settings to use when exporting this array (Default: CSV)</param>
 /// <returns></returns>
 public static DataTable FromString(string source, CSVSettings settings = null)
 {
     byte[] byteArray = Encoding.UTF8.GetBytes(source);
     using (MemoryStream stream = new MemoryStream(byteArray))
     {
         using (CSVReader cr = new CSVReader(new StreamReader(stream), settings))
         {
             return(cr.ReadAsDataTable());
         }
     }
 }
Beispiel #24
0
        public static string ToCSVString(this IEnumerable <object> row, CSVSettings settings = null)
#endif
        {
            if (settings == null)
            {
                settings = CSVSettings.CSV;
            }
            var riskyChars          = settings.GetRiskyChars();
            var forceQualifierTypes = settings.GetForceQualifierTypes();

            return(ItemsToCsv(row, settings, riskyChars, forceQualifierTypes));
        }
Beispiel #25
0
        /// <summary>
        /// Try to parse a line of CSV data.  Can only return false if an unterminated text qualifier is encountered.
        ///
        /// This function cannot recognize 'sep=' lines because it does not know whether it is parsing the first line
        /// in the overall CSV stream.
        /// </summary>
        /// <returns>False if there was an unterminated text qualifier in the <paramref name="line"/></returns>
        /// <param name="line">The line of text to parse</param>
        /// <param name="settings">The CSV settings to use for this parsing operation (Default: CSV)</param>
        /// <param name="row">The array of fields found in the line</param>
        public static bool TryParseLine(string line, out string[] row, CSVSettings settings = null)
        {
            row = null;
            var machine = new CSVStateMachine(settings);

            while (machine.State == CSVState.CanKeepGoing)
            {
                row  = machine.ParseChunk(line, true);
                line = string.Empty;
            }
            return(machine.State == CSVState.Done);
        }
Beispiel #26
0
        /// <summary>
        /// Convert a CSV file (in string form) into a list of string arrays
        /// </summary>
        /// <param name="source_string"></param>
        /// <param name="settings">The CSV settings to use when loading this array (Default: CSV)</param>
        /// <returns></returns>
        public static List <string[]> LoadString(string source_string, CSVSettings settings = null)
        {
            byte[]       byteArray = Encoding.UTF8.GetBytes(source_string);
            MemoryStream stream    = new MemoryStream(byteArray);
            var          results   = new List <string[]>();

            using (CSVReader cr = new CSVReader(new StreamReader(stream))) {
                foreach (var line in cr)
                {
                    results.Add(line);
                }
            }
            return(results);
        }
Beispiel #27
0
        /// <summary>
        /// Add a single token to the list
        /// </summary>
        /// <param name="list">List.</param>
        /// <param name="work">Work.</param>
        /// <param name="settings">Settings.</param>
        private static void AddToken(List <string> list, StringBuilder work, CSVSettings settings)
        {
            var s = work.ToString();

            if (settings.AllowNull && String.Equals(s, settings.NullToken, StringComparison.Ordinal))
            {
                list.Add(null);
            }
            else
            {
                list.Add(s);
            }
            work.Length = 0;
        }
Beispiel #28
0
        /// <summary>
        /// Constructs a new state machine to begin processing CSV text
        /// </summary>
        public CSVStateMachine(CSVSettings settings)
        {
            _line     = "";
            _list     = new List <string>();
            _work     = new StringBuilder();
            _settings = settings ?? CSVSettings.CSV;
            _position = -1;

            // The presence of a "sep=" line may affect these values
            _delimiter    = _settings.FieldDelimiter;
            _allowSepLine = _settings.AllowSepLine;

            // We are ready for work
            State = CSVState.CanKeepGoing;
        }
Beispiel #29
0
        public static void AppendCSVLine <T>(this StringBuilder sb, T obj, CSVSettings settings = null) where T : class, new()
#endif
        {
            if (settings == null)
            {
                settings = CSVSettings.CSV;
            }

            // Duplicate settings, but flag ourselves to ignore the header
            settings = settings.CloneWithNewDelimiter(settings.FieldDelimiter);
            settings.HeaderRowIncluded = false;
            var line = Serialize(new T[] { obj }, settings);

            sb.Append(line);
        }
 /// <summary>
 /// Write a DataTable to a string in CSV format
 /// </summary>
 /// <param name="dt">The datatable to write</param>
 /// <param name="settings">The CSV settings to use when exporting this DataTable (Default: CSV)</param>
 /// <returns>The CSV string representing the object array.</returns>
 public static string WriteToString(this DataTable dt, CSVSettings settings = null)
 {
     using (var ms = new MemoryStream())
     {
         var sw = new StreamWriter(ms);
         var cw = new CSVWriter(sw, settings);
         cw.Write(dt);
         sw.Flush();
         ms.Position = 0;
         using (var sr = new StreamReader(ms))
         {
             return(sr.ReadToEnd());
         }
     }
 }