Ejemplo n.º 1
0
        /// <summary>Initializes a new instance of the <see cref="CsvWriter" /> class.</summary>
        /// <param name="properties">Extended properties.</param>
        /// <param name="layout">The table layout.</param>
        /// <param name="stream">The stream.</param>
        /// <param name="closeBaseStream">if set to <c>true</c> [close base stream on close].</param>
        public CsvWriter(RowLayout layout, Stream stream, CsvProperties properties = default, bool closeBaseStream = false)
        {
            BaseStream      = stream ?? throw new ArgumentNullException(nameof(stream));
            Layout          = layout ?? throw new ArgumentNullException(nameof(layout));
            Properties      = properties.Valid ? properties : CsvProperties.Default;
            CloseBaseStream = closeBaseStream;
            writer          = new DataWriter(stream, Properties.Encoding, Properties.NewLineMode);
            if (Properties.NoHeader)
            {
                return;
            }

            // write header
            for (var i = 0; i < Layout.FieldCount; i++)
            {
                if (i > 0)
                {
                    writer.Write(Properties.Separator);
                }

                if (Properties.StringMarker.HasValue)
                {
                    writer.Write(Properties.StringMarker.Value);
                }

                writer.Write(Layout[i].NameAtDatabase);
                if (Properties.StringMarker.HasValue)
                {
                    writer.Write(Properties.StringMarker.Value);
                }
            }

            writer.WriteLine();
            writer.Flush();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Reads a whole list from the specified csv file.
        /// </summary>
        /// <param name="properties">Properties of the csv file.</param>
        /// <param name="fileName">File name of the csv file.</param>
        /// <returns>Returns a new <see cref="List{TStruct}"/>.</returns>
        /// <typeparam name="TStruct">Structure type.</typeparam>
        public static IList <TStruct> ReadList <TStruct>(CsvProperties properties, string fileName)
            where TStruct : struct
        {
            var layout = RowLayout.CreateTyped(typeof(TStruct));

            using var reader = new CsvReader(layout, fileName, properties);
            return(reader.ReadList <TStruct>());
        }
Ejemplo n.º 3
0
        /// <summary>Reads a whole list from the specified csv stream.</summary>
        /// <param name="properties">Properties of the csv file.</param>
        /// <param name="stream">The stream.</param>
        /// <returns>Returns a new <see cref="List{TStruct}" />.</returns>
        /// <typeparam name="TStruct">Structure type.</typeparam>
        public static List <TStruct> ReadList <TStruct>(CsvProperties properties, Stream stream)
            where TStruct : struct
        {
            var layout = RowLayout.CreateTyped(typeof(TStruct));

            using (var reader = new CsvReader(layout, stream, properties))
            {
                return(reader.ReadList <TStruct>());
            }
        }
Ejemplo n.º 4
0
        /// <summary>Creates a new csv file with the specified name and writes the whole table.</summary>
        /// <param name="table">Table to write to the csv file.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="properties">Properties of the csv file.</param>
        public static void WriteTable(ITable table, Stream stream, CsvProperties properties = default)
        {
            if (table == null)
            {
                throw new ArgumentNullException(nameof(table));
            }

            var writer = new CsvWriter(table.Layout, stream, properties);

            try
            {
                writer.Write(table);
            }
            finally
            {
                writer.Close();
            }
        }
Ejemplo n.º 5
0
        /// <summary>Parses a single row of data from the specified string.</summary>
        /// <param name="properties">The csv properties.</param>
        /// <param name="layout">The row layout.</param>
        /// <param name="data">The buffer to parse.</param>
        /// <returns>Returns a new <see cref="Row" /> instance.</returns>
        public static Row ParseRow(CsvProperties properties, RowLayout layout, string data)
        {
            try
            {
                var fieldCount       = layout.FieldCount;
                var fieldNumber      = 0;
                var ident            = new Queue <char>();
                var identInARowCount = 0;
                var currentValue     = new List <char>();
                var i      = -1;
                var values = new object[fieldCount];
                while (fieldNumber < fieldCount)
                {
                    ++i;
                    if ((i == data.Length) && (fieldNumber == (fieldCount - 1)))
                    {
                        break;
                    }

                    if (i >= data.Length)
                    {
                        throw new InvalidDataException("Unexpected end of input!");
                    }

                    if (properties.Separator == data[i])
                    {
                        if (ident.Count == 0)
                        {
                            identInARowCount = 0;
                            if (properties.StringMarker.HasValue)
                            {
                                values[fieldNumber] = layout.ParseValue(fieldNumber, new string(currentValue.ToArray()).Unescape(),
                                                                        properties.StringMarker.Value.ToString(), properties.Format);
                            }
                            else
                            {
                                values[fieldNumber] = layout.ParseValue(fieldNumber, new string(currentValue.ToArray()).Unescape(), string.Empty,
                                                                        properties.Format);
                            }

                            fieldNumber++;
                            currentValue.Clear();
                            continue;
                        }
                    }

                    if (properties.StringMarker == data[i])
                    {
                        identInARowCount++;
                        if ((ident.Count > 0) && (ident.Peek() == data[i]))
                        {
                            ident.Dequeue();
                            if (identInARowCount > 1)
                            {
                                // escaped char
                                currentValue.Add(data[i]);
                            }
                        }
                        else
                        {
                            ident.Enqueue(data[i]);
                        }
                    }
                    else
                    {
                        identInARowCount = 0;
                        currentValue.Add(data[i]);
                    }
                }

                if (ident.Count > 0)
                {
                    throw new InvalidDataException("Invalid ident/escaping!");
                }

                if (properties.StringMarker.HasValue)
                {
                    values[fieldNumber] = layout.ParseValue(fieldNumber, new string(currentValue.ToArray()).Unescape(),
                                                            properties.StringMarker.Value.ToString(), properties.Format);
                }
                else
                {
                    values[fieldNumber] = layout.ParseValue(fieldNumber, new string(currentValue.ToArray()).Unescape(), string.Empty, properties.Format);
                }

                fieldNumber++;
                if (i < data.Length)
                {
                    if (properties.Separator == data[i])
                    {
                        i++;
                    }

                    if (i < data.Length)
                    {
                        throw new InvalidDataException("Additional data at end of line!");
                    }
                }

                return(new Row(layout, values, false));
            }
            catch (EndOfStreamException)
            {
                if (data.Length > 0)
                {
                    throw;
                }

                return(null);
            }
            catch (Exception ex)
            {
                throw new InvalidDataException("Error while reading row data!", ex);
            }
        }
Ejemplo n.º 6
0
        /// <summary>Initializes a new instance of the <see cref="CsvReader" /> class.</summary>
        /// <param name="properties">Properties to apply to the reader.</param>
        /// <param name="layout">Layout to use when reading the csv data.</param>
        /// <param name="stream">Stream to read data from.</param>
        /// <param name="closeBaseStream">if set to <c>true</c> [close base stream on close].</param>
        public CsvReader(RowLayout layout, Stream stream, CsvProperties properties = default, bool closeBaseStream = false)
        {
            Layout          = layout;
            BaseStream      = stream ?? throw new ArgumentNullException(nameof(stream));
            Properties      = properties.Valid ? properties : CsvProperties.Default;
            CloseBaseStream = closeBaseStream;
            reader          = new DataReader(stream, Properties.Encoding, Properties.NewLineMode);
            if (!Properties.NoHeader)
            {
                var header = reader.ReadLine();
                currentRowNumber++;
                var fields = header.Split(Properties.Separator);
                if (!Properties.AllowFieldMatching)
                {
                    if (fields.Length != Layout.FieldCount)
                    {
                        if ((fields.Length - 1) != Layout.FieldCount)
                        {
                            throw new InvalidDataException($"Invalid header fieldcount (expected '{Layout.FieldCount}' got '{fields.Length}')!");
                        }
                    }
                }
                else
                {
                    if (fields.Length != Layout.FieldCount)
                    {
                        fieldNumberMatching = new int[Layout.FieldCount];
                    }
                }

                var count = Math.Min(Layout.FieldCount, fields.Length);
                for (var i = 0; i < count; i++)
                {
                    var fieldName  = fields[i].UnboxText(false);
                    var fieldIndex = Layout.GetFieldIndex(fieldName, false);
                    if (fieldIndex < 0)
                    {
                        throw new InvalidDataException(
                                  $"Error loading CSV Header! Got field name '{fieldName}' instead of '{Layout[i].Name}' at type '{Layout.Name}'");
                    }

                    if (!Properties.AllowFieldMatching)
                    {
                        if (fieldIndex != i)
                        {
                            throw new InvalidDataException($"Fieldposition of Field '{fieldName}' does not match!");
                        }

                        if (!string.Equals(Layout[fieldIndex].Name, fieldName))
                        {
                            throw new InvalidDataException(
                                      $"Invalid header value at field number '{i}' name '{fieldName}' expected '{Layout[fieldIndex].Name}'!");
                        }
                    }
                    else
                    {
                        if ((fieldNumberMatching == null) && (fieldIndex != i))
                        {
                            fieldNumberMatching = new int[Layout.FieldCount];
                        }
                    }
                }

                if (fieldNumberMatching != null)
                {
                    var i = 0;
                    for (; i < count; i++)
                    {
                        var fieldName = fields[i].UnboxText(false);
                        fieldNumberMatching[i] = Layout.GetFieldIndex(fieldName, false);
                    }

                    for (; i < Layout.FieldCount; i++)
                    {
                        fieldNumberMatching[i] = -1;
                    }
                }
            }
        }
Ejemplo n.º 7
0
 /// <summary>Initializes a new instance of the <see cref="CsvReader" /> class.</summary>
 /// <param name="properties">Properties to apply to the reader.</param>
 /// <param name="layout">Layout to use when reading from the csv file.</param>
 /// <param name="fileName">Filename to write to.</param>
 public CsvReader(RowLayout layout, string fileName, CsvProperties properties = default)
     : this(layout, File.OpenRead(fileName), properties, true)
 {
 }
Ejemplo n.º 8
0
 /// <summary>Initializes a new instance of the <see cref="CsvWriter" /> class.</summary>
 /// <param name="layout">The table layout.</param>
 /// <param name="fileName">Filename to write to.</param>
 /// <param name="properties">Extended properties.</param>
 public CsvWriter(RowLayout layout, string fileName, CsvProperties properties = default)
     : this(layout, File.Create(fileName), properties, true)
 {
 }
Ejemplo n.º 9
0
        /// <summary>Creates a new csv file with the specified name and writes the whole table.</summary>
        /// <param name="rows">Table to write to the csv file.</param>
        /// <param name="fileName">File name of the csv file.</param>
        /// <param name="properties">Properties of the csv file.</param>
        /// <typeparam name="TStruct">Structure type.</typeparam>
        public static void WriteAlien <TStruct>(IEnumerable <TStruct> rows, string fileName, CsvProperties properties = default)
            where TStruct : struct
        {
            var layout = RowLayout.CreateAlien(typeof(TStruct), false);
            var writer = new CsvWriter(layout, fileName, properties);

            try
            {
                writer.Write(rows);
            }
            finally
            {
                writer.Close();
            }
        }
Ejemplo n.º 10
0
        /// <summary>Creates a string representation of the specified row.</summary>
        /// <param name="properties">The csv properties.</param>
        /// <param name="layout">The row layout.</param>
        /// <param name="row">The row.</param>
        /// <returns>Returns a new string representing the row.</returns>
        public static string RowToString(CsvProperties properties, RowLayout layout, Row row)
        {
            var result = new StringBuilder();
            var values = row.Values;

            for (var i = 0; i < layout.FieldCount; i++)
            {
                if (i > 0)
                {
                    result.Append(properties.Separator);
                }

                if ((values != null) && (values[i] != null))
                {
                    var field = layout[i];
                    switch (field.DataType)
                    {
                    case DataType.Binary:
                    {
                        var str = Base64.NoPadding.Encode((byte[])values[i]);
                        result.Append(str);
                        break;
                    }

                    case DataType.Bool:
                    case DataType.Int8:
                    case DataType.Int16:
                    case DataType.Int32:
                    case DataType.Int64:
                    case DataType.UInt8:
                    case DataType.UInt16:
                    case DataType.UInt32:
                    case DataType.UInt64:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals(0))
                        {
                            break;
                        }

                        var str = values[i].ToString();
                        result.Append(str);
                        break;
                    }

                    case DataType.Char:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals((char)0))
                        {
                            break;
                        }

                        var str = values[i].ToString();
                        result.Append(str);
                        break;
                    }

                    case DataType.Decimal:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals(0m))
                        {
                            break;
                        }

                        var value = (decimal)values[i];
                        result.Append(value.ToString(properties.Format));
                        break;
                    }

                    case DataType.Single:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals(0f))
                        {
                            break;
                        }

                        var value = (float)values[i];
                        result.Append(value.ToString("R", properties.Format));
                        break;
                    }

                    case DataType.Double:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals(0d))
                        {
                            break;
                        }

                        var value = (double)values[i];
                        result.Append(value.ToString("R", properties.Format));
                        break;
                    }

                    case DataType.TimeSpan:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals(TimeSpan.Zero))
                        {
                            break;
                        }

                        var str = field.GetString(values[i], $"{properties.StringMarker}", properties.Format);
                        result.Append(str);
                        break;
                    }

                    case DataType.DateTime:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals(new DateTime(0)))
                        {
                            break;
                        }

                        string str;
                        if (properties.DateTimeFormat != null)
                        {
                            str = ((DateTime)values[i]).ToString(properties.DateTimeFormat, properties.Format);
                        }
                        else
                        {
                            str = field.GetString(values[i], $"{properties.StringMarker}", properties.Format);
                        }

                        result.Append(str);
                        break;
                    }

                    case DataType.User:
                    case DataType.String:
                    {
                        if (!properties.SaveDefaultValues && values[i].Equals(string.Empty))
                        {
                            break;
                        }

                        var str = values[i] == null ? string.Empty : values[i].ToString();
                        str = str.EscapeUtf8();
                        if (properties.StringMarker.HasValue)
                        {
                            str = str.Replace($"{properties.StringMarker}", $"{properties.StringMarker}{properties.StringMarker}");
                            result.Append(properties.StringMarker);
                        }

                        if (str.Length == 0)
                        {
                            result.Append(" ");
                        }
                        else
                        {
                            if (properties.StringMarker.HasValue)
                            {
                                if (str.StartsWith(properties.StringMarker.ToString()))
                                {
                                    result.Append(" ");
                                }
                            }

                            result.Append(str);
                            if (properties.StringMarker.HasValue)
                            {
                                if (str.EndsWith(properties.StringMarker.ToString()))
                                {
                                    result.Append(" ");
                                }
                            }
                        }

                        if (properties.StringMarker.HasValue)
                        {
                            result.Append(properties.StringMarker);
                        }

                        break;
                    }

                    case DataType.Enum:
                    {
                        if (!properties.SaveDefaultValues && Convert.ToInt32(values[i]).Equals(0))
                        {
                            break;
                        }

                        var str = values[i].ToString();
                        result.Append(str);
                        break;
                    }

                    default:
                        throw new NotImplementedException($"DataType {layout[i].DataType} is not implemented!");
                    }
                }
            }

            return(result.ToString());
        }