[chronojump] CSV support 25% (read file works)



commit 035ca5662198d13ac8f80d2446cf0e157dceccb9
Author: Xavier de Blas <xaviblas gmail com>
Date:   Tue Apr 8 14:33:51 2014 +0200

    CSV support 25% (read file works)

 src/Makefile.am   |    1 +
 src/chronojump.cs |    3 +-
 src/utilCSV.cs    |  356 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 359 insertions(+), 1 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 42befa9..2961cff 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -138,6 +138,7 @@ SOURCES = \
        treeViewMultiChronopic.cs\
        util.cs\
        utilAll.cs\
+       utilCSV.cs\
        utilDate.cs\
        utilEncoder.cs\
        utilGtk.cs\
diff --git a/src/chronojump.cs b/src/chronojump.cs
index 474aeba..f4847a5 100644
--- a/src/chronojump.cs
+++ b/src/chronojump.cs
@@ -133,7 +133,8 @@ public class ChronoJump
                Log.WriteLine("baseDir1:" + baseDirectory);
                Log.WriteLine("envPath+rBinPath:" + envPath + Path.PathSeparator + rBinPath);
                
-               
+       
+               //UtilCSV.ReadValues("/tmp/chronojump-encoder-graph-input-multi.csv");  
                
                if(UtilAll.IsWindows())
                        
Environment.SetEnvironmentVariable("GST_PLUGIN_PATH",RelativeToPrefix("lib\\gstreamer-0.10"));
diff --git a/src/utilCSV.cs b/src/utilCSV.cs
new file mode 100644
index 0000000..7fb9784
--- /dev/null
+++ b/src/utilCSV.cs
@@ -0,0 +1,356 @@
+//Jonathan Wood
+//http://www.blackbeltcoder.com/Articles/files/reading-and-writing-csv-files-in-c
+//License: The Code Project Open License (CPOL)
+//http://www.blackbeltcoder.com/Legal/Licenses/CPOL
+
+using System;                          //IDispsable
+using System.IO;                       //for detect OS, StreamReader
+using System.Collections;              //ArrayList
+using System.Collections.Generic;      //List
+using System.Diagnostics;              //Debug
+using System.Text;                     //StringBuilder
+
+
+public class UtilCSV
+{
+       public static void WriteValues(string fileWrite)
+       {
+               using (var writer = new CsvFileWriter(fileWrite))
+               {
+                       //Write each row of data
+                       for (int row = 0; row < 100; row++)
+                       {
+                               // TODO: Populate column values for this row
+                               List<string> columns = new List<string>();
+                               writer.WriteRow(columns);
+                       }
+               }
+       }
+
+       public static void ReadValues(string fileRead)
+       {
+               Log.WriteLine("READING CSV");
+               List<string> columns = new List<string>();
+               using (var reader = new CsvFileReader(fileRead))
+               {
+                       while (reader.ReadRow(columns))
+                       {
+                               string sep = "";
+                               foreach(string str in columns) {
+                                       Log.Write(sep + str);
+                                       sep = ":";
+                               }
+                               Log.Write("\n");
+                       }
+               }
+               Log.WriteLine("READED CSV");
+       }
+}
+
+/// <summary>
+/// Determines how empty lines are interpreted when reading CSV files.
+/// These values do not affect empty lines that occur within quoted fields
+/// or empty lines that appear at the end of the input file.
+/// </summary>
+public enum EmptyLineBehavior
+{
+    /// <summary>
+    /// Empty lines are interpreted as a line with zero columns.
+    /// </summary>
+    NoColumns,
+    /// <summary>
+    /// Empty lines are interpreted as a line with a single empty column.
+    /// </summary>
+    EmptyColumn,
+    /// <summary>
+    /// Empty lines are skipped over as though they did not exist.
+    /// </summary>
+    Ignore,
+    /// <summary>
+    /// An empty line is interpreted as the end of the input file.
+    /// </summary>
+    EndOfFile,
+}
+
+/// <summary>
+/// Common base class for CSV reader and writer classes.
+/// </summary>
+public abstract class CsvFileCommon
+{
+    /// <summary>
+    /// These are special characters in CSV files. If a column contains any
+    /// of these characters, the entire column is wrapped in double quotes.
+    /// </summary>
+    protected char[] SpecialChars = new char[] { ',', '"', '\r', '\n' };
+
+    // Indexes into SpecialChars for characters with specific meaning
+    private const int DelimiterIndex = 0;
+    private const int QuoteIndex = 1;
+
+    /// <summary>
+    /// Gets/sets the character used for column delimiters.
+    /// </summary>
+    public char Delimiter
+    {
+        get { return SpecialChars[DelimiterIndex]; }
+        set { SpecialChars[DelimiterIndex] = value; }
+    }
+
+    /// <summary>
+    /// Gets/sets the character used for column quotes.
+    /// </summary>
+    public char Quote
+    {
+        get { return SpecialChars[QuoteIndex]; }
+        set { SpecialChars[QuoteIndex] = value; }
+    }
+}
+
+/// <summary>
+/// Class for reading from comma-separated-value (CSV) files
+/// </summary>
+public class CsvFileReader : CsvFileCommon, IDisposable
+{
+    // Private members
+    private StreamReader Reader;
+    private string CurrLine;
+    private int CurrPos;
+    private EmptyLineBehavior EmptyLineBehavior;
+
+    /// <summary>
+    /// Initializes a new instance of the CsvFileReader class for the
+    /// specified stream.
+    /// </summary>
+    /// <param name="stream">The stream to read from</param>
+    /// <param name="emptyLineBehavior">Determines how empty lines are handled</param>
+    public CsvFileReader(Stream stream,
+        EmptyLineBehavior emptyLineBehavior = EmptyLineBehavior.NoColumns)
+    {
+        Reader = new StreamReader(stream);
+        EmptyLineBehavior = emptyLineBehavior;
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the CsvFileReader class for the
+    /// specified file path.
+    /// </summary>
+    /// <param name="path">The name of the CSV file to read from</param>
+    /// <param name="emptyLineBehavior">Determines how empty lines are handled</param>
+    public CsvFileReader(string path,
+        EmptyLineBehavior emptyLineBehavior = EmptyLineBehavior.NoColumns)
+    {
+        Reader = new StreamReader(path);
+        EmptyLineBehavior = emptyLineBehavior;
+    }
+
+    /// <summary>
+    /// Reads a row of columns from the current CSV file. Returns false if no
+    /// more data could be read because the end of the file was reached.
+    /// </summary>
+    /// <param name="columns">Collection to hold the columns read</param>
+    public bool ReadRow(List<string> columns)
+    {
+        // Verify required argument
+        if (columns == null)
+            throw new ArgumentNullException("columns");
+
+    ReadNextLine:
+        // Read next line from the file
+        CurrLine = Reader.ReadLine();
+        CurrPos = 0;
+        // Test for end of file
+        if (CurrLine == null)
+            return false;
+        // Test for empty line
+        if (CurrLine.Length == 0)
+        {
+            switch (EmptyLineBehavior)
+            {
+                case EmptyLineBehavior.NoColumns:
+                    columns.Clear();
+                    return true;
+                case EmptyLineBehavior.Ignore:
+                    goto ReadNextLine;
+                case EmptyLineBehavior.EndOfFile:
+                    return false;
+            }
+        }
+
+        // Parse line
+        string column;
+        int numColumns = 0;
+        while (true)
+        {
+            // Read next column
+            if (CurrPos < CurrLine.Length && CurrLine[CurrPos] == Quote)
+                column = ReadQuotedColumn();
+            else
+                column = ReadUnquotedColumn();
+            // Add column to list
+            if (numColumns < columns.Count)
+                columns[numColumns] = column;
+            else
+                columns.Add(column);
+            numColumns++;
+            // Break if we reached the end of the line
+            if (CurrLine == null || CurrPos == CurrLine.Length)
+                break;
+            // Otherwise skip delimiter
+            Debug.Assert(CurrLine[CurrPos] == Delimiter);
+            CurrPos++;
+        }
+        // Remove any unused columns from collection
+        if (numColumns < columns.Count)
+            columns.RemoveRange(numColumns, columns.Count - numColumns);
+        // Indicate success
+        return true;
+    }
+
+    /// <summary>
+    /// Reads a quoted column by reading from the current line until a
+    /// closing quote is found or the end of the file is reached. On return,
+    /// the current position points to the delimiter or the end of the last
+    /// line in the file. Note: CurrLine may be set to null on return.
+    /// </summary>
+    private string ReadQuotedColumn()
+    {
+        // Skip opening quote character
+        Debug.Assert(CurrPos < CurrLine.Length && CurrLine[CurrPos] == Quote);
+        CurrPos++;
+
+        // Parse column
+        StringBuilder builder = new StringBuilder();
+        while (true)
+        {
+            while (CurrPos == CurrLine.Length)
+            {
+                // End of line so attempt to read the next line
+                CurrLine = Reader.ReadLine();
+                CurrPos = 0;
+                // Done if we reached the end of the file
+                if (CurrLine == null)
+                    return builder.ToString();
+                // Otherwise, treat as a multi-line field
+                builder.Append(Environment.NewLine);
+            }
+
+            // Test for quote character
+            if (CurrLine[CurrPos] == Quote)
+            {
+                // If two quotes, skip first and treat second as literal
+                int nextPos = (CurrPos + 1);
+                if (nextPos < CurrLine.Length && CurrLine[nextPos] == Quote)
+                    CurrPos++;
+                else
+                    break;  // Single quote ends quoted sequence
+            }
+            // Add current character to the column
+            builder.Append(CurrLine[CurrPos++]);
+        }
+
+        if (CurrPos < CurrLine.Length)
+        {
+            // Consume closing quote
+            Debug.Assert(CurrLine[CurrPos] == Quote);
+            CurrPos++;
+            // Append any additional characters appearing before next delimiter
+            builder.Append(ReadUnquotedColumn());
+        }
+        // Return column value
+        return builder.ToString();
+    }
+
+    /// <summary>
+    /// Reads an unquoted column by reading from the current line until a
+    /// delimiter is found or the end of the line is reached. On return, the
+    /// current position points to the delimiter or the end of the current
+    /// line.
+    /// </summary>
+    private string ReadUnquotedColumn()
+    {
+        int startPos = CurrPos;
+        CurrPos = CurrLine.IndexOf(Delimiter, CurrPos);
+        if (CurrPos == -1)
+            CurrPos = CurrLine.Length;
+        if (CurrPos > startPos)
+            return CurrLine.Substring(startPos, CurrPos - startPos);
+        return String.Empty;
+    }
+
+    // Propagate Dispose to StreamReader
+    public void Dispose()
+    {
+        Reader.Dispose();
+    }
+}
+
+/// <summary>
+/// Class for writing to comma-separated-value (CSV) files.
+/// </summary>
+public class CsvFileWriter : CsvFileCommon, IDisposable
+{
+    // Private members
+    private StreamWriter Writer;
+    private string OneQuote = null;
+    private string TwoQuotes = null;
+    private string QuotedFormat = null;
+
+    /// <summary>
+    /// Initializes a new instance of the CsvFileWriter class for the
+    /// specified stream.
+    /// </summary>
+    /// <param name="stream">The stream to write to</param>
+    public CsvFileWriter(Stream stream)
+    {
+        Writer = new StreamWriter(stream);
+    }
+
+    /// <summary>
+    /// Initializes a new instance of the CsvFileWriter class for the
+    /// specified file path.
+    /// </summary>
+    /// <param name="path">The name of the CSV file to write to</param>
+    public CsvFileWriter(string path)
+    {
+        Writer = new StreamWriter(path);
+    }
+
+    /// <summary>
+    /// Writes a row of columns to the current CSV file.
+    /// </summary>
+    /// <param name="columns">The list of columns to write</param>
+    public void WriteRow(List<string> columns)
+    {
+        // Verify required argument
+        if (columns == null)
+            throw new ArgumentNullException("columns");
+
+        // Ensure we're using current quote character
+        if (OneQuote == null || OneQuote[0] != Quote)
+        {
+            OneQuote = String.Format("{0}", Quote);
+            TwoQuotes = String.Format("{0}{0}", Quote);
+            QuotedFormat = String.Format("{0}{{0}}{0}", Quote);
+        }
+
+        // Write each column
+        for (int i = 0; i < columns.Count; i++)
+        {
+            // Add delimiter if this isn't the first column
+            if (i > 0)
+                Writer.Write(Delimiter);
+            // Write this column
+            if (columns[i].IndexOfAny(SpecialChars) == -1)
+                Writer.Write(columns[i]);
+            else
+                Writer.Write(QuotedFormat, columns[i].Replace(OneQuote, TwoQuotes));
+        }
+        Writer.WriteLine();
+    }
+
+    // Propagate Dispose to StreamWriter
+    public void Dispose()
+    {
+        Writer.Dispose();
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]