/src/CsvHelper/Configuration/CsvConfiguration.cs

https://github.com/JoshClose/CsvHelper · C# · 205 lines · 130 code · 31 blank · 44 comment · 23 complexity · d9c861936648556b1317d297d255cd78 MD5 · raw file

  1. // Copyright 2009-2021 Josh Close
  2. // This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
  3. // See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
  4. // https://github.com/JoshClose/CsvHelper
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Globalization;
  8. using System.IO;
  9. using System.Linq;
  10. using System.Reflection;
  11. using System.Text;
  12. using CsvHelper.TypeConversion;
  13. namespace CsvHelper.Configuration
  14. {
  15. /// <summary>
  16. /// Configuration used for reading and writing CSV data.
  17. /// </summary>
  18. public record CsvConfiguration : IReaderConfiguration, IWriterConfiguration
  19. {
  20. private string newLine = "\r\n";
  21. /// <inheritdoc/>
  22. public virtual bool AllowComments { get; set; }
  23. /// <inheritdoc/>
  24. public virtual BadDataFound BadDataFound { get; set; } = ConfigurationFunctions.BadDataFound;
  25. /// <inheritdoc/>
  26. public virtual int BufferSize { get; set; } = 0x1000;
  27. /// <inheritdoc/>
  28. public virtual bool CacheFields { get; set; }
  29. /// <inheritdoc/>
  30. public virtual char Comment { get; set; } = '#';
  31. /// <inheritdoc/>
  32. public virtual bool CountBytes { get; set; }
  33. /// <inheritdoc/>
  34. public virtual CultureInfo CultureInfo { get; protected set; }
  35. /// <inheritdoc/>
  36. public virtual string Delimiter { get; set; }
  37. /// <inheritdoc/>
  38. public virtual bool DetectDelimiter { get; set; }
  39. /// <inheritdoc/>
  40. public virtual string[] DetectDelimiterValues { get; set; } = new[] { ",", ";", "|", "\t" };
  41. /// <inheritdoc/>
  42. public virtual bool DetectColumnCountChanges { get; set; }
  43. /// <inheritdoc/>
  44. public virtual IComparer<string> DynamicPropertySort { get; set; }
  45. /// <inheritdoc/>
  46. public virtual Encoding Encoding { get; set; } = Encoding.UTF8;
  47. /// <inheritdoc/>
  48. public virtual char Escape { get; set; } = '"';
  49. /// <inheritdoc/>
  50. public virtual bool ExceptionMessagesContainRawData { get; set; } = true;
  51. /// <inheritdoc/>
  52. public virtual GetConstructor GetConstructor { get; set; } = ConfigurationFunctions.GetConstructor;
  53. /// <inheritdoc/>
  54. public virtual GetDynamicPropertyName GetDynamicPropertyName { get; set; } = ConfigurationFunctions.GetDynamicPropertyName;
  55. /// <inheritdoc/>
  56. public virtual bool HasHeaderRecord { get; set; } = true;
  57. /// <inheritdoc/>
  58. public virtual HeaderValidated HeaderValidated { get; set; } = ConfigurationFunctions.HeaderValidated;
  59. /// <inheritdoc/>
  60. public virtual bool IgnoreBlankLines { get; set; } = true;
  61. /// <inheritdoc/>
  62. public virtual bool IgnoreReferences { get; set; }
  63. /// <inheritdoc/>
  64. public virtual bool IncludePrivateMembers { get; set; }
  65. /// <inheritdoc/>
  66. public virtual char[] InjectionCharacters { get; set; } = new[] { '=', '@', '+', '-' };
  67. /// <inheritdoc/>
  68. public virtual char InjectionEscapeCharacter { get; set; } = '\t';
  69. /// <inheritdoc/>
  70. public bool IsNewLineSet { get; private set; }
  71. /// <inheritdoc/>
  72. public virtual bool LeaveOpen { get; set; }
  73. /// <inheritdoc/>
  74. public virtual bool LineBreakInQuotedFieldIsBadData { get; set; }
  75. /// <inheritdoc/>
  76. public virtual MemberTypes MemberTypes { get; set; } = MemberTypes.Properties;
  77. /// <inheritdoc/>
  78. public virtual MissingFieldFound MissingFieldFound { get; set; } = ConfigurationFunctions.MissingFieldFound;
  79. /// <inheritdoc/>
  80. public virtual CsvMode Mode { get; set; }
  81. /// <inheritdoc/>
  82. public virtual string NewLine
  83. {
  84. get => newLine;
  85. set
  86. {
  87. IsNewLineSet = true;
  88. newLine = value;
  89. }
  90. }
  91. /// <inheritdoc/>
  92. public virtual PrepareHeaderForMatch PrepareHeaderForMatch { get; set; } = ConfigurationFunctions.PrepareHeaderForMatch;
  93. /// <inheritdoc/>
  94. public virtual int ProcessFieldBufferSize { get; set; } = 1024;
  95. /// <inheritdoc/>
  96. public virtual char Quote { get; set; } = '"';
  97. /// <inheritdoc/>
  98. public virtual ReadingExceptionOccurred ReadingExceptionOccurred { get; set; } = ConfigurationFunctions.ReadingExceptionOccurred;
  99. /// <inheritdoc/>
  100. public virtual ReferenceHeaderPrefix ReferenceHeaderPrefix { get; set; }
  101. /// <inheritdoc/>
  102. public virtual bool SanitizeForInjection { get; set; }
  103. /// <inheritdoc/>
  104. public ShouldQuote ShouldQuote { get; set; } = ConfigurationFunctions.ShouldQuote;
  105. /// <inheritdoc/>
  106. public virtual ShouldSkipRecord ShouldSkipRecord { get; set; } = ConfigurationFunctions.ShouldSkipRecord;
  107. /// <inheritdoc/>
  108. public virtual ShouldUseConstructorParameters ShouldUseConstructorParameters { get; set; } = ConfigurationFunctions.ShouldUseConstructorParameters;
  109. /// <inheritdoc/>
  110. public virtual TrimOptions TrimOptions { get; set; }
  111. /// <inheritdoc/>
  112. public virtual bool UseNewObjectForNullReferenceMembers { get; set; } = true;
  113. /// <inheritdoc/>
  114. public virtual char[] WhiteSpaceChars { get; set; } = new char[] { ' ' };
  115. /// <summary>
  116. /// Initializes a new instance of the <see cref="CsvConfiguration"/> class
  117. /// using the given <see cref="System.Globalization.CultureInfo"/>. Since <see cref="Delimiter"/>
  118. /// uses <see cref="CultureInfo"/> for it's default, the given <see cref="System.Globalization.CultureInfo"/>
  119. /// will be used instead.
  120. /// </summary>
  121. /// <param name="cultureInfo">The culture information.</param>
  122. public CsvConfiguration(CultureInfo cultureInfo)
  123. {
  124. CultureInfo = cultureInfo;
  125. Delimiter = cultureInfo.TextInfo.ListSeparator;
  126. }
  127. /// <summary>
  128. /// Validates the configuration.
  129. /// </summary>
  130. public void Validate()
  131. {
  132. var escape = Escape.ToString();
  133. var quote = Quote.ToString();
  134. var lineEndings = new[] { "\r", "\n", "\r\n" };
  135. var whiteSpaceChars = WhiteSpaceChars.Select(c => c.ToString()).ToArray();
  136. // Escape
  137. if (escape == Delimiter) throw new ConfigurationException($"{Escape} and {Delimiter} cannot be the same.");
  138. if (escape == NewLine && IsNewLineSet) throw new ConfigurationException($"{Escape} and {NewLine} cannot be the same.");
  139. if (lineEndings.Contains(Escape.ToString()) && !IsNewLineSet) throw new ConfigurationException($"{Escape} cannot be a line ending. ('\\r', '\\n', '\\r\\n')");
  140. if (whiteSpaceChars.Contains(escape)) throw new ConfigurationException($"{Escape} cannot be a WhiteSpaceChar.");
  141. // Quote
  142. if (quote == Delimiter) throw new ConfigurationException($"{Quote} and {Delimiter} cannot be the same.");
  143. if (quote == NewLine && IsNewLineSet) throw new ConfigurationException($"{Quote} and {NewLine} cannot be the same.");
  144. if (lineEndings.Contains(quote)) throw new ConfigurationException($"{Quote} cannot be a line ending. ('\\r', '\\n', '\\r\\n')");
  145. if (whiteSpaceChars.Contains(quote)) throw new ConfigurationException($"{Quote} cannot be a WhiteSpaceChar.");
  146. // Delimiter
  147. if (Delimiter == NewLine && IsNewLineSet) throw new ConfigurationException($"{Delimiter} and {NewLine} cannot be the same.");
  148. if (lineEndings.Contains(Delimiter)) throw new ConfigurationException($"{Delimiter} cannot be a line ending. ('\\r', '\\n', '\\r\\n')");
  149. if (whiteSpaceChars.Contains(Delimiter)) throw new ConfigurationException($"{Delimiter} cannot be a WhiteSpaceChar.");
  150. // Detect Delimiter
  151. if (DetectDelimiter && DetectDelimiterValues.Length == 0) throw new ConfigurationException($"At least one value is required for {nameof(DetectDelimiterValues)} when {nameof(DetectDelimiter)} is enabled.");
  152. }
  153. }
  154. }