PageRenderTime 36ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/Web2.0/_code/CsvDataReader.cs

#
C# | 186 lines | 144 code | 13 blank | 29 comment | 47 complexity | c9bc0f4ce55f36fbdf30149c8c7631cf MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**********************************************************************************************************************
  2. * The contents of this file are subject to the SugarCRM Public License Version 1.1.3 ("License"); You may not use this
  3. * file except in compliance with the License. You may obtain a copy of the License at http://www.sugarcrm.com/SPL
  4. * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
  5. * express or implied. See the License for the specific language governing rights and limitations under the License.
  6. *
  7. * All copies of the Covered Code must include on each user interface screen:
  8. * (i) the "Powered by SugarCRM" logo and
  9. * (ii) the SugarCRM copyright notice
  10. * (iii) the SplendidCRM copyright notice
  11. * in the same form as they appear in the distribution. See full license for requirements.
  12. *
  13. * The Original Code is: SplendidCRM Open Source
  14. * The Initial Developer of the Original Code is SplendidCRM Software, Inc.
  15. * Portions created by SplendidCRM Software are Copyright (C) 2006 SplendidCRM Software, Inc. All Rights Reserved.
  16. * Contributor(s): ______________________________________.
  17. *********************************************************************************************************************/
  18. using System;
  19. using System.IO;
  20. using System.Data;
  21. using System.Data.Common;
  22. using System.Text;
  23. //using MySql.Data.MySqlClient;
  24. namespace SplendidCRM
  25. {
  26. /// <summary>
  27. /// Summary description for CsvDataReader.
  28. /// </summary>
  29. public class CsvDataReader
  30. {
  31. private DataTable m_tbl;
  32. public DataTable Table
  33. {
  34. get { return m_tbl; }
  35. }
  36. public CsvDataReader(Stream stm) : this(stm, ',')
  37. {
  38. }
  39. public CsvDataReader(Stream stm, char chFieldSeparator)
  40. {
  41. m_tbl = new DataTable();
  42. using ( TextReader reader = new StreamReader(stm) )
  43. {
  44. m_tbl.Columns.Add("Column001");
  45. string sLine = null;
  46. while ( (sLine = reader.ReadLine()) != null )
  47. {
  48. if ( sLine.Length == 0 )
  49. continue;
  50. DataRow row = m_tbl.NewRow();
  51. m_tbl.Rows.Add(row);
  52. int i = 0;
  53. int nMode = 0;
  54. int nField = 0;
  55. bool bContinueParsing = true;
  56. while ( bContinueParsing )
  57. {
  58. switch ( nMode )
  59. {
  60. case 0: // Search for next entry.
  61. {
  62. if ( chFieldSeparator == ControlChars.Tab )
  63. {
  64. // Don't skip the tab when it is used as a separator.
  65. while ( Char.IsWhiteSpace(sLine[i]) && sLine[i] != ControlChars.Tab )
  66. i++;
  67. }
  68. else
  69. {
  70. while ( Char.IsWhiteSpace(sLine[i]) )
  71. i++;
  72. }
  73. nMode = 1;
  74. break;
  75. }
  76. case 1: // Determine if field is quoted or unquoted.
  77. {
  78. // first check if field is empty.
  79. char chPunctuation = sLine[i];
  80. if ( chPunctuation == chFieldSeparator )
  81. {
  82. i++;
  83. nField++;
  84. if ( nField >= m_tbl.Columns.Count )
  85. m_tbl.Columns.Add("Column" + nField.ToString("000"));
  86. nMode = 0;
  87. }
  88. if ( chPunctuation == '\"' )
  89. {
  90. i++;
  91. // Field is quoted, so start reading until next quote.
  92. nMode = 3;
  93. }
  94. else
  95. {
  96. // Field is unquoted, so start reading until next separator or end-of-line.
  97. nMode = 2;
  98. }
  99. break;
  100. }
  101. case 2: // Extract unquoted field.
  102. {
  103. nField++;
  104. if ( nField > m_tbl.Columns.Count )
  105. m_tbl.Columns.Add("Column" + nField.ToString("000"));
  106. int nFieldStart = i;
  107. // Field is unquoted, so start reading until next separator or end-of-line.
  108. while ( i < sLine.Length && sLine[i] != chFieldSeparator )
  109. i++;
  110. int nFieldEnd = i;
  111. string sField = sLine.Substring(nFieldStart, nFieldEnd-nFieldStart);
  112. row[nField-1] = sField;
  113. nMode = 0;
  114. i++;
  115. break;
  116. }
  117. case 3: // Extract quoted field.
  118. {
  119. nField++;
  120. if ( nField > m_tbl.Columns.Count )
  121. m_tbl.Columns.Add("Column" + nField.ToString("000"));
  122. bool bMultiline = false;
  123. StringBuilder sbField = new StringBuilder();
  124. do
  125. {
  126. int nFieldStart = i;
  127. // Field is quoted, so start reading until next quote. Watch out for an escaped quote (two double quotes).
  128. while ( ( i < sLine.Length && sLine[i] != '\"' ) || ( i + 1 < sLine.Length && sLine[i] == '\"' && sLine[i + 1] == '\"' ) )
  129. {
  130. if ( i + 1 < sLine.Length && sLine[i] == '\"' && sLine[i + 1] == '\"' )
  131. i++;
  132. i++;
  133. }
  134. int nFieldEnd = i;
  135. if ( sbField.Length > 0 )
  136. sbField.Append(ControlChars.CrLf);
  137. sbField.Append(sLine.Substring(nFieldStart, nFieldEnd - nFieldStart));
  138. // 08/23/2006 Paul. If we are at the end of the line, then it must be a multi-line string.
  139. bMultiline = (i == sLine.Length);
  140. if ( bMultiline )
  141. {
  142. sLine = reader.ReadLine();
  143. i = 0;
  144. if ( sLine == null )
  145. break;
  146. }
  147. }
  148. while ( bMultiline );
  149. if ( sLine != null )
  150. {
  151. // Skip all characters until we reach the separator or end-of-line.
  152. while ( i < sLine.Length && sLine[i] != chFieldSeparator )
  153. i++;
  154. }
  155. string sField = sbField.ToString();
  156. sField = sField.Replace("\"\"", "\"");
  157. row[nField-1] = sField;
  158. nMode = 0;
  159. i++;
  160. break;
  161. }
  162. default:
  163. bContinueParsing = false;
  164. break;
  165. }
  166. if ( i >= sLine.Length )
  167. break;
  168. }
  169. }
  170. }
  171. }
  172. }
  173. }