/// <summary>
        /// Reads the values of a single CSV formatted record into a given
        /// <see cref="CsvValues"/> container.
        /// </summary>
        /// <param name="aTextReader"></param>
        /// <param name="vValues">
        /// Destination that will receive the record data. All values in this
        /// instance are overwritten. Missing values are overwritten with String.Empty
        /// references.
        /// </param>
        /// <returns>
        /// If a record was read, then the number of values that were actually found is
        /// returned. For an empty line zero is returned. If an immediate end of file was
        /// encountered, then -1 is returned.
        /// </returns>
        public int ReadLine(TextReader aTextReader, CsvValues vValues)
        {
            if ((aTextReader == null) || (vValues == null))
            {
                throw new ArgumentNullException();
            }

            Reset();
            bool fMore = false;

            do
            {
                string sLine = aTextReader.ReadLine();
                if (sLine == null)
                {
                    if (fMore)
                    {
                        throw new FormatException("CSV truncated");
                    }
                    return -1;
                }

                fMore = !ParseLine(sLine, vValues);
            }
            while (fMore);

            // Store the number of actual values that have been read.

            vValues.InternalSetActualValues(m_nValueIndex);

            // After splitting up all values from the given CSV line, the final nValueIndex
            // tells us the number of values that we actually extracted from the line. If
            // the values array expects more data, then it is filled with empty string values.

            for (int i = m_nValueIndex; i < m_aCsvFile.MaxValues; ++i)
            {
                vValues[i] = String.Empty;
            }

            //

            return m_nValueIndex;
        }
        private string _GetCsvStatementData(Swift9xxBase aStmt)
        {
            StringBuilder sb = new StringBuilder(20000);

            sb.Append("EntryDate;ValueDate;Value;AcctNo;BankCode;Name1;Name2;PaymtPurpose;EntryText;PrimaNotaNo;TranTypeIdCode;ZkaTranCode;TextKeyExt;BankRef;OwnerRef;SupplementaryDetails");
            sb.Append(Environment.NewLine);

            foreach (SwiftStatementLine aStmtLine in aStmt.StatementLines)
            {
                CsvValues aCsv = new CsvValues(16);

                if (!aStmtLine.EntryDate.IsNull)
                {
                    aCsv[0] = aStmtLine.EntryDate.ToString(SwiftDateFormat.StandardDate);
                }
                if (!aStmtLine.ValueDate.IsNull)
                {
                    aCsv[1] = aStmtLine.ValueDate.ToString(SwiftDateFormat.StandardDate);
                }

                aCsv[2] = SwiftAmt.Format(aStmtLine.DecValue, ',', 2);
                aCsv[3] = aStmtLine.PayeePayerAcctNo;
                aCsv[4] = aStmtLine.PayeePayerBankCode;
                aCsv[5] = aStmtLine.PayeePayerName1;
                aCsv[6] = aStmtLine.PayeePayerName2;

                string[] vsPaymtPurpose = aStmtLine.PaymtPurpose;
                if (vsPaymtPurpose != null)
                {
                    aCsv[7] = String.Join("|", vsPaymtPurpose);
                }

                aCsv[8] = aStmtLine.EntryText;
                aCsv[9] = aStmtLine.PrimaNotaNo;
                aCsv[10] = aStmtLine.TranTypeIdCode;
                aCsv[11] = aStmtLine.ZkaTranCode;
                aCsv[12] = aStmtLine.TextKeyExt;
                aCsv[13] = aStmtLine.BankRef;
                aCsv[14] = aStmtLine.OwnerRef;
                aCsv[15] = aStmtLine.SupplementaryDetails;

                sb.Append(aCsv);
                sb.Append(Environment.NewLine);
            }

            return sb.ToString();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sLine"></param>
        /// <param name="vValues"></param>
        /// <returns>
        /// If the final state after parsing the line indicates the end of the record,
        /// then true is returned.
        /// </returns>
        internal bool ParseLine(string sLine, CsvValues vValues)
        {
            int nMaxValues = m_aCsvFile.MaxValues;
            char chComma = m_aCsvFile.Comma;
            char chQuote = m_aCsvFile.Quote;

            int nLineLength = sLine.Length;
            for (int i = 0; i <= nLineLength; ++i)
            {
                int ch = (i == nLineLength) ? -1 : sLine[i];

                // Process character according to state machine.

                switch (m_nState)
                {

                // StartValue - This is the initial state which is reentered every time when
                // we await another field value.

                case ParseState.StartValue:
                    if (ch == chQuote)
                    {
                        m_nState = ParseState.QuotedValue;
                    }
                    else if (ch == ' ')
                    {
                        // m_nState = ParseState.StartValue;
                    }
                    else if (ch == chComma)
                    {
                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = String.Empty;
                        }
                        ++m_nValueIndex;
                        // m_nState = ParseState.StartValue;
                    }
                    else if (ch == -1)
                    {
                        m_nState = ParseState.Done;
                    }
                    else
                    {
                        m_sb.Append((char)ch);
                        m_nState = ParseState.VanillaValue;
                    }
                    break;

                // VanillaValue - The characters of an unquoted value are collected until a
                // comma or the end of the line is encountered.

                case ParseState.VanillaValue:
                    if ((ch == chComma) || (ch == -1))
                    {
                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = m_sb.ToString().TrimEnd(' ');
                        }
                        ++m_nValueIndex;
                        m_sb.Length = 0;
                        m_nState = (ch == -1) ? ParseState.Done : ParseState.StartValue;
                    }
                    else
                    {
                        m_sb.Append((char)ch);
                        // m_nState = ParseState.VanillaValue;
                    }
                    break;

                // QuotedValue - The characters of a quoted value are collected. If another
                // quote is encountered it could be a quoted quote or the value could end.

                case ParseState.QuotedValue:
                    if (ch == chQuote)
                    {
                        m_nState = ParseState.QuoteInQuotedValue;
                    }
                    else if (ch == -1)
                    {
                        m_sb.Append(Environment.NewLine);
                        // m_nState = ParseState.QuotedValue;
                    }
                    else
                    {
                        m_sb.Append((char)ch);
                        // m_nState = ParseState.QuotedValue;
                    }
                    break;

                // QuoteInQuotedValue - A quote within a quoted value was encountered. We must
                // now find another quote, or a comma delimiter, or the end of the line.

                case ParseState.QuoteInQuotedValue:
                    if (ch == chQuote)
                    {
                        m_sb.Append((char)ch);
                        m_nState = ParseState.QuotedValue;
                    }
                    else if ((ch == chComma) || (ch == -1))
                    {
                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = m_sb.ToString();
                        }
                        ++m_nValueIndex;
                        m_sb.Length = 0;
                        m_nState = (ch == -1) ? ParseState.Done : ParseState.StartValue;
                    }
                    else if (ch == ' ')
                    {
                        // This is either malformed, or there really is whitespace after the
                        // closing quote.

                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = m_sb.ToString();
                        }
                        ++m_nValueIndex;
                        m_sb.Length = 0;
                        m_nState = ParseState.EndQuotedValue;
                    }
                    else
                    {
                        // This is an invalid structure. Within a quoted field, all quotes
                        // must be doubled. Anyway we try to recover gracefully by simply
                        // accepting the quote and the subsequent character.

                        m_sb.Append(chQuote);
                        m_sb.Append((char)ch);
                        m_nState = ParseState.QuotedValue;
                    }
                    break;

                case ParseState.EndQuotedValue:
                    if (ch == chComma)
                    {
                        m_nState = ParseState.StartValue;
                    }
                    else if (ch == -1)
                    {
                        m_nState = ParseState.Done;
                    }
                    else if (ch != ' ')
                    {
                        // This is an invalid structure. Only whitespace may appear until the
                        // next field. We try to recover by backing up and continuing the
                        // previous field. If multiple whitespaces occur after the quote, then
                        // they will be collapsed into a single whitespace.

                        Debug.Assert(m_nValueIndex > 0);
                        Debug.Assert(m_sb.Length == 0);

                        --m_nValueIndex;
                        m_sb.Append(vValues[m_nValueIndex]);
                        m_sb.Append(chQuote);
                        m_sb.Append(' ');
                        m_sb.Append((char)ch);
                        m_nState = ParseState.QuotedValue;
                    }
                    break;
                }
            }

            //

            return m_nState == ParseState.Done;
        }
Example #4
0
 public void SetHeader(CsvValues aCsvHeader)
 {
     m_nMaxValues = aCsvHeader.ActualValues;
     _BuildHeaderHashtable(aCsvHeader);
 }
Example #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sLine"></param>
        /// <param name="vValues"></param>
        /// <returns>
        /// If the final state after parsing the line indicates the end of the record,
        /// then true is returned.
        /// </returns>

        internal bool ParseLine(string sLine, CsvValues vValues)
        {
            int  nMaxValues = m_aCsvFile.MaxValues;
            char chComma    = m_aCsvFile.Comma;
            char chQuote    = m_aCsvFile.Quote;

            int nLineLength = sLine.Length;

            for (int i = 0; i <= nLineLength; ++i)
            {
                int ch = (i == nLineLength) ? -1 : sLine[i];

                // Process character according to state machine.

                switch (m_nState)
                {
                // StartValue - This is the initial state which is reentered every time when
                // we await another field value.

                case ParseState.StartValue:
                    if (ch == chQuote)
                    {
                        m_nState = ParseState.QuotedValue;
                    }
                    else if (ch == ' ')
                    {
                        // m_nState = ParseState.StartValue;
                    }
                    else if (ch == chComma)
                    {
                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = String.Empty;
                        }
                        ++m_nValueIndex;
                        // m_nState = ParseState.StartValue;
                    }
                    else if (ch == -1)
                    {
                        m_nState = ParseState.Done;
                    }
                    else
                    {
                        m_sb.Append((char)ch);
                        m_nState = ParseState.VanillaValue;
                    }
                    break;

                // VanillaValue - The characters of an unquoted value are collected until a
                // comma or the end of the line is encountered.

                case ParseState.VanillaValue:
                    if ((ch == chComma) || (ch == -1))
                    {
                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = m_sb.ToString().TrimEnd(' ');
                        }
                        ++m_nValueIndex;
                        m_sb.Length = 0;
                        m_nState    = (ch == -1) ? ParseState.Done : ParseState.StartValue;
                    }
                    else
                    {
                        m_sb.Append((char)ch);
                        // m_nState = ParseState.VanillaValue;
                    }
                    break;

                // QuotedValue - The characters of a quoted value are collected. If another
                // quote is encountered it could be a quoted quote or the value could end.

                case ParseState.QuotedValue:
                    if (ch == chQuote)
                    {
                        m_nState = ParseState.QuoteInQuotedValue;
                    }
                    else if (ch == -1)
                    {
                        m_sb.Append(Environment.NewLine);
                        // m_nState = ParseState.QuotedValue;
                    }
                    else
                    {
                        m_sb.Append((char)ch);
                        // m_nState = ParseState.QuotedValue;
                    }
                    break;

                // QuoteInQuotedValue - A quote within a quoted value was encountered. We must
                // now find another quote, or a comma delimiter, or the end of the line.

                case ParseState.QuoteInQuotedValue:
                    if (ch == chQuote)
                    {
                        m_sb.Append((char)ch);
                        m_nState = ParseState.QuotedValue;
                    }
                    else if ((ch == chComma) || (ch == -1))
                    {
                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = m_sb.ToString();
                        }
                        ++m_nValueIndex;
                        m_sb.Length = 0;
                        m_nState    = (ch == -1) ? ParseState.Done : ParseState.StartValue;
                    }
                    else if (ch == ' ')
                    {
                        // This is either malformed, or there really is whitespace after the
                        // closing quote.

                        if (m_nValueIndex < nMaxValues)
                        {
                            vValues[m_nValueIndex] = m_sb.ToString();
                        }
                        ++m_nValueIndex;
                        m_sb.Length = 0;
                        m_nState    = ParseState.EndQuotedValue;
                    }
                    else
                    {
                        // This is an invalid structure. Within a quoted field, all quotes
                        // must be doubled. Anyway we try to recover gracefully by simply
                        // accepting the quote and the subsequent character.

                        m_sb.Append(chQuote);
                        m_sb.Append((char)ch);
                        m_nState = ParseState.QuotedValue;
                    }
                    break;

                case ParseState.EndQuotedValue:
                    if (ch == chComma)
                    {
                        m_nState = ParseState.StartValue;
                    }
                    else if (ch == -1)
                    {
                        m_nState = ParseState.Done;
                    }
                    else if (ch != ' ')
                    {
                        // This is an invalid structure. Only whitespace may appear until the
                        // next field. We try to recover by backing up and continuing the
                        // previous field. If multiple whitespaces occur after the quote, then
                        // they will be collapsed into a single whitespace.

                        Debug.Assert(m_nValueIndex > 0);
                        Debug.Assert(m_sb.Length == 0);

                        --m_nValueIndex;
                        m_sb.Append(vValues[m_nValueIndex]);
                        m_sb.Append(chQuote);
                        m_sb.Append(' ');
                        m_sb.Append((char)ch);
                        m_nState = ParseState.QuotedValue;
                    }
                    break;
                }
            }

            //

            return(m_nState == ParseState.Done);
        }
        private void _BuildHeaderHashtable(CsvValues aCsvHeader)
        {
            m_vHeader = new Hashtable();
            for (int i = 0; i < aCsvHeader.MaxValues; ++i)
            {
                string sColName = aCsvHeader[i];
                if (!string.IsNullOrEmpty(sColName))
                {
                    // Before we add the column name, we check whether the same column name
                    // was already used. If so, then we generate an unique column name by
                    // appending a number.

                    string sBaseName = sColName;
                    int n = 2;

                    while (m_vHeader.ContainsKey(sColName))
                    {
                        sColName = sBaseName + n.ToString(CultureInfo.InvariantCulture);
                        ++n;
                    }

                    // Now we have a unique column name and thus can safely add the header
                    // entry.

                    m_vHeader.Add(sColName, i);
                }
            }
        }
        private int _ReadValues(CsvValues vValues)
        {
            // Read one CSV line from the StreamReader. If we encounter the end of the
            // StreamReader, then -1 is returned. Only if a non-empty line was read, then we
            // update the line number.

            int nValueCount = m_aParser.ReadLine(m_aReader, vValues);
            if (nValueCount > 0)
            {
                ++m_nLine;
            }

            return nValueCount;
        }
        public void WriteLine(CsvValues aCsv)
        {
            Debug.Assert(m_aReader == null);
            Debug.Assert(m_aWriter != null);
            Debug.Assert(aCsv.File == this);

            string sLine = aCsv.ToString(m_chComma, m_chQuote);
            m_aWriter.WriteLine(sLine);
        }
        /// <summary>
        /// Writing the CSV header creates an internal hashtable that associates the column
        /// indices with their column names.
        /// </summary>
        public void WriteHeader(CsvValues aCsvHeader)
        {
            Debug.Assert(m_aReader == null);
            Debug.Assert(m_aWriter != null);
            Debug.Assert(aCsvHeader.File == this);

            _BuildHeaderHashtable(aCsvHeader);
            string sLine = aCsvHeader.ToString(m_chComma, m_chQuote);
            m_aWriter.WriteLine(sLine);
        }
Example #10
0
 public void SetHeader(CsvValues aCsvHeader)
 {
     m_nMaxValues = aCsvHeader.ActualValues;
     _BuildHeaderHashtable(aCsvHeader);
 }
Example #11
0
        public CsvValues ReadLine()
        {
            Debug.Assert(m_aReader != null);
            Debug.Assert(m_aWriter == null);

            CsvValues aCsv = new CsvValues(this, m_nMaxValues);
            int nValueCount = _ReadValues(aCsv);
            return nValueCount < 0 ? null : aCsv;
        }
Example #12
0
        /// <summary>
        /// Successfully reading the CSV header creates an internal hashtable that associates
        /// the column indices with their column names. In addition, the
        /// <see cref="MaxValues"/> property is adjusted to the actual number of values that
        /// were found in the header line.
        /// </summary>
        public CsvValues ReadHeader()
        {
            Debug.Assert(m_aReader != null);
            Debug.Assert(m_aWriter == null);

            CsvValues aCsvHeader = new CsvValues(this, m_nMaxValues);
            int nMaxValues = _ReadValues(aCsvHeader);
            if (nMaxValues <= 0)
            {
                throw new FormatException("Csv");
            }

            SetHeader(aCsvHeader);

            return aCsvHeader;
        }