Decompiled source of CSV Helper v1.0.0
BepInEx/patchers/CsvHelper.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Diagnostics; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Sources; using CsvHelper.Configuration; using CsvHelper.Configuration.Attributes; using CsvHelper.Delegates; using CsvHelper.Expressions; using CsvHelper.TypeConversion; using Microsoft.CSharp.RuntimeBinder; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("CsvHelper.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000db97564beef98ad18a76ba31f769fab92b14341c9c37ed12f8004bb2a1a7fe42ad829b0e285915a816f05a32325c5e0ba83bd69d8f4d26a0785ccf446749842ad038f7325601a99c59a323dfa7ecf210139159da0aad1822b5d9c9be6d914ecbaa8b8c908c4af798a89b8777010971d81975079a49662ced398c742ff186a94")] [assembly: TargetFramework(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")] [assembly: AssemblyCompany("Josh Close")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2009-2024 Josh Close")] [assembly: AssemblyDescription("A library for reading and writing CSV files. Extremely fast, flexible, and easy to use. Supports reading and writing of custom class objects.")] [assembly: AssemblyFileVersion("33.1.0.26")] [assembly: AssemblyInformationalVersion("33.1.0+5dad8b8b1d8b074f8353cfd482e939db788a8927")] [assembly: AssemblyProduct("CsvHelper")] [assembly: AssemblyTitle("CsvHelper")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JoshClose/CsvHelper")] [assembly: AssemblyVersion("33.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CsvHelper { public static class ArrayHelper { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Trim(char[] buffer, ref int start, ref int length, char[] trimChars) { for (int i = start; i < start + length; i++) { char c = buffer[i]; if (!Contains(trimChars, in c)) { break; } start++; length--; } int num = start + length - 1; while (num > start) { char c2 = buffer[num]; if (Contains(trimChars, in c2)) { length--; num--; continue; } break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Contains(char[] array, in char c) { for (int i = 0; i < array.Length; i++) { if (array[i] == c) { return true; } } return false; } } [Serializable] public class BadDataException : CsvHelperException { public readonly string Field; public readonly string RawRecord; public BadDataException(string field, string rawRecord, CsvContext context) : base(context) { Field = field; RawRecord = rawRecord; } public BadDataException(string field, string rawRecord, CsvContext context, string message) : base(context, message) { Field = field; RawRecord = rawRecord; } public BadDataException(string field, string rawRecord, CsvContext context, string message, Exception innerException) : base(context, message, innerException) { Field = field; RawRecord = rawRecord; } } internal static class AsyncExtensions { public static ValueTask DisposeAsync(this TextWriter textWriter) { textWriter?.Dispose(); return default(ValueTask); } } public class CsvContext { public virtual TypeConverterOptionsCache TypeConverterOptionsCache { get; set; } = new TypeConverterOptionsCache(); public virtual TypeConverterCache TypeConverterCache { get; set; } = new TypeConverterCache(); public virtual ClassMapCollection Maps { get; private set; } public IParser? Parser { get; private set; } public IReader? Reader { get; internal set; } public IWriter? Writer { get; internal set; } public CsvConfiguration Configuration { get; private set; } public CsvContext(IReader reader) { Reader = reader; Parser = reader.Parser; Configuration = (reader.Configuration as CsvConfiguration) ?? throw new InvalidOperationException("IReader.Configuration must be of type CsvConfiguration to be used in the context."); Maps = new ClassMapCollection(this); } public CsvContext(IParser parser) { Parser = parser; Configuration = (parser.Configuration as CsvConfiguration) ?? throw new InvalidOperationException("IParser.Configuration must be of type CsvConfiguration to be used in the context."); Maps = new ClassMapCollection(this); } public CsvContext(IWriter writer) { Writer = writer; Configuration = (writer.Configuration as CsvConfiguration) ?? throw new InvalidOperationException("IWriter.Configuration must be of type CsvConfiguration to be used in the context."); Maps = new ClassMapCollection(this); } public CsvContext(CsvConfiguration configuration) { Configuration = configuration; Maps = new ClassMapCollection(this); } public virtual TMap RegisterClassMap<TMap>() where TMap : ClassMap { TMap val = ObjectResolver.Current.Resolve<TMap>(Array.Empty<object>()); RegisterClassMap(val); return val; } public virtual ClassMap RegisterClassMap(Type classMapType) { if (!typeof(ClassMap).IsAssignableFrom(classMapType)) { throw new ArgumentException("The class map type must inherit from CsvClassMap."); } ClassMap classMap = (ClassMap)ObjectResolver.Current.Resolve(classMapType); RegisterClassMap(classMap); return classMap; } public virtual void RegisterClassMap(ClassMap map) { if (map.MemberMaps.Count == 0 && map.ReferenceMaps.Count == 0 && map.ParameterMaps.Count == 0) { throw new ConfigurationException("No mappings were specified in the CsvClassMap."); } Maps.Add(map); } public virtual void UnregisterClassMap<TMap>() where TMap : ClassMap { UnregisterClassMap(typeof(TMap)); } public virtual void UnregisterClassMap(Type classMapType) { Maps.Remove(classMapType); } public virtual void UnregisterClassMap() { Maps.Clear(); } public virtual ClassMap<T> AutoMap<T>() { DefaultClassMap<T> defaultClassMap = ObjectResolver.Current.Resolve<DefaultClassMap<T>>(Array.Empty<object>()); defaultClassMap.AutoMap(this); Maps.Add(defaultClassMap); return defaultClassMap; } public virtual ClassMap AutoMap(Type type) { Type type2 = typeof(DefaultClassMap<>).MakeGenericType(type); ClassMap classMap = (ClassMap)ObjectResolver.Current.Resolve(type2); classMap.AutoMap(this); Maps.Add(classMap); return classMap; } } public class CsvDataReader : IDataReader, IDisposable, IDataRecord { private readonly CsvReader csv; private readonly DataTable schemaTable; private bool skipNextRead; public object this[int i] => csv[i] ?? string.Empty; public object this[string name] => csv[name] ?? string.Empty; public int Depth => 0; public bool IsClosed { get; private set; } public int RecordsAffected => 0; public int FieldCount => csv?.Parser.Count ?? 0; public CsvDataReader(CsvReader csv, DataTable? schemaTable = null) { this.csv = csv; csv.Read(); if (csv.Configuration.HasHeaderRecord && csv.HeaderRecord == null) { csv.ReadHeader(); } else { skipNextRead = true; } this.schemaTable = schemaTable ?? GetSchemaTable(); } public void Close() { Dispose(); } public void Dispose() { csv.Dispose(); IsClosed = true; } public bool GetBoolean(int i) { return csv.GetField<bool>(i); } public byte GetByte(int i) { return csv.GetField<byte>(i); } public long GetBytes(int i, long fieldOffset, byte[]? buffer, int bufferoffset, int length) { byte[] field = csv.GetField<byte[]>(i); if (field == null) { return 0L; } if (buffer == null) { buffer = new byte[field.Length]; } Array.Copy(field, fieldOffset, buffer, bufferoffset, length); return field.Length; } public char GetChar(int i) { return csv.GetField<char>(i); } public long GetChars(int i, long fieldoffset, char[]? buffer, int bufferoffset, int length) { char[] array = csv.GetField(i)?.ToCharArray(); if (array == null) { return 0L; } if (buffer == null) { buffer = new char[array.Length]; } Array.Copy(array, fieldoffset, buffer, bufferoffset, length); return array.Length; } public IDataReader GetData(int i) { throw new NotSupportedException(); } public string GetDataTypeName(int i) { if (i >= schemaTable.Rows.Count) { throw new IndexOutOfRangeException($"SchemaTable does not contain a definition for field '{i}'."); } Type obj = schemaTable.Rows[i]["DataType"] as Type; if (obj == null) { throw new InvalidOperationException($"SchemaTable does not contain a 'DataType' of type 'Type' for field '{i}'."); } return obj.Name; } public DateTime GetDateTime(int i) { return csv.GetField<DateTime>(i); } public decimal GetDecimal(int i) { return csv.GetField<decimal>(i); } public double GetDouble(int i) { return csv.GetField<double>(i); } public Type GetFieldType(int i) { return typeof(string); } public float GetFloat(int i) { return csv.GetField<float>(i); } public Guid GetGuid(int i) { return csv.GetField<Guid>(i); } public short GetInt16(int i) { return csv.GetField<short>(i); } public int GetInt32(int i) { return csv.GetField<int>(i); } public long GetInt64(int i) { return csv.GetField<long>(i); } public string GetName(int i) { if (!csv.Configuration.HasHeaderRecord) { return string.Empty; } string[]? headerRecord = csv.HeaderRecord; return ((headerRecord != null) ? headerRecord[i] : null) ?? string.Empty; } public int GetOrdinal(string name) { int fieldIndex = csv.GetFieldIndex(name, 0, isTryGet: true); if (fieldIndex >= 0) { return fieldIndex; } PrepareHeaderForMatchArgs args = new PrepareHeaderForMatchArgs(name, 0); string text = csv.Configuration.PrepareHeaderForMatch(args); string[] headerRecord = csv.HeaderRecord; for (int i = 0; i < ((headerRecord != null) ? headerRecord.Length : 0); i++) { args = new PrepareHeaderForMatchArgs(((headerRecord != null) ? headerRecord[i] : null) ?? string.Empty, i); string @string = csv.Configuration.PrepareHeaderForMatch(args); if (csv.Configuration.CultureInfo.CompareInfo.Compare(text, @string, CompareOptions.IgnoreCase) == 0) { return i; } } throw new IndexOutOfRangeException("Field with name '" + name + "' and prepared name '" + text + "' was not found."); } public DataTable GetSchemaTable() { if (schemaTable != null) { return schemaTable; } DataTable dataTable = new DataTable("SchemaTable"); dataTable.Columns.Add("AllowDBNull", typeof(bool)); dataTable.Columns.Add("AutoIncrementSeed", typeof(long)); dataTable.Columns.Add("AutoIncrementStep", typeof(long)); dataTable.Columns.Add("BaseCatalogName"); dataTable.Columns.Add("BaseColumnName"); dataTable.Columns.Add("BaseColumnNamespace"); dataTable.Columns.Add("BaseSchemaName"); dataTable.Columns.Add("BaseTableName"); dataTable.Columns.Add("BaseTableNamespace"); dataTable.Columns.Add("ColumnName"); dataTable.Columns.Add("ColumnMapping", typeof(MappingType)); dataTable.Columns.Add("ColumnOrdinal", typeof(int)); dataTable.Columns.Add("ColumnSize", typeof(int)); dataTable.Columns.Add("DataType", typeof(Type)); dataTable.Columns.Add("DefaultValue", typeof(object)); dataTable.Columns.Add("Expression"); dataTable.Columns.Add("IsAutoIncrement", typeof(bool)); dataTable.Columns.Add("IsKey", typeof(bool)); dataTable.Columns.Add("IsLong", typeof(bool)); dataTable.Columns.Add("IsReadOnly", typeof(bool)); dataTable.Columns.Add("IsRowVersion", typeof(bool)); dataTable.Columns.Add("IsUnique", typeof(bool)); dataTable.Columns.Add("NumericPrecision", typeof(short)); dataTable.Columns.Add("NumericScale", typeof(short)); dataTable.Columns.Add("ProviderType", typeof(int)); for (int i = 0; i < csv.ColumnCount; i++) { object obj; if (!csv.Configuration.HasHeaderRecord) { obj = i; } else { string[]? headerRecord = csv.HeaderRecord; obj = ((headerRecord != null) ? headerRecord[i] : null); } object value = obj; DataRow dataRow = dataTable.NewRow(); dataRow["AllowDBNull"] = true; dataRow["AutoIncrementSeed"] = DBNull.Value; dataRow["AutoIncrementStep"] = DBNull.Value; dataRow["BaseCatalogName"] = null; dataRow["BaseColumnName"] = value; dataRow["BaseColumnNamespace"] = null; dataRow["BaseSchemaName"] = null; dataRow["BaseTableName"] = null; dataRow["BaseTableNamespace"] = null; dataRow["ColumnName"] = value; dataRow["ColumnMapping"] = MappingType.Element; dataRow["ColumnOrdinal"] = i; dataRow["ColumnSize"] = int.MaxValue; dataRow["DataType"] = typeof(string); dataRow["DefaultValue"] = null; dataRow["Expression"] = null; dataRow["IsAutoIncrement"] = false; dataRow["IsKey"] = false; dataRow["IsLong"] = false; dataRow["IsReadOnly"] = true; dataRow["IsRowVersion"] = false; dataRow["IsUnique"] = false; dataRow["NumericPrecision"] = DBNull.Value; dataRow["NumericScale"] = DBNull.Value; dataRow["ProviderType"] = DbType.String; dataTable.Rows.Add(dataRow); } return dataTable; } public string GetString(int i) { return csv.GetField(i) ?? string.Empty; } public object GetValue(int i) { object obj; if (!IsDBNull(i)) { obj = csv.GetField(i); if (obj == null) { return string.Empty; } } else { obj = DBNull.Value; } return obj; } public int GetValues(object[] values) { for (int i = 0; i < values.Length; i++) { values[i] = (IsDBNull(i) ? ((IConvertible)DBNull.Value) : ((IConvertible)(csv.GetField(i) ?? string.Empty))); } return csv.Parser.Count; } public bool IsDBNull(int i) { string field = csv.GetField(i); List<string> nullValues = csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues; if (field != null) { return nullValues.Contains(field); } return true; } public bool NextResult() { return false; } public bool Read() { if (skipNextRead) { skipNextRead = false; return true; } return csv.Read(); } } [Serializable] public class CsvHelperException : Exception { [NonSerialized] private readonly CsvContext? context; public CsvContext? Context => context; protected internal CsvHelperException() { } protected internal CsvHelperException(string message) : base(message) { } protected internal CsvHelperException(string message, Exception innerException) : base(message, innerException) { } public CsvHelperException(CsvContext context) { this.context = context; } public CsvHelperException(CsvContext context, string message) : base(AddDetails(message, context)) { this.context = context; } public CsvHelperException(CsvContext context, string message, Exception innerException) : base(AddDetails(message, context), innerException) { this.context = context; } private static string AddDetails(string message, CsvContext context) { string text = new string(' ', 3); StringBuilder stringBuilder = new StringBuilder(); if (context.Reader != null) { stringBuilder.AppendLine("IReader state:"); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "ColumnCount", context.Reader.ColumnCount)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "CurrentIndex", context.Reader.CurrentIndex)); try { StringBuilder stringBuilder2 = new StringBuilder(); if (context.Reader.HeaderRecord != null) { stringBuilder2.Append("[\""); stringBuilder2.Append(string.Join("\",\"", context.Reader.HeaderRecord)); stringBuilder2.Append("\"]"); } stringBuilder.AppendLine(string.Format("{0}{1}:{2}{3}", text, "HeaderRecord", Environment.NewLine, stringBuilder2)); } catch { } } if (context.Parser != null) { stringBuilder.AppendLine("IParser state:"); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "ByteCount", context.Parser.ByteCount)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "CharCount", context.Parser.CharCount)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Row", context.Parser.Row)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "RawRow", context.Parser.RawRow)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Count", context.Parser.Count)); try { string text2 = (context.Configuration.ExceptionMessagesContainRawData ? context.Parser.RawRecord : "Hidden because ExceptionMessagesContainRawData is false."); stringBuilder.AppendLine(text + "RawRecord:" + Environment.NewLine + text2); } catch { } } if (context.Writer != null) { stringBuilder.AppendLine("IWriter state:"); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Row", context.Writer.Row)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Index", context.Writer.Index)); StringBuilder stringBuilder3 = new StringBuilder(); if (context.Writer.HeaderRecord != null) { stringBuilder3.Append("["); if (context.Writer.HeaderRecord.Length != 0) { stringBuilder3.Append("\""); stringBuilder3.Append(string.Join("\",\"", context.Writer.HeaderRecord)); stringBuilder3.Append("\""); } stringBuilder3.Append("]"); } stringBuilder.AppendLine(string.Format("{0}{1}:{2}{3}", text, "HeaderRecord", Environment.NewLine, context.Writer.Row)); } return $"{message}{Environment.NewLine}{stringBuilder}"; } } public enum CsvMode { RFC4180, Escape, NoEscape } public class CsvParser : IParser, IDisposable { [DebuggerDisplay("Start = {Start}, Length = {Length}, Buffer.Length = {Buffer.Length}")] protected readonly struct ProcessedField { public readonly int Start; public readonly int Length; public readonly char[] Buffer; public ProcessedField(int start, int length, char[] buffer) { Start = start; Length = length; Buffer = buffer; } } private enum ReadLineResult { None, Complete, Incomplete } private enum ParserState { None, Spaces, BlankLine, Delimiter, LineEnding, NewLine } [DebuggerDisplay("Start = {Start}, Length = {Length}, QuoteCount = {QuoteCount}, IsBad = {IsBad}")] private struct Field { public int Start; public int Length; public int QuoteCount; public bool IsBad; public bool IsProcessed; } private readonly IParserConfiguration configuration; private readonly FieldCache fieldCache = new FieldCache(); private readonly TextReader reader; private readonly char quote; private readonly char escape; private readonly bool countBytes; private readonly Encoding encoding; private readonly bool ignoreBlankLines; private readonly char comment; private readonly bool allowComments; private readonly BadDataFound? badDataFound; private readonly bool lineBreakInQuotedFieldIsBadData; private readonly TrimOptions trimOptions; private readonly char[] whiteSpaceChars; private readonly bool leaveOpen; private readonly CsvMode mode; private readonly string newLine; private readonly char newLineFirstChar; private readonly bool isNewLineSet; private readonly bool cacheFields; private readonly string[] delimiterValues; private readonly bool detectDelimiter; private readonly double maxFieldSize; private string delimiter; private char delimiterFirstChar; private char[] buffer; private int bufferSize; private int charsRead; private int bufferPosition; private int rowStartPosition; private int fieldStartPosition; private int row; private int rawRow; private long charCount; private long byteCount; private bool inQuotes; private bool inEscape; private Field[] fields; private string[] processedFields; private int fieldsPosition; private bool disposed; private int quoteCount; private char[] processFieldBuffer; private int processFieldBufferSize; private ParserState state; private int delimiterPosition = 1; private int newLinePosition = 1; private bool fieldIsBadData; private bool fieldIsQuoted; private bool isProcessingField; private bool isRecordProcessed; private string[] record = Array.Empty<string>(); public long CharCount => charCount; public long ByteCount => byteCount; public int Row => row; public string[]? Record { get { if (isRecordProcessed) { return record; } if (fieldsPosition == 0) { return null; } string[] array = new string[fieldsPosition]; for (int i = 0; i < array.Length; i++) { array[i] = this[i]; } record = array; isRecordProcessed = true; return record; } } public string RawRecord => new string(buffer, rowStartPosition, bufferPosition - rowStartPosition); public int Count => fieldsPosition; public int RawRow => rawRow; public string Delimiter => delimiter; public CsvContext Context { get; private set; } public IParserConfiguration Configuration => configuration; public string this[int index] { get { if (isProcessingField) { string message = "You can't access IParser[int] or IParser.Record inside of the BadDataFound callback. Use BadDataFoundArgs.Field and BadDataFoundArgs.RawRecord instead."; throw new ParserException(Context, message); } isProcessingField = true; string field = GetField(index); isProcessingField = false; return field; } } public CsvParser(TextReader reader, CultureInfo culture, bool leaveOpen = false) : this(reader, new CsvConfiguration(culture), leaveOpen) { } public CsvParser(TextReader reader, IParserConfiguration configuration, bool leaveOpen = false) { this.reader = reader ?? throw new ArgumentNullException("reader"); this.configuration = configuration ?? throw new ArgumentNullException("configuration"); configuration.Validate(); Context = new CsvContext(this); allowComments = configuration.AllowComments; badDataFound = configuration.BadDataFound; bufferSize = configuration.BufferSize; cacheFields = configuration.CacheFields; comment = configuration.Comment; countBytes = configuration.CountBytes; delimiter = configuration.Delimiter; delimiterFirstChar = configuration.Delimiter[0]; delimiterValues = configuration.DetectDelimiterValues; detectDelimiter = configuration.DetectDelimiter; encoding = configuration.Encoding; escape = configuration.Escape; ignoreBlankLines = configuration.IgnoreBlankLines; isNewLineSet = configuration.IsNewLineSet; this.leaveOpen = leaveOpen; lineBreakInQuotedFieldIsBadData = configuration.LineBreakInQuotedFieldIsBadData; maxFieldSize = configuration.MaxFieldSize; newLine = configuration.NewLine; newLineFirstChar = configuration.NewLine[0]; mode = configuration.Mode; processFieldBufferSize = configuration.ProcessFieldBufferSize; quote = configuration.Quote; whiteSpaceChars = configuration.WhiteSpaceChars; trimOptions = configuration.TrimOptions; buffer = new char[bufferSize]; processFieldBuffer = new char[processFieldBufferSize]; fields = new Field[128]; processedFields = new string[128]; } public bool Read() { isRecordProcessed = false; rowStartPosition = bufferPosition; fieldStartPosition = rowStartPosition; fieldsPosition = 0; quoteCount = 0; row++; rawRow++; char c = '\0'; char cPrev = c; do { if (bufferPosition >= charsRead) { if (!FillBuffer()) { return ReadEndOfFile(); } if (row == 1 && detectDelimiter) { DetectDelimiter(); } } } while (ReadLine(ref c, ref cPrev) != ReadLineResult.Complete); return true; } public async Task<bool> ReadAsync() { isRecordProcessed = false; rowStartPosition = bufferPosition; fieldStartPosition = rowStartPosition; fieldsPosition = 0; quoteCount = 0; row++; rawRow++; char c = '\0'; char cPrev = c; do { if (bufferPosition >= charsRead) { if (!(await FillBufferAsync().ConfigureAwait(continueOnCapturedContext: false))) { return ReadEndOfFile(); } if (row == 1 && detectDelimiter) { DetectDelimiter(); } } } while (ReadLine(ref c, ref cPrev) != ReadLineResult.Complete); return true; } private void DetectDelimiter() { string text = new string(buffer, 0, charsRead); string text2 = configuration.GetDelimiter(new GetDelimiterArgs(text, configuration)); if (text2 != null) { delimiter = text2; delimiterFirstChar = text2[0]; configuration.Validate(); } } private ReadLineResult ReadLine(ref char c, ref char cPrev) { while (bufferPosition < charsRead) { if (state != 0) { ReadLineResult readLineResult = state switch { ParserState.Spaces => ReadSpaces(ref c), ParserState.BlankLine => ReadBlankLine(ref c), ParserState.Delimiter => ReadDelimiter(ref c), ParserState.LineEnding => ReadLineEnding(ref c), ParserState.NewLine => ReadNewLine(ref c), _ => throw new InvalidOperationException($"Parser state '{state}' is not valid."), }; int num = readLineResult switch { ReadLineResult.Complete => (state == ParserState.LineEnding || state == ParserState.NewLine) ? 1 : 0, ReadLineResult.Incomplete => 1, _ => 0, }; if (readLineResult == ReadLineResult.Complete) { state = ParserState.None; } if (num != 0) { return readLineResult; } } cPrev = c; c = buffer[bufferPosition]; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } if (maxFieldSize > 0.0 && (double)(bufferPosition - fieldStartPosition - 1) > maxFieldSize) { throw new MaxFieldSizeException(Context); } if (rowStartPosition == bufferPosition - 1 && ((allowComments && c == comment) || (ignoreBlankLines && (((c == '\r' || c == '\n') && !isNewLineSet) || (c == newLineFirstChar && isNewLineSet))))) { state = ParserState.BlankLine; if (ReadBlankLine(ref c) == ReadLineResult.Complete) { state = ParserState.None; continue; } return ReadLineResult.Incomplete; } if (mode == CsvMode.RFC4180) { bool flag = fieldStartPosition == bufferPosition - 1; if (flag) { if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim && ArrayHelper.Contains(whiteSpaceChars, in c)) { ReadLineResult readLineResult2 = ReadSpaces(ref c); if (readLineResult2 == ReadLineResult.Incomplete) { fieldStartPosition = bufferPosition; return readLineResult2; } } fieldIsQuoted = c == quote; } if (fieldIsQuoted) { if (c == quote || c == escape) { quoteCount++; if (!inQuotes && !flag && cPrev != escape) { fieldIsBadData = true; } else if (!fieldIsBadData) { inQuotes = !inQuotes; } } if (inQuotes) { if (c != '\r' && (c != '\n' || cPrev == '\r')) { continue; } rawRow++; if (!lineBreakInQuotedFieldIsBadData) { continue; } fieldIsBadData = true; } } else if (c == quote || c == escape) { fieldIsBadData = true; } } else if (mode == CsvMode.Escape) { if (inEscape) { inEscape = false; continue; } if (c == escape) { inEscape = true; continue; } } if (c == delimiterFirstChar) { state = ParserState.Delimiter; ReadLineResult readLineResult3 = ReadDelimiter(ref c); if (readLineResult3 == ReadLineResult.Incomplete) { return readLineResult3; } state = ParserState.None; continue; } if (!isNewLineSet && (c == '\r' || c == '\n')) { state = ParserState.LineEnding; ReadLineResult num2 = ReadLineEnding(ref c); if (num2 == ReadLineResult.Complete) { state = ParserState.None; } return num2; } if (!isNewLineSet || c != newLineFirstChar) { continue; } state = ParserState.NewLine; ReadLineResult num3 = ReadNewLine(ref c); if (num3 == ReadLineResult.Complete) { state = ParserState.None; } return num3; } return ReadLineResult.Incomplete; } private ReadLineResult ReadSpaces(ref char c) { while (ArrayHelper.Contains(whiteSpaceChars, in c)) { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } c = buffer[bufferPosition]; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } } return ReadLineResult.Complete; } private ReadLineResult ReadBlankLine(ref char c) { while (bufferPosition < charsRead) { if (c == '\r' || c == '\n') { ReadLineResult num = ReadLineEnding(ref c); if (num == ReadLineResult.Complete) { rowStartPosition = bufferPosition; fieldStartPosition = rowStartPosition; row++; rawRow++; } return num; } c = buffer[bufferPosition]; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } } return ReadLineResult.Incomplete; } private ReadLineResult ReadDelimiter(ref char c) { for (int i = delimiterPosition; i < delimiter.Length; i++) { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } delimiterPosition++; c = buffer[bufferPosition]; if (c != delimiter[i]) { c = buffer[bufferPosition - 1]; delimiterPosition = 1; return ReadLineResult.Complete; } bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } } AddField(fieldStartPosition, bufferPosition - fieldStartPosition - delimiter.Length); fieldStartPosition = bufferPosition; delimiterPosition = 1; fieldIsBadData = false; return ReadLineResult.Complete; } private ReadLineResult ReadLineEnding(ref char c) { int num = 1; if (c == '\r') { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } c = buffer[bufferPosition]; if (c == '\n') { num++; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } } } if (state == ParserState.LineEnding) { AddField(fieldStartPosition, bufferPosition - fieldStartPosition - num); } fieldIsBadData = false; return ReadLineResult.Complete; } private ReadLineResult ReadNewLine(ref char c) { for (int i = newLinePosition; i < newLine.Length; i++) { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } newLinePosition++; c = buffer[bufferPosition]; if (c != newLine[i]) { c = buffer[bufferPosition - 1]; newLinePosition = 1; return ReadLineResult.Complete; } bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } } AddField(fieldStartPosition, bufferPosition - fieldStartPosition - newLine.Length); fieldStartPosition = bufferPosition; newLinePosition = 1; fieldIsBadData = false; return ReadLineResult.Complete; } private bool ReadEndOfFile() { ParserState parserState = state; state = ParserState.None; switch (parserState) { case ParserState.BlankLine: return false; case ParserState.Delimiter: AddField(fieldStartPosition, bufferPosition - fieldStartPosition - delimiter.Length); fieldStartPosition = bufferPosition; AddField(fieldStartPosition, bufferPosition - fieldStartPosition); return true; case ParserState.LineEnding: AddField(fieldStartPosition, bufferPosition - fieldStartPosition - 1); return true; case ParserState.NewLine: AddField(fieldStartPosition, bufferPosition - fieldStartPosition - newLine.Length); return true; default: if (rowStartPosition < bufferPosition) { AddField(fieldStartPosition, bufferPosition - fieldStartPosition); } return fieldsPosition > 0; } } private void AddField(int start, int length) { if (fieldsPosition >= fields.Length) { int newSize = fields.Length * 2; Array.Resize(ref fields, newSize); Array.Resize(ref processedFields, newSize); } ref Field reference = ref fields[fieldsPosition]; reference.Start = start - rowStartPosition; reference.Length = length; reference.QuoteCount = quoteCount; reference.IsBad = fieldIsBadData; reference.IsProcessed = false; fieldsPosition++; quoteCount = 0; } private bool FillBuffer() { if (rowStartPosition == 0 && charCount > 0 && charsRead == bufferSize) { bufferSize *= 2; char[] array = new char[bufferSize]; buffer.CopyTo(array, 0); buffer = array; } int num = Math.Max(charsRead - rowStartPosition, 0); Array.Copy(buffer, rowStartPosition, buffer, 0, num); fieldStartPosition -= rowStartPosition; rowStartPosition = 0; bufferPosition = num; charsRead = reader.Read(buffer, num, buffer.Length - num); if (charsRead == 0) { return false; } charsRead += num; return true; } private async Task<bool> FillBufferAsync() { if (rowStartPosition == 0 && charCount > 0 && charsRead == bufferSize) { bufferSize *= 2; char[] array = new char[bufferSize]; buffer.CopyTo(array, 0); buffer = array; } int charsLeft = Math.Max(charsRead - rowStartPosition, 0); Array.Copy(buffer, rowStartPosition, buffer, 0, charsLeft); fieldStartPosition -= rowStartPosition; rowStartPosition = 0; bufferPosition = charsLeft; charsRead = await reader.ReadAsync(buffer, charsLeft, buffer.Length - charsLeft).ConfigureAwait(continueOnCapturedContext: false); if (charsRead == 0) { return false; } charsRead += charsLeft; return true; } private string GetField(int index) { if (index > fieldsPosition) { throw new IndexOutOfRangeException(); } ref Field reference = ref fields[index]; if (reference.Length == 0) { return string.Empty; } if (reference.IsProcessed) { return processedFields[index]; } int start = reference.Start + rowStartPosition; int length = reference.Length; int num = reference.QuoteCount; ProcessedField processedField = mode switch { CsvMode.RFC4180 => reference.IsBad ? ProcessRFC4180BadField(start, length) : ProcessRFC4180Field(start, length, num), CsvMode.Escape => ProcessEscapeField(start, length), CsvMode.NoEscape => ProcessNoEscapeField(start, length), _ => throw new InvalidOperationException($"ParseMode '{mode}' is not handled."), }; string text = (cacheFields ? fieldCache.GetField(processedField.Buffer, processedField.Start, processedField.Length) : new string(processedField.Buffer, processedField.Start, processedField.Length)); processedFields[index] = text; reference.IsProcessed = true; return text; } protected ProcessedField ProcessRFC4180Field(int start, int length, int quoteCount) { int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (quoteCount == 0) { return new ProcessedField(start2, length2, buffer); } if (buffer[start2] != quote || buffer[start2 + length2 - 1] != quote || (length2 == 1 && buffer[start2] == quote)) { return ProcessRFC4180BadField(start, length); } start2++; length2 -= 2; if ((trimOptions & TrimOptions.InsideQuotes) == TrimOptions.InsideQuotes) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (quoteCount == 2) { return new ProcessedField(start2, length2, buffer); } if (length2 > processFieldBuffer.Length) { while (length2 > processFieldBufferSize) { processFieldBufferSize *= 2; } processFieldBuffer = new char[processFieldBufferSize]; } bool flag = false; int num = 0; for (int i = start2; i < start2 + length2; i++) { char c = buffer[i]; if (flag) { flag = false; } else if (c == escape) { flag = true; continue; } processFieldBuffer[num] = c; num++; } return new ProcessedField(0, num, processFieldBuffer); } protected ProcessedField ProcessRFC4180BadField(int start, int length) { BadDataFoundArgs args = new BadDataFoundArgs(new string(buffer, start, length), RawRecord, Context); badDataFound?.Invoke(args); int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (buffer[start2] != quote) { return new ProcessedField(start2, length2, buffer); } if (length2 > processFieldBuffer.Length) { while (length2 > processFieldBufferSize) { processFieldBufferSize *= 2; } processFieldBuffer = new char[processFieldBufferSize]; } bool flag = false; int num = 0; char c = '\0'; bool flag2 = false; for (int i = start2 + 1; i < start2 + length2; i++) { char c2 = c; c = buffer[i]; if (flag) { flag = false; if (c == quote) { continue; } if (c2 == quote) { flag2 = true; } } if (c == escape && !flag2) { flag = true; continue; } processFieldBuffer[num] = c; num++; } return new ProcessedField(0, num, processFieldBuffer); } protected ProcessedField ProcessEscapeField(int start, int length) { int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (length2 > processFieldBuffer.Length) { while (length2 > processFieldBufferSize) { processFieldBufferSize *= 2; } processFieldBuffer = new char[processFieldBufferSize]; } bool flag = false; int num = 0; for (int i = start2; i < start2 + length2; i++) { char c = buffer[i]; if (flag) { flag = false; } else if (c == escape) { flag = true; continue; } processFieldBuffer[num] = c; num++; } return new ProcessedField(0, num, processFieldBuffer); } protected ProcessedField ProcessNoEscapeField(int start, int length) { int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } return new ProcessedField(start2, length2, buffer); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing && !leaveOpen) { reader?.Dispose(); } disposed = true; } } } public class CsvReader : IReader, IReaderRow, IDisposable { [CompilerGenerated] private sealed class <EnumerateRecords>d__90<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IDisposable, IEnumerator where T : notnull { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; public CsvReader <>4__this; private T record; public T <>3__record; T IEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateRecords>d__90(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. e.g. .ToList() Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { if (!csvReader.Read()) { return false; } csvReader.ReadHeader(); csvReader.ValidateHeader<T>(); } break; case 1: <>1__state = -1; break; } while (csvReader.Read()) { try { csvReader.recordManager.Value.Hydrate(record); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } <>2__current = record; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<T> IEnumerable<T>.GetEnumerator() { <EnumerateRecords>d__90<T> <EnumerateRecords>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateRecords>d__ = this; } else { <EnumerateRecords>d__ = new <EnumerateRecords>d__90<T>(0) { <>4__this = <>4__this }; } <EnumerateRecords>d__.record = <>3__record; return <EnumerateRecords>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<T>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetRecords>d__87<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IDisposable, IEnumerator where T : notnull { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; public CsvReader <>4__this; private Func<T> <read>5__2; T IEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecords>d__87(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <read>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. e.g. .ToList() Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { if (!csvReader.Read()) { return false; } csvReader.ReadHeader(); csvReader.ValidateHeader<T>(); } <read>5__2 = null; break; case 1: <>1__state = -1; break; } while (csvReader.Read()) { T val; try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<T>(typeof(T)); } val = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } <>2__current = val; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<T> IEnumerable<T>.GetEnumerator() { <GetRecords>d__87<T> result; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; result = this; } else { result = new <GetRecords>d__87<T>(0) { <>4__this = <>4__this }; } return result; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<T>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetRecords>d__89 : IEnumerable<object>, IEnumerable, IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int <>l__initialThreadId; public CsvReader <>4__this; private Type type; public Type <>3__type; private Func<object> <read>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecords>d__89(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <read>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<object>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. e.g. .ToList() Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { if (!csvReader.Read()) { return false; } csvReader.ReadHeader(); csvReader.ValidateHeader(type); } <read>5__2 = null; break; case 1: <>1__state = -1; break; } while (csvReader.Read()) { object obj; try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<object>(type); } obj = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } <>2__current = obj; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<object> IEnumerable<object>.GetEnumerator() { <GetRecords>d__89 <GetRecords>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetRecords>d__ = this; } else { <GetRecords>d__ = new <GetRecords>d__89(0) { <>4__this = <>4__this }; } <GetRecords>d__.type = <>3__type; return <GetRecords>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<object>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetRecordsAsync>d__91<T> : IAsyncEnumerable<T>, IAsyncEnumerator<T>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine where T : notnull { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private T <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; public CsvReader <>4__this; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; private Func<T> <read>5__2; private ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter <>u__1; T IAsyncEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecordsAsync>d__91(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; try { ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter awaiter; T val; switch (num) { default: if (<>w__disposeMode) { break; } num = (<>1__state = -1); if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { <>2__current = default(T); awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_00e0; } goto IL_0102; case 0: awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_00e0; case -4: num = (<>1__state = -1); if (<>w__disposeMode) { break; } goto IL_01cd; case 1: { awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_023a; } IL_023a: if (!awaiter.GetResult()) { break; } cancellationToken.ThrowIfCancellationRequested(); try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<T>(typeof(T)); } val = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } goto IL_01cd; } <>2__current = val; num = (<>1__state = -4); goto IL_02e6; IL_0102: <read>5__2 = null; goto IL_01cd; IL_00e0: if (!awaiter.GetResult()) { <>w__disposeMode = true; break; } csvReader.ReadHeader(); csvReader.ValidateHeader<T>(); goto IL_0102; IL_01cd: <>2__current = default(T); awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__1 = awaiter; <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_023a; } } catch (Exception exception) { <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = default(T); <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = default(T); <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_02e6: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<T> IAsyncEnumerable<T>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetRecordsAsync>d__91<T> <GetRecordsAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetRecordsAsync>d__ = this; } else { <GetRecordsAsync>d__ = new <GetRecordsAsync>d__91<T>(-3) { <>4__this = <>4__this }; } if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetRecordsAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetRecordsAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<T>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } [CompilerGenerated] private sealed class <GetRecordsAsync>d__93 : IAsyncEnumerable<object>, IAsyncEnumerator<object>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private object <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; public CsvReader <>4__this; private Type type; public Type <>3__type; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; private Func<object> <read>5__2; private ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter <>u__1; object IAsyncEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecordsAsync>d__93(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; try { ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter awaiter; object obj; switch (num) { default: if (<>w__disposeMode) { break; } num = (<>1__state = -1); if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<object>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { <>2__current = null; awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_00db; } goto IL_0103; case 0: awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_00db; case -4: num = (<>1__state = -1); if (<>w__disposeMode) { break; } goto IL_01ca; case 1: { awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_0232; } IL_0232: if (!awaiter.GetResult()) { break; } cancellationToken.ThrowIfCancellationRequested(); try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<object>(type); } obj = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } goto IL_01ca; } <>2__current = obj; num = (<>1__state = -4); goto IL_02d4; IL_0103: <read>5__2 = null; goto IL_01ca; IL_00db: if (!awaiter.GetResult()) { <>w__disposeMode = true; break; } csvReader.ReadHeader(); csvReader.ValidateHeader(type); goto IL_0103; IL_01ca: <>2__current = null; awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__1 = awaiter; <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_0232; } } catch (Exception exception) { <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_02d4: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<object> IAsyncEnumerable<object>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetRecordsAsync>d__93 <GetRecordsAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetRecordsAsync>d__ = this; } else { <GetRecordsAsync>d__ = new <GetRecordsAsync>d__93(-3) { <>4__this = <>4__this }; } <GetRecordsAsync>d__.type = <>3__type; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetRecordsAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetRecordsAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<object>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } private readonly Lazy<RecordManager> recordManager; private readonly bool detectColumnCountChanges; private readonly Dictionary<string, List<int>> namedIndexes = new Dictionary<string, List<int>>(); private readonly Dictionary<string, (string, int)> namedIndexCache = new Dictionary<string, (string, int)>(); private readonly Dictionary<Type, TypeConverterOptions> typeConverterOptionsCache = new Dictionary<Type, TypeConverterOptions>(); private readonly MemberMapData reusableMemberMapData = new MemberMapData(null); private readonly bool hasHeaderRecord; private readonly HeaderValidated? headerValidated; private readonly ShouldSkipRecord? shouldSkipRecord; private readonly ReadingExceptionOccurred? readingExceptionOccurred; private readonly CultureInfo cultureInfo; private readonly bool ignoreBlankLines; private readonly MissingFieldFound? missingFieldFound; private readonly bool includePrivateMembers; private readonly PrepareHeaderForMatch prepareHeaderForMatch; private CsvContext context; private bool disposed; private IParser parser; private int prevColumnCount; private int currentIndex = -1; private bool hasBeenRead; private string[]? headerRecord; public virtual int ColumnCount => parser.Count; public virtual int CurrentIndex => currentIndex; public virtual string[]? HeaderRecord => headerRecord; public virtual CsvContext Context => context; public virtual IReaderConfiguration Configuration { get; private set; } public virtual IParser Parser => parser; public virtual string? this[int index] { get { CheckHasBeenRead(); return GetField(index); } } public virtual string? this[string name] { get { CheckHasBeenRead(); return GetField(name); } } public virtual string? this[string name, int index] { get { CheckHasBeenRead(); return GetField(name, index); } } public CsvReader(TextReader reader, CultureInfo culture, bool leaveOpen = false) : this(new CsvParser(reader, culture, leaveOpen)) { } public CsvReader(TextReader reader, IReaderConfiguration configuration, bool leaveOpen = false) : this(new CsvParser(reader, configuration, leaveOpen)) { } public CsvReader(IParser parser) { Configuration = (parser.Configuration as IReaderConfiguration) ?? throw new ConfigurationException("The IParser configuration must implement IReaderConfiguration to be used in CsvReader."); this.parser = parser ?? throw new ArgumentNullException("parser"); context = parser.Context ?? throw new InvalidOperationException("For IParser to be used in CsvReader, Context must also implement CsvContext."); context.Reader = this; recordManager = new Lazy<RecordManager>(() => ObjectResolver.Current.Resolve<RecordManager>(new object[1] { this })); cultureInfo = Configuration.CultureInfo; detectColumnCountChanges = Configuration.DetectColumnCountChanges; hasHeaderRecord = Configuration.HasHeaderRecord; headerValidated = Configuration.HeaderValidated; ignoreBlankLines = Configuration.IgnoreBlankLines; includePrivateMembers = Configuration.IncludePrivateMembers; missingFieldFound = Configuration.MissingFieldFound; prepareHeaderForMatch = Configuration.PrepareHeaderForMatch; readingExceptionOccurred = Configuration.ReadingExceptionOccurred; shouldSkipRecord = Configuration.ShouldSkipRecord; } public virtual bool ReadHeader() { if (!hasHeaderRecord) { throw new ReaderException(context, "Configuration.HasHeaderRecord is false."); } headerRecord = parser.Record; ParseNamedIndexes(); return headerRecord != null; } public virtual void ValidateHeader<T>() { ValidateHeader(typeof(T)); } public virtual void ValidateHeader(Type type) { if (!hasHeaderRecord) { throw new InvalidOperationException("Validation can't be performed on a the header if no header exists. HasHeaderRecord can't be false."); } CheckHasBeenRead(); if (headerRecord == null) { throw new InvalidOperationException("The header must be read before it can be validated."); } if (context.Maps[type] == null) { context.Maps.Add(context.AutoMap(type)); } ClassMap map = context.Maps[type]; List<InvalidHeader> list = new List<InvalidHeader>(); ValidateHeader(map, list); HeaderValidatedArgs args = new HeaderValidatedArgs(list.ToArray(), context); headerValidated?.Invoke(args); } protected virtual void ValidateHeader(ClassMap map, List<InvalidHeader> invalidHeaders) { foreach (ParameterMap parameterMap in map.ParameterMaps) { if (!parameterMap.Data.Ignore && !parameterMap.Data.IsConstantSet && (!parameterMap.Data.IsIndexSet || parameterMap.Data.IsNameSet)) { if (parameterMap.ConstructorTypeMap != null) { ValidateHeader(parameterMap.ConstructorTypeMap, invalidHeaders); } else if (parameterMap.ReferenceMap != null) { ValidateHeader(parameterMap.ReferenceMap.Data.Mapping, invalidHeaders); } else if (GetFieldIndex(parameterMap.Data.Names, parameterMap.Data.NameIndex, isTryGet: true) == -1 && !parameterMap.Data.IsOptional) { invalidHeaders.Add(new InvalidHeader { Index = parameterMap.Data.NameIndex, Names = parameterMap.Data.Names.ToList() }); } } } foreach (MemberMap memberMap in map.MemberMaps) { if (!memberMap.Data.Ignore && CanRead(memberMap) && memberMap.Data.ReadingConvertExpression == null && !memberMap.Data.IsConstantSet && (!memberMap.Data.IsIndexSet || memberMap.Data.IsNameSet) && GetFieldIndex(memberMap.Data.Names, memberMap.Data.NameIndex, isTryGet: true) == -1 && !memberMap.Data.IsOptional) { invalidHeaders.Add(new InvalidHeader { Index = memberMap.Data.NameIndex, Names = memberMap.Data.Names.ToList() }); } } foreach (MemberReferenceMap referenceMap in map.ReferenceMaps) { if (CanRead(referenceMap)) { ValidateHeader(referenceMap.Data.Mapping, invalidHeaders); } } } public virtual bool Read() { bool flag; ShouldSkipRecord? obj; do { flag = parser.Read(); hasBeenRead = true; if (!flag) { break; } obj = shouldSkipRecord; } while (obj != null && obj(new ShouldSkipRecordArgs(this))); currentIndex = -1; if (detectColumnCountChanges && flag) { if (prevColumnCount > 0 && prevColumnCount != parser.Count) { BadDataException ex = new BadDataException(string.Empty, parser.RawRecord, context, "An inconsistent number of columns has been detected."); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex); ReadingExceptionOccurred? obj2 = readingExceptionOccurred; if (obj2 == null || obj2(args)) { throw ex; } } prevColumnCount = parser.Count; } return flag; } public virtual async Task<bool> ReadAsync() { bool flag; do { flag = await parser.ReadAsync().ConfigureAwait(continueOnCapturedContext: false); hasBeenRead = true; } while (flag && (shouldSkipRecord?.Invoke(new ShouldSkipRecordArgs(this)) ?? false)); currentIndex = -1; if (detectColumnCountChanges && flag) { if (prevColumnCount > 0 && prevColumnCount != parser.Count) { BadDataException ex = new BadDataException(string.Empty, parser.RawRecord, context, "An inconsistent number of columns has been detected."); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex); if (readingExceptionOccurred?.Invoke(args) ?? true) { throw ex; } } prevColumnCount = parser.Count; } return flag; } public virtual string? GetField(int index) { CheckHasBeenRead(); currentIndex = index; if (index >= parser.Count || index < 0) { MissingFieldFoundArgs args = new MissingFieldFoundArgs(null, index, context); missingFieldFound?.Invoke(args); return null; } return parser[index]; } public virtual string? GetField(string name) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name); if (fieldIndex < 0) { return null; } return GetField(fieldIndex); } public virtual string? GetField(string name, int index) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index); if (fieldIndex < 0) { return null; } return GetField(fieldIndex); } public virtual object? GetField(Type type, int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return GetField(type, index, converter); } public virtual object? GetField(Type type, string name) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return GetField(type, name, converter); } public virtual object? GetField(Type type, string name, int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return GetField(type, name, index, converter); } public virtual object? GetField(Type type, int index, ITypeConverter converter) { CheckHasBeenRead(); reusableMemberMapData.Index = index; reusableMemberMapData.TypeConverter = converter; if (!typeConverterOptionsCache.TryGetValue(type, out TypeConverterOptions value)) { value = TypeConverterOptions.Merge(new TypeConverterOptions { CultureInfo = cultureInfo }, context.TypeConverterOptionsCache.GetOptions(type)); typeConverterOptionsCache.Add(type, value); } reusableMemberMapData.TypeConverterOptions = value; string field = GetField(index); return converter.ConvertFromString(field, this, reusableMemberMapData); } public virtual object? GetField(Type type, string name, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name); return GetField(type, fieldIndex, converter); } public virtual object? GetField(Type type, string name, int index, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index); return GetField(type, fieldIndex, converter); } public virtual T? GetField<T>(int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return GetField<T>(index, converter); } public virtual T? GetField<T>(string name) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return GetField<T>(name, converter); } public virtual T? GetField<T>(string name, int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return GetField<T>(name, index, converter); } public virtual T? GetField<T>(int index, ITypeConverter converter) { CheckHasBeenRead(); if (index >= parser.Count || index < 0) { currentIndex = index; MissingFieldFoundArgs args = new MissingFieldFoundArgs(null, index, context); missingFieldFound?.Invoke(args); return default(T); } return (T)GetField(typeof(T), index, converter); } public virtual T? GetField<T>(string name, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name); return GetField<T>(fieldIndex, converter); } public virtual T? GetField<T>(string name, int index, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index); return GetField<T>(fieldIndex, converter); } public virtual T? GetField<T, TConverter>(int index) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return GetField<T>(index, val); } public virtual T? GetField<T, TConverter>(string name) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return GetField<T>(name, val); } public virtual T? GetField<T, TConverter>(string name, int index) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return GetField<T>(name, index, val); } public virtual bool TryGetField(Type type, int index, out object? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return TryGetField(type, index, converter, out field); } public virtual bool TryGetField(Type type, string name, out object? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return TryGetField(type, name, converter, out field); } public virtual bool TryGetField(Type type, string name, int index, out object? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return TryGetField(type, name, index, converter, out field); } public virtual bool TryGetField(Type type, int index, ITypeConverter converter, out object? field) { CheckHasBeenRead(); try { field = GetField(type, index, converter); return true; } catch { field = (type.GetTypeInfo().IsValueType ? ObjectResolver.Current.Resolve(type) : null); return false; } } public virtual bool TryGetField(Type type, string name, ITypeConverter converter, out object? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, 0, isTryGet: true); if (fieldIndex == -1) { field = (type.GetTypeInfo().IsValueType ? ObjectResolver.Current.Resolve(type) : null); return false; } return TryGetField(type, fieldIndex, converter, out field); } public virtual bool TryGetField(Type type, string name, int index, ITypeConverter converter, out object? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index, isTryGet: true); if (fieldIndex == -1) { field = (type.GetTypeInfo().IsValueType ? ObjectResolver.Current.Resolve(type) : null); return false; } return TryGetField(type, fieldIndex, converter, out field); } public virtual bool TryGetField<T>(int index, out T? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return TryGetField<T>(index, converter, out field); } public virtual bool TryGetField<T>(string name, out T? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return TryGetField<T>(name, converter, out field); } public virtual bool TryGetField<T>(string name, int index, out T? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return TryGetField<T>(name, index, converter, out field); } public virtual bool TryGetField<T>(int index, ITypeConverter converter, out T? field) { CheckHasBeenRead(); try { field = GetField<T>(index, converter); return true; } catch { field = default(T); return false; } } public virtual bool TryGetField<T>(string name, ITypeConverter converter, out T? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, 0, isTryGet: true); if (fieldIndex == -1) { field = default(T); return false; } return TryGetField<T>(fieldIndex, converter, out field); } public virtual bool TryGetField<T>(string name, int index, ITypeConverter converter, out T? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index, isTryGet: true); if (fieldIndex == -1) { field = default(T); return false; } return TryGetField<T>(fieldIndex, converter, out field); } public virtual bool TryGetField<T, TConverter>(int index, out T? field) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return TryGetField<T>(index, val, out field); } public virtual bool TryGetField<T, TConverter>(string name, out T? field) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return TryGetField<T>(name, val, out field); } public virtual bool TryGetField<T, TConverter>(string name, int index, out T? field) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return TryGetField<T>(name, index, val, out field); } public virtual T GetRecord<T>() { CheckHasBeenRead(); if (headerRecord == null && hasHeaderRecord) { ReadHeader(); ValidateHeader<T>(); if (!Read()) { throw new ReaderException(context, "There are no records."); } } try { return recordManager.Value.GetReadDelegate<T>(typeof(T))(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? obj = readingExceptionOccurred; if (obj == null || obj(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } return (T)args.Record; } } public virtual T GetRecord<T>(T anonymousTypeDefinition) { if (anonymousTypeDefinition == null) { throw new ArgumentNullException("anonymousTypeDefinition"); } if (!anonymousTypeDefinition.GetType().IsAnonymous()) { throw new ArgumentException("Argument is not an anonymous type.", "anonymousTypeDefinition"); } return GetRecord<T>(); } public virtual object GetRecord(Type type) { CheckHasBeenRead(); if (headerRecord == null && hasHeaderRecord) { ReadHeader(); ValidateHeader(type); if (!Read()) { throw new ReaderException(context, "There are no records."); } } try { return recordManager.Value.GetReadDelegate<object>(type)(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? obj = readingExceptionOccurred; if (obj == null || obj(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } return args.Record; } } [IteratorStateMachine(typeof(<GetRecords>d__87<>))] public virtual IEnumerable<T> GetRecords<T>() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRecords>d__87<T>(-2) { <>4__this = this }; } public virtual IEnumerable<T> GetRecords<T>(T anonymousTypeDefinition) { if (anonymousTypeDefinition == null) { throw new ArgumentNullException("anonymousTypeDefinition"); } if (!anonymousTypeDefinition.GetType().IsAnonymous()) { throw new ArgumentException("Argument is not an anonymous type.", "anonymousTypeDefinition"); } return GetRecords<T>(); } [IteratorStateMachine(typeof(<GetRecords>d__89))] public virtual IEnumerable<object> GetRecords(Type type) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRecords>d__89(-2) { <>4__this = this, <>3__type = type }; } [IteratorStateMachine(typeof(<EnumerateRecords>d__90<>))] public virtual IEnumerable<T> EnumerateRecords<T>(T record) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateRecords>d__90<T>(-2) { <>4__this = this, <>3__record = record }; } [AsyncIteratorStateMachine(typeof(<GetRecordsAsync>d__91<>))] public virtual IAsyncEnumerable<T> GetRecordsAsync<T>([EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetRecordsAsync>d__91<T>(-2) { <>4__this = this, <>3__cancellationToken = cancellationToken }; } public virtual IAsyncEnumerable<T> GetRecordsAsync<T>(T anonymousTypeDefinition, CancellationToken cancellationToken = default(CancellationToken)) { if (anonymousTypeDefinition == null) { throw new ArgumentNullException("anonymousTypeDefinition"); } if (!anonymousTypeDefinition.GetType().IsAnonymous()) { throw new ArgumentException("Argument is not an anonymous type.", "anonymousTypeDefinition"); } return GetRecordsAsync<T>(cancellationToken); } [AsyncIteratorStateMachine(typeof(<GetRecordsAsync>d__93))] public virtual IAsyncEnumerable<object> GetRecordsAsync(Type type, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetRecordsAsync>d__93(-2) { <>4__this = this, <>3__type = type, <>3__cancellationToken = cancellationToken }; } public virtual async IAsyncEnumerable<T> EnumerateRecordsAsync<T>(T record, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { if (disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (hasHeaderRecord && headerRecord == null) { if (!(await ReadAsync().ConfigureAwait(continueOnCapturedContext: false))) { yield break; } ReadHeader(); ValidateHeader<T>(); } while (await ReadAsync().ConfigureAwait(continueOnCapturedContext: false)) { cancellationToken.ThrowIfCancellationRequested(); try { recordManager.Value.Hydrate(record); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); if (readingExceptionOccurred?.Invoke(args) ?? true) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } yield return record; } } public virtual int GetFieldIndex(string name, int index = 0, bool isTryGet = false) { return GetFieldIndex(new string[1] { name }, index, isTryGet); } public virtual int GetFieldIndex(IEnumerable<string> names, int index = 0, bool isTryGet = false, bool isOptional = false) { if (names == null) { throw new ArgumentNullException("names"); } if (!hasHeaderRecord) { throw new ReaderException(context, "There is no header record to determine the index by name."); } if (headerRecord == null) { throw new ReaderException(context, "The header has not been read. You must call ReadHeader() before any fields can be retrieved by name."); } string key = string.Join("_", names) + index; if (namedIndexCache.TryGetValue(key, out (string, int) value)) { var (key2, index2) = value; return namedIndexes[key2][index2]; } string text = null; int num = 0; foreach (string name in names) { PrepareHeaderForMatchArgs args = new PrepareHeaderForMatchArgs(name, num); string text2 = prepareHeaderForMatch(args); if (namedIndexes.ContainsKey(text2 ?? string.Empty)) { text = text2; break; } num++; } if (text == null || index >= namedIndexes[text].Count) { if (!isTryGet && !isOptional) { MissingFieldFoundArgs args2 = new MissingFieldFoundArgs(names.ToArray(), index, context); missingFieldFound?.Invoke(args2); } return -1; } namedIndexCache.Add(key, (text, index)); return namedIndexes[text][index]; } public virtual bool CanRead(MemberMap memberMap) { bool flag = memberMap.Data.Ignore; PropertyInfo propertyInfo = memberMap.Data.Member as PropertyInfo; if (propertyInfo != null) { flag = flag || (propertyInfo.GetSetMethod() == null && !includePrivateMembers) || propertyInfo.GetSetMethod(nonPublic: true) == null; } return !flag; } public virtual bool CanRead(MemberReferenceMap memberReferenceMap) { bool flag = false; PropertyInfo propertyInfo = memberReferenceMap.Data.Member as PropertyInfo; if (propertyInfo != null) { flag = (propertyInfo.GetSetMethod() == null && !includePrivateMembers) || propertyInfo.GetSetMethod(nonPublic: true) == null; } return !flag; } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { parser.Dispose(); } disposed = true; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected virtual void CheckHasBeenRead() { if (!hasBeenRead) { throw new ReaderException(context, "You must call read on the reader before accessing its data."); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected virtual void ParseNamedIndexes() { if (headerRecord == null) { throw new ReaderException(context, "No header record was found."); } namedIndexes.Clear(); namedIndexCache.Clear(); for (int i = 0; i < headerRecord.Length; i++) { PrepareHeaderForMatchArgs args = new PrepareHeaderForMatchArgs(headerRecord[i], i); string key = prepareHeaderForMatch(args); if (namedIndexes.TryGetValue(key, out List<int> value)) { value.Add(i); continue; } namedIndexes[key] = new List<int> { i }; } } } public class CsvWriter : IWriter, IWriterRow, IDisposable, IAsyncDisposable { private readonly TextWriter writer; private readonly CsvContext context; private readonly Lazy<RecordManager> recordManager; private readonly TypeConverterCache typeConverterCache; private readonly TrimOptions trimOptions; private readonly ShouldQuote shouldQuote; private readonly MemberMapData reusableMemberMapData = new MemberMapData(null); private readonly Dictionary<Type, TypeConverterOptions> typeConverterOptionsCache = new Dictionary<Type, TypeConverterOptions>(); private readonly string quoteString; private readonly char quote; private readonly CultureInfo cultureInfo; private readonly char comment; private readonly bool hasHeaderRecord; private readonly bool includePrivateMembers; private readonly IComparer<string>? dynamicPropertySort; private readonly string delimiter; private readonly bool leaveOpen; private readonly string newLine; private readonly char[] injectionCharacters; private readonly char injectionEscapeCharacter; private readonly InjectionOptions injectionOptions; private readonly CsvMode mode; private readonly string escapeString; private readonly string escapeQuoteString; private readonly string escapeDelimiterString; private readonly string escapeNewlineString; private readonly string escapeEscapeString; private bool disposed; private bool hasHeaderBeenWritten; private int row = 1; private int index; private char[] buffer; private int bufferSize; private int bufferPosition; private Type? fieldType; public virtual string?[]? HeaderRecord { get; private set; } public virtual int Row => row; public virtual int Index => index; public virtual CsvContext Context => context; public virtual IWriterConfiguration Configuration { get; private set; } public CsvWriter(TextWriter writer, CultureInfo culture, bool leaveOpen = false) : this(writer, new CsvConfiguration(culture), leaveOpen) { } public CsvWriter(TextWriter writer, IWriterConfiguration configuration, bool leaveOpen = false) { IWriterConfiguration configuration2 = configuration; base..ctor(); CsvWriter csvWriter = this; configuration2.Validate(); this.writer = writer; Configuration = configuration2; context = new CsvContext(this); typeConverterCache = context.TypeConverterCache; recordManager = new Lazy<RecordManager>(() => ObjectResolver.Current.Resolve<RecordManager>(new object[1] { csvWriter })); comment = configuration2.Comment; bufferSize = configuration2.BufferSize; delimiter = configuration2.Delimiter; cultureInfo = configuration2.CultureInfo; dynamicPropertySort = configuration2.DynamicPropertySort; escapeDelimiterString = new string(configuration2.Delimiter.SelectMany((char c) => new char[2] { configuration2.Escape, c }).ToArray()); escapeNewlineString = new string(configuration2.NewLine.SelectMany((char c) => new char[2] { configuration2.Escape, c }).ToArray()); escapeQuoteString = new string(new char[2] { configuration2.Escape, configuration2.Quote }); escapeEscapeString = new string(new char[2] { configuration2.Escape, configuration2.Escape }); hasHeaderRecord = configuration2.HasHeaderRecord; includePrivateMembers = configuration2.IncludePrivateMembers; injectionCharacters = configuration2.InjectionCharacters; injectionEscapeCharacter = configuration2.InjectionEscapeCharacter; this.leaveOpen = leaveOpen; mode = configuration2.Mode; newLine = configuration2.NewLine; quote = configuration2.Quote; quoteString = configuration2.Quote.ToString(); escapeString = configuration2.Escape.ToString(); injectionOptions = configuration2.InjectionOptions; shouldQuote = configuration2.ShouldQuote; trimOptions = configuration2.TrimOptions; buffer = new char[bufferSize]; } public virtual void WriteConvertedField(string? field, Type fieldType) { this.fieldType = fieldType; if (field != null) { WriteField(field); } } public virtual void WriteField(string? field) { if (field != null && (trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { field = field.Trim(); } if ((object)fieldType == null) { fieldType = typeof(string); } ShouldQuoteArgs args = new ShouldQuoteArgs(field, fieldType, this); bool flag = shouldQuote(args); WriteField(field, flag); } public virtual void WriteField(string? field, bool shouldQuote) { if (mode == CsvMode.RFC4180) { if (shouldQuote) { if (escapeString != quoteString) { field = field?.Replace(escapeString, escapeEscapeString); } field = field?.Replace(quoteString, escapeQuoteString); char c = quote; string text = c.ToString(); string? text2 = field; c = quote; field = text + text2 + c; } } else if (mode == CsvMode.Escape) { field = field?.Replace(escapeString, escapeEscapeString).Replace(quoteString, escapeQuoteString).Replace(delimiter, escapeDelimiterString) .Replace(newLine, escapeNewlineString); } if (injectionOptions != 0) { field = SanitizeForInjection(field); } if (index > 0) { WriteToBuffer(delimiter); } WriteToBuffer(field); index++; fieldType = null; } public virtual void WriteField<T>(T? field) { Type type = ((field == null) ? typeof(string) : field.GetType()); ITypeConverter converter = typeConverterCache.GetConverter(type); WriteField(field, converter); } public virtual void WriteField<T>(T? field, ITypeConverter converter) { Type type = ((field == null) ? typeof(string) : field.GetType()); reusableMemberMapData.TypeConverter = converter; if (!typeConverterOptionsCache.TryGetValue(type, out TypeConverterOptions value)) { value = TypeConverterOptions.Merge(new TypeConverterOptions { CultureInfo = cultureInfo }, context.TypeConverterOptionsCache.GetOptions(type)); typeConverterOptionsCache.Add(type, value); } reusableMemberMapData.TypeConverterOptions = value; string field2 = converter.ConvertToString(field, this, reusableMemberMapData); Wr
BepInEx/plugins/CsvHelper.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Diagnostics; using System.Dynamic; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Sources; using CsvHelper.Configuration; using CsvHelper.Configuration.Attributes; using CsvHelper.Delegates; using CsvHelper.Expressions; using CsvHelper.TypeConversion; using Microsoft.CSharp.RuntimeBinder; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: CLSCompliant(true)] [assembly: InternalsVisibleTo("CsvHelper.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001000db97564beef98ad18a76ba31f769fab92b14341c9c37ed12f8004bb2a1a7fe42ad829b0e285915a816f05a32325c5e0ba83bd69d8f4d26a0785ccf446749842ad038f7325601a99c59a323dfa7ecf210139159da0aad1822b5d9c9be6d914ecbaa8b8c908c4af798a89b8777010971d81975079a49662ced398c742ff186a94")] [assembly: TargetFramework(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")] [assembly: AssemblyCompany("Josh Close")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright © 2009-2024 Josh Close")] [assembly: AssemblyDescription("A library for reading and writing CSV files. Extremely fast, flexible, and easy to use. Supports reading and writing of custom class objects.")] [assembly: AssemblyFileVersion("33.1.0.26")] [assembly: AssemblyInformationalVersion("33.1.0+5dad8b8b1d8b074f8353cfd482e939db788a8927")] [assembly: AssemblyProduct("CsvHelper")] [assembly: AssemblyTitle("CsvHelper")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JoshClose/CsvHelper")] [assembly: AssemblyVersion("33.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CsvHelper { public static class ArrayHelper { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Trim(char[] buffer, ref int start, ref int length, char[] trimChars) { for (int i = start; i < start + length; i++) { char c = buffer[i]; if (!Contains(trimChars, in c)) { break; } start++; length--; } int num = start + length - 1; while (num > start) { char c2 = buffer[num]; if (Contains(trimChars, in c2)) { length--; num--; continue; } break; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool Contains(char[] array, in char c) { for (int i = 0; i < array.Length; i++) { if (array[i] == c) { return true; } } return false; } } [Serializable] public class BadDataException : CsvHelperException { public readonly string Field; public readonly string RawRecord; public BadDataException(string field, string rawRecord, CsvContext context) : base(context) { Field = field; RawRecord = rawRecord; } public BadDataException(string field, string rawRecord, CsvContext context, string message) : base(context, message) { Field = field; RawRecord = rawRecord; } public BadDataException(string field, string rawRecord, CsvContext context, string message, Exception innerException) : base(context, message, innerException) { Field = field; RawRecord = rawRecord; } } internal static class AsyncExtensions { public static ValueTask DisposeAsync(this TextWriter textWriter) { textWriter?.Dispose(); return default(ValueTask); } } public class CsvContext { public virtual TypeConverterOptionsCache TypeConverterOptionsCache { get; set; } = new TypeConverterOptionsCache(); public virtual TypeConverterCache TypeConverterCache { get; set; } = new TypeConverterCache(); public virtual ClassMapCollection Maps { get; private set; } public IParser? Parser { get; private set; } public IReader? Reader { get; internal set; } public IWriter? Writer { get; internal set; } public CsvConfiguration Configuration { get; private set; } public CsvContext(IReader reader) { Reader = reader; Parser = reader.Parser; Configuration = (reader.Configuration as CsvConfiguration) ?? throw new InvalidOperationException("IReader.Configuration must be of type CsvConfiguration to be used in the context."); Maps = new ClassMapCollection(this); } public CsvContext(IParser parser) { Parser = parser; Configuration = (parser.Configuration as CsvConfiguration) ?? throw new InvalidOperationException("IParser.Configuration must be of type CsvConfiguration to be used in the context."); Maps = new ClassMapCollection(this); } public CsvContext(IWriter writer) { Writer = writer; Configuration = (writer.Configuration as CsvConfiguration) ?? throw new InvalidOperationException("IWriter.Configuration must be of type CsvConfiguration to be used in the context."); Maps = new ClassMapCollection(this); } public CsvContext(CsvConfiguration configuration) { Configuration = configuration; Maps = new ClassMapCollection(this); } public virtual TMap RegisterClassMap<TMap>() where TMap : ClassMap { TMap val = ObjectResolver.Current.Resolve<TMap>(Array.Empty<object>()); RegisterClassMap(val); return val; } public virtual ClassMap RegisterClassMap(Type classMapType) { if (!typeof(ClassMap).IsAssignableFrom(classMapType)) { throw new ArgumentException("The class map type must inherit from CsvClassMap."); } ClassMap classMap = (ClassMap)ObjectResolver.Current.Resolve(classMapType); RegisterClassMap(classMap); return classMap; } public virtual void RegisterClassMap(ClassMap map) { if (map.MemberMaps.Count == 0 && map.ReferenceMaps.Count == 0 && map.ParameterMaps.Count == 0) { throw new ConfigurationException("No mappings were specified in the CsvClassMap."); } Maps.Add(map); } public virtual void UnregisterClassMap<TMap>() where TMap : ClassMap { UnregisterClassMap(typeof(TMap)); } public virtual void UnregisterClassMap(Type classMapType) { Maps.Remove(classMapType); } public virtual void UnregisterClassMap() { Maps.Clear(); } public virtual ClassMap<T> AutoMap<T>() { DefaultClassMap<T> defaultClassMap = ObjectResolver.Current.Resolve<DefaultClassMap<T>>(Array.Empty<object>()); defaultClassMap.AutoMap(this); Maps.Add(defaultClassMap); return defaultClassMap; } public virtual ClassMap AutoMap(Type type) { Type type2 = typeof(DefaultClassMap<>).MakeGenericType(type); ClassMap classMap = (ClassMap)ObjectResolver.Current.Resolve(type2); classMap.AutoMap(this); Maps.Add(classMap); return classMap; } } public class CsvDataReader : IDataReader, IDisposable, IDataRecord { private readonly CsvReader csv; private readonly DataTable schemaTable; private bool skipNextRead; public object this[int i] => csv[i] ?? string.Empty; public object this[string name] => csv[name] ?? string.Empty; public int Depth => 0; public bool IsClosed { get; private set; } public int RecordsAffected => 0; public int FieldCount => csv?.Parser.Count ?? 0; public CsvDataReader(CsvReader csv, DataTable? schemaTable = null) { this.csv = csv; csv.Read(); if (csv.Configuration.HasHeaderRecord && csv.HeaderRecord == null) { csv.ReadHeader(); } else { skipNextRead = true; } this.schemaTable = schemaTable ?? GetSchemaTable(); } public void Close() { Dispose(); } public void Dispose() { csv.Dispose(); IsClosed = true; } public bool GetBoolean(int i) { return csv.GetField<bool>(i); } public byte GetByte(int i) { return csv.GetField<byte>(i); } public long GetBytes(int i, long fieldOffset, byte[]? buffer, int bufferoffset, int length) { byte[] field = csv.GetField<byte[]>(i); if (field == null) { return 0L; } if (buffer == null) { buffer = new byte[field.Length]; } Array.Copy(field, fieldOffset, buffer, bufferoffset, length); return field.Length; } public char GetChar(int i) { return csv.GetField<char>(i); } public long GetChars(int i, long fieldoffset, char[]? buffer, int bufferoffset, int length) { char[] array = csv.GetField(i)?.ToCharArray(); if (array == null) { return 0L; } if (buffer == null) { buffer = new char[array.Length]; } Array.Copy(array, fieldoffset, buffer, bufferoffset, length); return array.Length; } public IDataReader GetData(int i) { throw new NotSupportedException(); } public string GetDataTypeName(int i) { if (i >= schemaTable.Rows.Count) { throw new IndexOutOfRangeException($"SchemaTable does not contain a definition for field '{i}'."); } Type obj = schemaTable.Rows[i]["DataType"] as Type; if (obj == null) { throw new InvalidOperationException($"SchemaTable does not contain a 'DataType' of type 'Type' for field '{i}'."); } return obj.Name; } public DateTime GetDateTime(int i) { return csv.GetField<DateTime>(i); } public decimal GetDecimal(int i) { return csv.GetField<decimal>(i); } public double GetDouble(int i) { return csv.GetField<double>(i); } public Type GetFieldType(int i) { return typeof(string); } public float GetFloat(int i) { return csv.GetField<float>(i); } public Guid GetGuid(int i) { return csv.GetField<Guid>(i); } public short GetInt16(int i) { return csv.GetField<short>(i); } public int GetInt32(int i) { return csv.GetField<int>(i); } public long GetInt64(int i) { return csv.GetField<long>(i); } public string GetName(int i) { if (!csv.Configuration.HasHeaderRecord) { return string.Empty; } string[]? headerRecord = csv.HeaderRecord; return ((headerRecord != null) ? headerRecord[i] : null) ?? string.Empty; } public int GetOrdinal(string name) { int fieldIndex = csv.GetFieldIndex(name, 0, isTryGet: true); if (fieldIndex >= 0) { return fieldIndex; } PrepareHeaderForMatchArgs args = new PrepareHeaderForMatchArgs(name, 0); string text = csv.Configuration.PrepareHeaderForMatch(args); string[] headerRecord = csv.HeaderRecord; for (int i = 0; i < ((headerRecord != null) ? headerRecord.Length : 0); i++) { args = new PrepareHeaderForMatchArgs(((headerRecord != null) ? headerRecord[i] : null) ?? string.Empty, i); string @string = csv.Configuration.PrepareHeaderForMatch(args); if (csv.Configuration.CultureInfo.CompareInfo.Compare(text, @string, CompareOptions.IgnoreCase) == 0) { return i; } } throw new IndexOutOfRangeException("Field with name '" + name + "' and prepared name '" + text + "' was not found."); } public DataTable GetSchemaTable() { if (schemaTable != null) { return schemaTable; } DataTable dataTable = new DataTable("SchemaTable"); dataTable.Columns.Add("AllowDBNull", typeof(bool)); dataTable.Columns.Add("AutoIncrementSeed", typeof(long)); dataTable.Columns.Add("AutoIncrementStep", typeof(long)); dataTable.Columns.Add("BaseCatalogName"); dataTable.Columns.Add("BaseColumnName"); dataTable.Columns.Add("BaseColumnNamespace"); dataTable.Columns.Add("BaseSchemaName"); dataTable.Columns.Add("BaseTableName"); dataTable.Columns.Add("BaseTableNamespace"); dataTable.Columns.Add("ColumnName"); dataTable.Columns.Add("ColumnMapping", typeof(MappingType)); dataTable.Columns.Add("ColumnOrdinal", typeof(int)); dataTable.Columns.Add("ColumnSize", typeof(int)); dataTable.Columns.Add("DataType", typeof(Type)); dataTable.Columns.Add("DefaultValue", typeof(object)); dataTable.Columns.Add("Expression"); dataTable.Columns.Add("IsAutoIncrement", typeof(bool)); dataTable.Columns.Add("IsKey", typeof(bool)); dataTable.Columns.Add("IsLong", typeof(bool)); dataTable.Columns.Add("IsReadOnly", typeof(bool)); dataTable.Columns.Add("IsRowVersion", typeof(bool)); dataTable.Columns.Add("IsUnique", typeof(bool)); dataTable.Columns.Add("NumericPrecision", typeof(short)); dataTable.Columns.Add("NumericScale", typeof(short)); dataTable.Columns.Add("ProviderType", typeof(int)); for (int i = 0; i < csv.ColumnCount; i++) { object obj; if (!csv.Configuration.HasHeaderRecord) { obj = i; } else { string[]? headerRecord = csv.HeaderRecord; obj = ((headerRecord != null) ? headerRecord[i] : null); } object value = obj; DataRow dataRow = dataTable.NewRow(); dataRow["AllowDBNull"] = true; dataRow["AutoIncrementSeed"] = DBNull.Value; dataRow["AutoIncrementStep"] = DBNull.Value; dataRow["BaseCatalogName"] = null; dataRow["BaseColumnName"] = value; dataRow["BaseColumnNamespace"] = null; dataRow["BaseSchemaName"] = null; dataRow["BaseTableName"] = null; dataRow["BaseTableNamespace"] = null; dataRow["ColumnName"] = value; dataRow["ColumnMapping"] = MappingType.Element; dataRow["ColumnOrdinal"] = i; dataRow["ColumnSize"] = int.MaxValue; dataRow["DataType"] = typeof(string); dataRow["DefaultValue"] = null; dataRow["Expression"] = null; dataRow["IsAutoIncrement"] = false; dataRow["IsKey"] = false; dataRow["IsLong"] = false; dataRow["IsReadOnly"] = true; dataRow["IsRowVersion"] = false; dataRow["IsUnique"] = false; dataRow["NumericPrecision"] = DBNull.Value; dataRow["NumericScale"] = DBNull.Value; dataRow["ProviderType"] = DbType.String; dataTable.Rows.Add(dataRow); } return dataTable; } public string GetString(int i) { return csv.GetField(i) ?? string.Empty; } public object GetValue(int i) { object obj; if (!IsDBNull(i)) { obj = csv.GetField(i); if (obj == null) { return string.Empty; } } else { obj = DBNull.Value; } return obj; } public int GetValues(object[] values) { for (int i = 0; i < values.Length; i++) { values[i] = (IsDBNull(i) ? ((IConvertible)DBNull.Value) : ((IConvertible)(csv.GetField(i) ?? string.Empty))); } return csv.Parser.Count; } public bool IsDBNull(int i) { string field = csv.GetField(i); List<string> nullValues = csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues; if (field != null) { return nullValues.Contains(field); } return true; } public bool NextResult() { return false; } public bool Read() { if (skipNextRead) { skipNextRead = false; return true; } return csv.Read(); } } [Serializable] public class CsvHelperException : Exception { [NonSerialized] private readonly CsvContext? context; public CsvContext? Context => context; protected internal CsvHelperException() { } protected internal CsvHelperException(string message) : base(message) { } protected internal CsvHelperException(string message, Exception innerException) : base(message, innerException) { } public CsvHelperException(CsvContext context) { this.context = context; } public CsvHelperException(CsvContext context, string message) : base(AddDetails(message, context)) { this.context = context; } public CsvHelperException(CsvContext context, string message, Exception innerException) : base(AddDetails(message, context), innerException) { this.context = context; } private static string AddDetails(string message, CsvContext context) { string text = new string(' ', 3); StringBuilder stringBuilder = new StringBuilder(); if (context.Reader != null) { stringBuilder.AppendLine("IReader state:"); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "ColumnCount", context.Reader.ColumnCount)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "CurrentIndex", context.Reader.CurrentIndex)); try { StringBuilder stringBuilder2 = new StringBuilder(); if (context.Reader.HeaderRecord != null) { stringBuilder2.Append("[\""); stringBuilder2.Append(string.Join("\",\"", context.Reader.HeaderRecord)); stringBuilder2.Append("\"]"); } stringBuilder.AppendLine(string.Format("{0}{1}:{2}{3}", text, "HeaderRecord", Environment.NewLine, stringBuilder2)); } catch { } } if (context.Parser != null) { stringBuilder.AppendLine("IParser state:"); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "ByteCount", context.Parser.ByteCount)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "CharCount", context.Parser.CharCount)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Row", context.Parser.Row)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "RawRow", context.Parser.RawRow)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Count", context.Parser.Count)); try { string text2 = (context.Configuration.ExceptionMessagesContainRawData ? context.Parser.RawRecord : "Hidden because ExceptionMessagesContainRawData is false."); stringBuilder.AppendLine(text + "RawRecord:" + Environment.NewLine + text2); } catch { } } if (context.Writer != null) { stringBuilder.AppendLine("IWriter state:"); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Row", context.Writer.Row)); stringBuilder.AppendLine(string.Format("{0}{1}: {2}", text, "Index", context.Writer.Index)); StringBuilder stringBuilder3 = new StringBuilder(); if (context.Writer.HeaderRecord != null) { stringBuilder3.Append("["); if (context.Writer.HeaderRecord.Length != 0) { stringBuilder3.Append("\""); stringBuilder3.Append(string.Join("\",\"", context.Writer.HeaderRecord)); stringBuilder3.Append("\""); } stringBuilder3.Append("]"); } stringBuilder.AppendLine(string.Format("{0}{1}:{2}{3}", text, "HeaderRecord", Environment.NewLine, context.Writer.Row)); } return $"{message}{Environment.NewLine}{stringBuilder}"; } } public enum CsvMode { RFC4180, Escape, NoEscape } public class CsvParser : IParser, IDisposable { [DebuggerDisplay("Start = {Start}, Length = {Length}, Buffer.Length = {Buffer.Length}")] protected readonly struct ProcessedField { public readonly int Start; public readonly int Length; public readonly char[] Buffer; public ProcessedField(int start, int length, char[] buffer) { Start = start; Length = length; Buffer = buffer; } } private enum ReadLineResult { None, Complete, Incomplete } private enum ParserState { None, Spaces, BlankLine, Delimiter, LineEnding, NewLine } [DebuggerDisplay("Start = {Start}, Length = {Length}, QuoteCount = {QuoteCount}, IsBad = {IsBad}")] private struct Field { public int Start; public int Length; public int QuoteCount; public bool IsBad; public bool IsProcessed; } private readonly IParserConfiguration configuration; private readonly FieldCache fieldCache = new FieldCache(); private readonly TextReader reader; private readonly char quote; private readonly char escape; private readonly bool countBytes; private readonly Encoding encoding; private readonly bool ignoreBlankLines; private readonly char comment; private readonly bool allowComments; private readonly BadDataFound? badDataFound; private readonly bool lineBreakInQuotedFieldIsBadData; private readonly TrimOptions trimOptions; private readonly char[] whiteSpaceChars; private readonly bool leaveOpen; private readonly CsvMode mode; private readonly string newLine; private readonly char newLineFirstChar; private readonly bool isNewLineSet; private readonly bool cacheFields; private readonly string[] delimiterValues; private readonly bool detectDelimiter; private readonly double maxFieldSize; private string delimiter; private char delimiterFirstChar; private char[] buffer; private int bufferSize; private int charsRead; private int bufferPosition; private int rowStartPosition; private int fieldStartPosition; private int row; private int rawRow; private long charCount; private long byteCount; private bool inQuotes; private bool inEscape; private Field[] fields; private string[] processedFields; private int fieldsPosition; private bool disposed; private int quoteCount; private char[] processFieldBuffer; private int processFieldBufferSize; private ParserState state; private int delimiterPosition = 1; private int newLinePosition = 1; private bool fieldIsBadData; private bool fieldIsQuoted; private bool isProcessingField; private bool isRecordProcessed; private string[] record = Array.Empty<string>(); public long CharCount => charCount; public long ByteCount => byteCount; public int Row => row; public string[]? Record { get { if (isRecordProcessed) { return record; } if (fieldsPosition == 0) { return null; } string[] array = new string[fieldsPosition]; for (int i = 0; i < array.Length; i++) { array[i] = this[i]; } record = array; isRecordProcessed = true; return record; } } public string RawRecord => new string(buffer, rowStartPosition, bufferPosition - rowStartPosition); public int Count => fieldsPosition; public int RawRow => rawRow; public string Delimiter => delimiter; public CsvContext Context { get; private set; } public IParserConfiguration Configuration => configuration; public string this[int index] { get { if (isProcessingField) { string message = "You can't access IParser[int] or IParser.Record inside of the BadDataFound callback. Use BadDataFoundArgs.Field and BadDataFoundArgs.RawRecord instead."; throw new ParserException(Context, message); } isProcessingField = true; string field = GetField(index); isProcessingField = false; return field; } } public CsvParser(TextReader reader, CultureInfo culture, bool leaveOpen = false) : this(reader, new CsvConfiguration(culture), leaveOpen) { } public CsvParser(TextReader reader, IParserConfiguration configuration, bool leaveOpen = false) { this.reader = reader ?? throw new ArgumentNullException("reader"); this.configuration = configuration ?? throw new ArgumentNullException("configuration"); configuration.Validate(); Context = new CsvContext(this); allowComments = configuration.AllowComments; badDataFound = configuration.BadDataFound; bufferSize = configuration.BufferSize; cacheFields = configuration.CacheFields; comment = configuration.Comment; countBytes = configuration.CountBytes; delimiter = configuration.Delimiter; delimiterFirstChar = configuration.Delimiter[0]; delimiterValues = configuration.DetectDelimiterValues; detectDelimiter = configuration.DetectDelimiter; encoding = configuration.Encoding; escape = configuration.Escape; ignoreBlankLines = configuration.IgnoreBlankLines; isNewLineSet = configuration.IsNewLineSet; this.leaveOpen = leaveOpen; lineBreakInQuotedFieldIsBadData = configuration.LineBreakInQuotedFieldIsBadData; maxFieldSize = configuration.MaxFieldSize; newLine = configuration.NewLine; newLineFirstChar = configuration.NewLine[0]; mode = configuration.Mode; processFieldBufferSize = configuration.ProcessFieldBufferSize; quote = configuration.Quote; whiteSpaceChars = configuration.WhiteSpaceChars; trimOptions = configuration.TrimOptions; buffer = new char[bufferSize]; processFieldBuffer = new char[processFieldBufferSize]; fields = new Field[128]; processedFields = new string[128]; } public bool Read() { isRecordProcessed = false; rowStartPosition = bufferPosition; fieldStartPosition = rowStartPosition; fieldsPosition = 0; quoteCount = 0; row++; rawRow++; char c = '\0'; char cPrev = c; do { if (bufferPosition >= charsRead) { if (!FillBuffer()) { return ReadEndOfFile(); } if (row == 1 && detectDelimiter) { DetectDelimiter(); } } } while (ReadLine(ref c, ref cPrev) != ReadLineResult.Complete); return true; } public async Task<bool> ReadAsync() { isRecordProcessed = false; rowStartPosition = bufferPosition; fieldStartPosition = rowStartPosition; fieldsPosition = 0; quoteCount = 0; row++; rawRow++; char c = '\0'; char cPrev = c; do { if (bufferPosition >= charsRead) { if (!(await FillBufferAsync().ConfigureAwait(continueOnCapturedContext: false))) { return ReadEndOfFile(); } if (row == 1 && detectDelimiter) { DetectDelimiter(); } } } while (ReadLine(ref c, ref cPrev) != ReadLineResult.Complete); return true; } private void DetectDelimiter() { string text = new string(buffer, 0, charsRead); string text2 = configuration.GetDelimiter(new GetDelimiterArgs(text, configuration)); if (text2 != null) { delimiter = text2; delimiterFirstChar = text2[0]; configuration.Validate(); } } private ReadLineResult ReadLine(ref char c, ref char cPrev) { while (bufferPosition < charsRead) { if (state != 0) { ReadLineResult readLineResult = state switch { ParserState.Spaces => ReadSpaces(ref c), ParserState.BlankLine => ReadBlankLine(ref c), ParserState.Delimiter => ReadDelimiter(ref c), ParserState.LineEnding => ReadLineEnding(ref c), ParserState.NewLine => ReadNewLine(ref c), _ => throw new InvalidOperationException($"Parser state '{state}' is not valid."), }; int num = readLineResult switch { ReadLineResult.Complete => (state == ParserState.LineEnding || state == ParserState.NewLine) ? 1 : 0, ReadLineResult.Incomplete => 1, _ => 0, }; if (readLineResult == ReadLineResult.Complete) { state = ParserState.None; } if (num != 0) { return readLineResult; } } cPrev = c; c = buffer[bufferPosition]; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } if (maxFieldSize > 0.0 && (double)(bufferPosition - fieldStartPosition - 1) > maxFieldSize) { throw new MaxFieldSizeException(Context); } if (rowStartPosition == bufferPosition - 1 && ((allowComments && c == comment) || (ignoreBlankLines && (((c == '\r' || c == '\n') && !isNewLineSet) || (c == newLineFirstChar && isNewLineSet))))) { state = ParserState.BlankLine; if (ReadBlankLine(ref c) == ReadLineResult.Complete) { state = ParserState.None; continue; } return ReadLineResult.Incomplete; } if (mode == CsvMode.RFC4180) { bool flag = fieldStartPosition == bufferPosition - 1; if (flag) { if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim && ArrayHelper.Contains(whiteSpaceChars, in c)) { ReadLineResult readLineResult2 = ReadSpaces(ref c); if (readLineResult2 == ReadLineResult.Incomplete) { fieldStartPosition = bufferPosition; return readLineResult2; } } fieldIsQuoted = c == quote; } if (fieldIsQuoted) { if (c == quote || c == escape) { quoteCount++; if (!inQuotes && !flag && cPrev != escape) { fieldIsBadData = true; } else if (!fieldIsBadData) { inQuotes = !inQuotes; } } if (inQuotes) { if (c != '\r' && (c != '\n' || cPrev == '\r')) { continue; } rawRow++; if (!lineBreakInQuotedFieldIsBadData) { continue; } fieldIsBadData = true; } } else if (c == quote || c == escape) { fieldIsBadData = true; } } else if (mode == CsvMode.Escape) { if (inEscape) { inEscape = false; continue; } if (c == escape) { inEscape = true; continue; } } if (c == delimiterFirstChar) { state = ParserState.Delimiter; ReadLineResult readLineResult3 = ReadDelimiter(ref c); if (readLineResult3 == ReadLineResult.Incomplete) { return readLineResult3; } state = ParserState.None; continue; } if (!isNewLineSet && (c == '\r' || c == '\n')) { state = ParserState.LineEnding; ReadLineResult num2 = ReadLineEnding(ref c); if (num2 == ReadLineResult.Complete) { state = ParserState.None; } return num2; } if (!isNewLineSet || c != newLineFirstChar) { continue; } state = ParserState.NewLine; ReadLineResult num3 = ReadNewLine(ref c); if (num3 == ReadLineResult.Complete) { state = ParserState.None; } return num3; } return ReadLineResult.Incomplete; } private ReadLineResult ReadSpaces(ref char c) { while (ArrayHelper.Contains(whiteSpaceChars, in c)) { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } c = buffer[bufferPosition]; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } } return ReadLineResult.Complete; } private ReadLineResult ReadBlankLine(ref char c) { while (bufferPosition < charsRead) { if (c == '\r' || c == '\n') { ReadLineResult num = ReadLineEnding(ref c); if (num == ReadLineResult.Complete) { rowStartPosition = bufferPosition; fieldStartPosition = rowStartPosition; row++; rawRow++; } return num; } c = buffer[bufferPosition]; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } } return ReadLineResult.Incomplete; } private ReadLineResult ReadDelimiter(ref char c) { for (int i = delimiterPosition; i < delimiter.Length; i++) { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } delimiterPosition++; c = buffer[bufferPosition]; if (c != delimiter[i]) { c = buffer[bufferPosition - 1]; delimiterPosition = 1; return ReadLineResult.Complete; } bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } } AddField(fieldStartPosition, bufferPosition - fieldStartPosition - delimiter.Length); fieldStartPosition = bufferPosition; delimiterPosition = 1; fieldIsBadData = false; return ReadLineResult.Complete; } private ReadLineResult ReadLineEnding(ref char c) { int num = 1; if (c == '\r') { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } c = buffer[bufferPosition]; if (c == '\n') { num++; bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } } } if (state == ParserState.LineEnding) { AddField(fieldStartPosition, bufferPosition - fieldStartPosition - num); } fieldIsBadData = false; return ReadLineResult.Complete; } private ReadLineResult ReadNewLine(ref char c) { for (int i = newLinePosition; i < newLine.Length; i++) { if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } newLinePosition++; c = buffer[bufferPosition]; if (c != newLine[i]) { c = buffer[bufferPosition - 1]; newLinePosition = 1; return ReadLineResult.Complete; } bufferPosition++; charCount++; if (countBytes) { byteCount += encoding.GetByteCount(new char[1] { c }); } if (bufferPosition >= charsRead) { return ReadLineResult.Incomplete; } } AddField(fieldStartPosition, bufferPosition - fieldStartPosition - newLine.Length); fieldStartPosition = bufferPosition; newLinePosition = 1; fieldIsBadData = false; return ReadLineResult.Complete; } private bool ReadEndOfFile() { ParserState parserState = state; state = ParserState.None; switch (parserState) { case ParserState.BlankLine: return false; case ParserState.Delimiter: AddField(fieldStartPosition, bufferPosition - fieldStartPosition - delimiter.Length); fieldStartPosition = bufferPosition; AddField(fieldStartPosition, bufferPosition - fieldStartPosition); return true; case ParserState.LineEnding: AddField(fieldStartPosition, bufferPosition - fieldStartPosition - 1); return true; case ParserState.NewLine: AddField(fieldStartPosition, bufferPosition - fieldStartPosition - newLine.Length); return true; default: if (rowStartPosition < bufferPosition) { AddField(fieldStartPosition, bufferPosition - fieldStartPosition); } return fieldsPosition > 0; } } private void AddField(int start, int length) { if (fieldsPosition >= fields.Length) { int newSize = fields.Length * 2; Array.Resize(ref fields, newSize); Array.Resize(ref processedFields, newSize); } ref Field reference = ref fields[fieldsPosition]; reference.Start = start - rowStartPosition; reference.Length = length; reference.QuoteCount = quoteCount; reference.IsBad = fieldIsBadData; reference.IsProcessed = false; fieldsPosition++; quoteCount = 0; } private bool FillBuffer() { if (rowStartPosition == 0 && charCount > 0 && charsRead == bufferSize) { bufferSize *= 2; char[] array = new char[bufferSize]; buffer.CopyTo(array, 0); buffer = array; } int num = Math.Max(charsRead - rowStartPosition, 0); Array.Copy(buffer, rowStartPosition, buffer, 0, num); fieldStartPosition -= rowStartPosition; rowStartPosition = 0; bufferPosition = num; charsRead = reader.Read(buffer, num, buffer.Length - num); if (charsRead == 0) { return false; } charsRead += num; return true; } private async Task<bool> FillBufferAsync() { if (rowStartPosition == 0 && charCount > 0 && charsRead == bufferSize) { bufferSize *= 2; char[] array = new char[bufferSize]; buffer.CopyTo(array, 0); buffer = array; } int charsLeft = Math.Max(charsRead - rowStartPosition, 0); Array.Copy(buffer, rowStartPosition, buffer, 0, charsLeft); fieldStartPosition -= rowStartPosition; rowStartPosition = 0; bufferPosition = charsLeft; charsRead = await reader.ReadAsync(buffer, charsLeft, buffer.Length - charsLeft).ConfigureAwait(continueOnCapturedContext: false); if (charsRead == 0) { return false; } charsRead += charsLeft; return true; } private string GetField(int index) { if (index > fieldsPosition) { throw new IndexOutOfRangeException(); } ref Field reference = ref fields[index]; if (reference.Length == 0) { return string.Empty; } if (reference.IsProcessed) { return processedFields[index]; } int start = reference.Start + rowStartPosition; int length = reference.Length; int num = reference.QuoteCount; ProcessedField processedField = mode switch { CsvMode.RFC4180 => reference.IsBad ? ProcessRFC4180BadField(start, length) : ProcessRFC4180Field(start, length, num), CsvMode.Escape => ProcessEscapeField(start, length), CsvMode.NoEscape => ProcessNoEscapeField(start, length), _ => throw new InvalidOperationException($"ParseMode '{mode}' is not handled."), }; string text = (cacheFields ? fieldCache.GetField(processedField.Buffer, processedField.Start, processedField.Length) : new string(processedField.Buffer, processedField.Start, processedField.Length)); processedFields[index] = text; reference.IsProcessed = true; return text; } protected ProcessedField ProcessRFC4180Field(int start, int length, int quoteCount) { int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (quoteCount == 0) { return new ProcessedField(start2, length2, buffer); } if (buffer[start2] != quote || buffer[start2 + length2 - 1] != quote || (length2 == 1 && buffer[start2] == quote)) { return ProcessRFC4180BadField(start, length); } start2++; length2 -= 2; if ((trimOptions & TrimOptions.InsideQuotes) == TrimOptions.InsideQuotes) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (quoteCount == 2) { return new ProcessedField(start2, length2, buffer); } if (length2 > processFieldBuffer.Length) { while (length2 > processFieldBufferSize) { processFieldBufferSize *= 2; } processFieldBuffer = new char[processFieldBufferSize]; } bool flag = false; int num = 0; for (int i = start2; i < start2 + length2; i++) { char c = buffer[i]; if (flag) { flag = false; } else if (c == escape) { flag = true; continue; } processFieldBuffer[num] = c; num++; } return new ProcessedField(0, num, processFieldBuffer); } protected ProcessedField ProcessRFC4180BadField(int start, int length) { BadDataFoundArgs args = new BadDataFoundArgs(new string(buffer, start, length), RawRecord, Context); badDataFound?.Invoke(args); int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (buffer[start2] != quote) { return new ProcessedField(start2, length2, buffer); } if (length2 > processFieldBuffer.Length) { while (length2 > processFieldBufferSize) { processFieldBufferSize *= 2; } processFieldBuffer = new char[processFieldBufferSize]; } bool flag = false; int num = 0; char c = '\0'; bool flag2 = false; for (int i = start2 + 1; i < start2 + length2; i++) { char c2 = c; c = buffer[i]; if (flag) { flag = false; if (c == quote) { continue; } if (c2 == quote) { flag2 = true; } } if (c == escape && !flag2) { flag = true; continue; } processFieldBuffer[num] = c; num++; } return new ProcessedField(0, num, processFieldBuffer); } protected ProcessedField ProcessEscapeField(int start, int length) { int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } if (length2 > processFieldBuffer.Length) { while (length2 > processFieldBufferSize) { processFieldBufferSize *= 2; } processFieldBuffer = new char[processFieldBufferSize]; } bool flag = false; int num = 0; for (int i = start2; i < start2 + length2; i++) { char c = buffer[i]; if (flag) { flag = false; } else if (c == escape) { flag = true; continue; } processFieldBuffer[num] = c; num++; } return new ProcessedField(0, num, processFieldBuffer); } protected ProcessedField ProcessNoEscapeField(int start, int length) { int start2 = start; int length2 = length; if ((trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { ArrayHelper.Trim(buffer, ref start2, ref length2, whiteSpaceChars); } return new ProcessedField(start2, length2, buffer); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing && !leaveOpen) { reader?.Dispose(); } disposed = true; } } } public class CsvReader : IReader, IReaderRow, IDisposable { [CompilerGenerated] private sealed class <EnumerateRecords>d__90<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IDisposable, IEnumerator where T : notnull { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; public CsvReader <>4__this; private T record; public T <>3__record; T IEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateRecords>d__90(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. e.g. .ToList() Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { if (!csvReader.Read()) { return false; } csvReader.ReadHeader(); csvReader.ValidateHeader<T>(); } break; case 1: <>1__state = -1; break; } while (csvReader.Read()) { try { csvReader.recordManager.Value.Hydrate(record); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } <>2__current = record; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<T> IEnumerable<T>.GetEnumerator() { <EnumerateRecords>d__90<T> <EnumerateRecords>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateRecords>d__ = this; } else { <EnumerateRecords>d__ = new <EnumerateRecords>d__90<T>(0) { <>4__this = <>4__this }; } <EnumerateRecords>d__.record = <>3__record; return <EnumerateRecords>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<T>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetRecords>d__87<T> : IEnumerable<T>, IEnumerable, IEnumerator<T>, IDisposable, IEnumerator where T : notnull { private int <>1__state; private T <>2__current; private int <>l__initialThreadId; public CsvReader <>4__this; private Func<T> <read>5__2; T IEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecords>d__87(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <read>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. e.g. .ToList() Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { if (!csvReader.Read()) { return false; } csvReader.ReadHeader(); csvReader.ValidateHeader<T>(); } <read>5__2 = null; break; case 1: <>1__state = -1; break; } while (csvReader.Read()) { T val; try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<T>(typeof(T)); } val = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } <>2__current = val; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<T> IEnumerable<T>.GetEnumerator() { <GetRecords>d__87<T> result; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; result = this; } else { result = new <GetRecords>d__87<T>(0) { <>4__this = <>4__this }; } return result; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<T>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetRecords>d__89 : IEnumerable<object>, IEnumerable, IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private int <>l__initialThreadId; public CsvReader <>4__this; private Type type; public Type <>3__type; private Func<object> <read>5__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecords>d__89(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <read>5__2 = null; <>1__state = -2; } private bool MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<object>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. e.g. .ToList() Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { if (!csvReader.Read()) { return false; } csvReader.ReadHeader(); csvReader.ValidateHeader(type); } <read>5__2 = null; break; case 1: <>1__state = -1; break; } while (csvReader.Read()) { object obj; try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<object>(type); } obj = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } <>2__current = obj; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<object> IEnumerable<object>.GetEnumerator() { <GetRecords>d__89 <GetRecords>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <GetRecords>d__ = this; } else { <GetRecords>d__ = new <GetRecords>d__89(0) { <>4__this = <>4__this }; } <GetRecords>d__.type = <>3__type; return <GetRecords>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<object>)this).GetEnumerator(); } } [CompilerGenerated] private sealed class <GetRecordsAsync>d__91<T> : IAsyncEnumerable<T>, IAsyncEnumerator<T>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine where T : notnull { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private T <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; public CsvReader <>4__this; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; private Func<T> <read>5__2; private ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter <>u__1; T IAsyncEnumerator<T>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecordsAsync>d__91(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; try { ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter awaiter; T val; switch (num) { default: if (<>w__disposeMode) { break; } num = (<>1__state = -1); if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { <>2__current = default(T); awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_00e0; } goto IL_0102; case 0: awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_00e0; case -4: num = (<>1__state = -1); if (<>w__disposeMode) { break; } goto IL_01cd; case 1: { awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_023a; } IL_023a: if (!awaiter.GetResult()) { break; } cancellationToken.ThrowIfCancellationRequested(); try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<T>(typeof(T)); } val = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } goto IL_01cd; } <>2__current = val; num = (<>1__state = -4); goto IL_02e6; IL_0102: <read>5__2 = null; goto IL_01cd; IL_00e0: if (!awaiter.GetResult()) { <>w__disposeMode = true; break; } csvReader.ReadHeader(); csvReader.ValidateHeader<T>(); goto IL_0102; IL_01cd: <>2__current = default(T); awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__1 = awaiter; <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_023a; } } catch (Exception exception) { <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = default(T); <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = default(T); <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_02e6: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<T> IAsyncEnumerable<T>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetRecordsAsync>d__91<T> <GetRecordsAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetRecordsAsync>d__ = this; } else { <GetRecordsAsync>d__ = new <GetRecordsAsync>d__91<T>(-3) { <>4__this = <>4__this }; } if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetRecordsAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetRecordsAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<T>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__91<T> stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } [CompilerGenerated] private sealed class <GetRecordsAsync>d__93 : IAsyncEnumerable<object>, IAsyncEnumerator<object>, IAsyncDisposable, IValueTaskSource<bool>, IValueTaskSource, IAsyncStateMachine { public int <>1__state; public AsyncIteratorMethodBuilder <>t__builder; public ManualResetValueTaskSourceCore<bool> <>v__promiseOfValueOrEnd; private object <>2__current; private bool <>w__disposeMode; private CancellationTokenSource <>x__combinedTokens; private int <>l__initialThreadId; public CsvReader <>4__this; private Type type; public Type <>3__type; private CancellationToken cancellationToken; public CancellationToken <>3__cancellationToken; private Func<object> <read>5__2; private ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter <>u__1; object IAsyncEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <GetRecordsAsync>d__93(int <>1__state) { <>t__builder = AsyncIteratorMethodBuilder.Create(); this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } private void MoveNext() { int num = <>1__state; CsvReader csvReader = <>4__this; try { ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter awaiter; object obj; switch (num) { default: if (<>w__disposeMode) { break; } num = (<>1__state = -1); if (csvReader.disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<object>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (csvReader.hasHeaderRecord && csvReader.headerRecord == null) { <>2__current = null; awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 0); <>u__1 = awaiter; <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_00db; } goto IL_0103; case 0: awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_00db; case -4: num = (<>1__state = -1); if (<>w__disposeMode) { break; } goto IL_01ca; case 1: { awaiter = <>u__1; <>u__1 = default(ConfiguredTaskAwaitable<bool>.ConfiguredTaskAwaiter); num = (<>1__state = -1); goto IL_0232; } IL_0232: if (!awaiter.GetResult()) { break; } cancellationToken.ThrowIfCancellationRequested(); try { if (<read>5__2 == null) { <read>5__2 = csvReader.recordManager.Value.GetReadDelegate<object>(type); } obj = <read>5__2(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(csvReader.context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? readingExceptionOccurred = csvReader.readingExceptionOccurred; if (readingExceptionOccurred == null || readingExceptionOccurred(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } goto IL_01ca; } <>2__current = obj; num = (<>1__state = -4); goto IL_02d4; IL_0103: <read>5__2 = null; goto IL_01ca; IL_00db: if (!awaiter.GetResult()) { <>w__disposeMode = true; break; } csvReader.ReadHeader(); csvReader.ValidateHeader(type); goto IL_0103; IL_01ca: <>2__current = null; awaiter = csvReader.ReadAsync().ConfigureAwait(continueOnCapturedContext: false).GetAwaiter(); if (!awaiter.IsCompleted) { num = (<>1__state = 1); <>u__1 = awaiter; <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.AwaitUnsafeOnCompleted(ref awaiter, ref stateMachine); return; } goto IL_0232; } } catch (Exception exception) { <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetException(exception); return; } <>1__state = -2; <read>5__2 = null; if (<>x__combinedTokens != null) { <>x__combinedTokens.Dispose(); <>x__combinedTokens = null; } <>2__current = null; <>t__builder.Complete(); <>v__promiseOfValueOrEnd.SetResult(result: false); return; IL_02d4: <>v__promiseOfValueOrEnd.SetResult(result: true); } void IAsyncStateMachine.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext this.MoveNext(); } [DebuggerHidden] private void SetStateMachine(IAsyncStateMachine stateMachine) { } void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine) { //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine this.SetStateMachine(stateMachine); } [DebuggerHidden] IAsyncEnumerator<object> IAsyncEnumerable<object>.GetAsyncEnumerator(CancellationToken cancellationToken = default(CancellationToken)) { <GetRecordsAsync>d__93 <GetRecordsAsync>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = -3; <>t__builder = AsyncIteratorMethodBuilder.Create(); <>w__disposeMode = false; <GetRecordsAsync>d__ = this; } else { <GetRecordsAsync>d__ = new <GetRecordsAsync>d__93(-3) { <>4__this = <>4__this }; } <GetRecordsAsync>d__.type = <>3__type; if (<>3__cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = cancellationToken; } else if (cancellationToken.Equals(<>3__cancellationToken) || cancellationToken.Equals(default(CancellationToken))) { <GetRecordsAsync>d__.cancellationToken = <>3__cancellationToken; } else { <>x__combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(<>3__cancellationToken, cancellationToken); <GetRecordsAsync>d__.cancellationToken = <>x__combinedTokens.Token; } return <GetRecordsAsync>d__; } [DebuggerHidden] ValueTask<bool> IAsyncEnumerator<object>.MoveNextAsync() { if (<>1__state == -2) { return default(ValueTask<bool>); } <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); short version = <>v__promiseOfValueOrEnd.Version; if (<>v__promiseOfValueOrEnd.GetStatus(version) == ValueTaskSourceStatus.Succeeded) { return new ValueTask<bool>(<>v__promiseOfValueOrEnd.GetResult(version)); } return new ValueTask<bool>(this, version); } [DebuggerHidden] bool IValueTaskSource<bool>.GetResult(short token) { return <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource<bool>.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource<bool>.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] void IValueTaskSource.GetResult(short token) { <>v__promiseOfValueOrEnd.GetResult(token); } [DebuggerHidden] ValueTaskSourceStatus IValueTaskSource.GetStatus(short token) { return <>v__promiseOfValueOrEnd.GetStatus(token); } [DebuggerHidden] void IValueTaskSource.OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) { <>v__promiseOfValueOrEnd.OnCompleted(continuation, state, token, flags); } [DebuggerHidden] ValueTask IAsyncDisposable.DisposeAsync() { if (<>1__state >= -1) { throw new NotSupportedException(); } if (<>1__state == -2) { return default(ValueTask); } <>w__disposeMode = true; <>v__promiseOfValueOrEnd.Reset(); <GetRecordsAsync>d__93 stateMachine = this; <>t__builder.MoveNext(ref stateMachine); return new ValueTask(this, <>v__promiseOfValueOrEnd.Version); } } private readonly Lazy<RecordManager> recordManager; private readonly bool detectColumnCountChanges; private readonly Dictionary<string, List<int>> namedIndexes = new Dictionary<string, List<int>>(); private readonly Dictionary<string, (string, int)> namedIndexCache = new Dictionary<string, (string, int)>(); private readonly Dictionary<Type, TypeConverterOptions> typeConverterOptionsCache = new Dictionary<Type, TypeConverterOptions>(); private readonly MemberMapData reusableMemberMapData = new MemberMapData(null); private readonly bool hasHeaderRecord; private readonly HeaderValidated? headerValidated; private readonly ShouldSkipRecord? shouldSkipRecord; private readonly ReadingExceptionOccurred? readingExceptionOccurred; private readonly CultureInfo cultureInfo; private readonly bool ignoreBlankLines; private readonly MissingFieldFound? missingFieldFound; private readonly bool includePrivateMembers; private readonly PrepareHeaderForMatch prepareHeaderForMatch; private CsvContext context; private bool disposed; private IParser parser; private int prevColumnCount; private int currentIndex = -1; private bool hasBeenRead; private string[]? headerRecord; public virtual int ColumnCount => parser.Count; public virtual int CurrentIndex => currentIndex; public virtual string[]? HeaderRecord => headerRecord; public virtual CsvContext Context => context; public virtual IReaderConfiguration Configuration { get; private set; } public virtual IParser Parser => parser; public virtual string? this[int index] { get { CheckHasBeenRead(); return GetField(index); } } public virtual string? this[string name] { get { CheckHasBeenRead(); return GetField(name); } } public virtual string? this[string name, int index] { get { CheckHasBeenRead(); return GetField(name, index); } } public CsvReader(TextReader reader, CultureInfo culture, bool leaveOpen = false) : this(new CsvParser(reader, culture, leaveOpen)) { } public CsvReader(TextReader reader, IReaderConfiguration configuration, bool leaveOpen = false) : this(new CsvParser(reader, configuration, leaveOpen)) { } public CsvReader(IParser parser) { Configuration = (parser.Configuration as IReaderConfiguration) ?? throw new ConfigurationException("The IParser configuration must implement IReaderConfiguration to be used in CsvReader."); this.parser = parser ?? throw new ArgumentNullException("parser"); context = parser.Context ?? throw new InvalidOperationException("For IParser to be used in CsvReader, Context must also implement CsvContext."); context.Reader = this; recordManager = new Lazy<RecordManager>(() => ObjectResolver.Current.Resolve<RecordManager>(new object[1] { this })); cultureInfo = Configuration.CultureInfo; detectColumnCountChanges = Configuration.DetectColumnCountChanges; hasHeaderRecord = Configuration.HasHeaderRecord; headerValidated = Configuration.HeaderValidated; ignoreBlankLines = Configuration.IgnoreBlankLines; includePrivateMembers = Configuration.IncludePrivateMembers; missingFieldFound = Configuration.MissingFieldFound; prepareHeaderForMatch = Configuration.PrepareHeaderForMatch; readingExceptionOccurred = Configuration.ReadingExceptionOccurred; shouldSkipRecord = Configuration.ShouldSkipRecord; } public virtual bool ReadHeader() { if (!hasHeaderRecord) { throw new ReaderException(context, "Configuration.HasHeaderRecord is false."); } headerRecord = parser.Record; ParseNamedIndexes(); return headerRecord != null; } public virtual void ValidateHeader<T>() { ValidateHeader(typeof(T)); } public virtual void ValidateHeader(Type type) { if (!hasHeaderRecord) { throw new InvalidOperationException("Validation can't be performed on a the header if no header exists. HasHeaderRecord can't be false."); } CheckHasBeenRead(); if (headerRecord == null) { throw new InvalidOperationException("The header must be read before it can be validated."); } if (context.Maps[type] == null) { context.Maps.Add(context.AutoMap(type)); } ClassMap map = context.Maps[type]; List<InvalidHeader> list = new List<InvalidHeader>(); ValidateHeader(map, list); HeaderValidatedArgs args = new HeaderValidatedArgs(list.ToArray(), context); headerValidated?.Invoke(args); } protected virtual void ValidateHeader(ClassMap map, List<InvalidHeader> invalidHeaders) { foreach (ParameterMap parameterMap in map.ParameterMaps) { if (!parameterMap.Data.Ignore && !parameterMap.Data.IsConstantSet && (!parameterMap.Data.IsIndexSet || parameterMap.Data.IsNameSet)) { if (parameterMap.ConstructorTypeMap != null) { ValidateHeader(parameterMap.ConstructorTypeMap, invalidHeaders); } else if (parameterMap.ReferenceMap != null) { ValidateHeader(parameterMap.ReferenceMap.Data.Mapping, invalidHeaders); } else if (GetFieldIndex(parameterMap.Data.Names, parameterMap.Data.NameIndex, isTryGet: true) == -1 && !parameterMap.Data.IsOptional) { invalidHeaders.Add(new InvalidHeader { Index = parameterMap.Data.NameIndex, Names = parameterMap.Data.Names.ToList() }); } } } foreach (MemberMap memberMap in map.MemberMaps) { if (!memberMap.Data.Ignore && CanRead(memberMap) && memberMap.Data.ReadingConvertExpression == null && !memberMap.Data.IsConstantSet && (!memberMap.Data.IsIndexSet || memberMap.Data.IsNameSet) && GetFieldIndex(memberMap.Data.Names, memberMap.Data.NameIndex, isTryGet: true) == -1 && !memberMap.Data.IsOptional) { invalidHeaders.Add(new InvalidHeader { Index = memberMap.Data.NameIndex, Names = memberMap.Data.Names.ToList() }); } } foreach (MemberReferenceMap referenceMap in map.ReferenceMaps) { if (CanRead(referenceMap)) { ValidateHeader(referenceMap.Data.Mapping, invalidHeaders); } } } public virtual bool Read() { bool flag; ShouldSkipRecord? obj; do { flag = parser.Read(); hasBeenRead = true; if (!flag) { break; } obj = shouldSkipRecord; } while (obj != null && obj(new ShouldSkipRecordArgs(this))); currentIndex = -1; if (detectColumnCountChanges && flag) { if (prevColumnCount > 0 && prevColumnCount != parser.Count) { BadDataException ex = new BadDataException(string.Empty, parser.RawRecord, context, "An inconsistent number of columns has been detected."); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex); ReadingExceptionOccurred? obj2 = readingExceptionOccurred; if (obj2 == null || obj2(args)) { throw ex; } } prevColumnCount = parser.Count; } return flag; } public virtual async Task<bool> ReadAsync() { bool flag; do { flag = await parser.ReadAsync().ConfigureAwait(continueOnCapturedContext: false); hasBeenRead = true; } while (flag && (shouldSkipRecord?.Invoke(new ShouldSkipRecordArgs(this)) ?? false)); currentIndex = -1; if (detectColumnCountChanges && flag) { if (prevColumnCount > 0 && prevColumnCount != parser.Count) { BadDataException ex = new BadDataException(string.Empty, parser.RawRecord, context, "An inconsistent number of columns has been detected."); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex); if (readingExceptionOccurred?.Invoke(args) ?? true) { throw ex; } } prevColumnCount = parser.Count; } return flag; } public virtual string? GetField(int index) { CheckHasBeenRead(); currentIndex = index; if (index >= parser.Count || index < 0) { MissingFieldFoundArgs args = new MissingFieldFoundArgs(null, index, context); missingFieldFound?.Invoke(args); return null; } return parser[index]; } public virtual string? GetField(string name) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name); if (fieldIndex < 0) { return null; } return GetField(fieldIndex); } public virtual string? GetField(string name, int index) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index); if (fieldIndex < 0) { return null; } return GetField(fieldIndex); } public virtual object? GetField(Type type, int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return GetField(type, index, converter); } public virtual object? GetField(Type type, string name) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return GetField(type, name, converter); } public virtual object? GetField(Type type, string name, int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return GetField(type, name, index, converter); } public virtual object? GetField(Type type, int index, ITypeConverter converter) { CheckHasBeenRead(); reusableMemberMapData.Index = index; reusableMemberMapData.TypeConverter = converter; if (!typeConverterOptionsCache.TryGetValue(type, out TypeConverterOptions value)) { value = TypeConverterOptions.Merge(new TypeConverterOptions { CultureInfo = cultureInfo }, context.TypeConverterOptionsCache.GetOptions(type)); typeConverterOptionsCache.Add(type, value); } reusableMemberMapData.TypeConverterOptions = value; string field = GetField(index); return converter.ConvertFromString(field, this, reusableMemberMapData); } public virtual object? GetField(Type type, string name, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name); return GetField(type, fieldIndex, converter); } public virtual object? GetField(Type type, string name, int index, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index); return GetField(type, fieldIndex, converter); } public virtual T? GetField<T>(int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return GetField<T>(index, converter); } public virtual T? GetField<T>(string name) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return GetField<T>(name, converter); } public virtual T? GetField<T>(string name, int index) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return GetField<T>(name, index, converter); } public virtual T? GetField<T>(int index, ITypeConverter converter) { CheckHasBeenRead(); if (index >= parser.Count || index < 0) { currentIndex = index; MissingFieldFoundArgs args = new MissingFieldFoundArgs(null, index, context); missingFieldFound?.Invoke(args); return default(T); } return (T)GetField(typeof(T), index, converter); } public virtual T? GetField<T>(string name, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name); return GetField<T>(fieldIndex, converter); } public virtual T? GetField<T>(string name, int index, ITypeConverter converter) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index); return GetField<T>(fieldIndex, converter); } public virtual T? GetField<T, TConverter>(int index) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return GetField<T>(index, val); } public virtual T? GetField<T, TConverter>(string name) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return GetField<T>(name, val); } public virtual T? GetField<T, TConverter>(string name, int index) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return GetField<T>(name, index, val); } public virtual bool TryGetField(Type type, int index, out object? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return TryGetField(type, index, converter, out field); } public virtual bool TryGetField(Type type, string name, out object? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return TryGetField(type, name, converter, out field); } public virtual bool TryGetField(Type type, string name, int index, out object? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter(type); return TryGetField(type, name, index, converter, out field); } public virtual bool TryGetField(Type type, int index, ITypeConverter converter, out object? field) { CheckHasBeenRead(); try { field = GetField(type, index, converter); return true; } catch { field = (type.GetTypeInfo().IsValueType ? ObjectResolver.Current.Resolve(type) : null); return false; } } public virtual bool TryGetField(Type type, string name, ITypeConverter converter, out object? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, 0, isTryGet: true); if (fieldIndex == -1) { field = (type.GetTypeInfo().IsValueType ? ObjectResolver.Current.Resolve(type) : null); return false; } return TryGetField(type, fieldIndex, converter, out field); } public virtual bool TryGetField(Type type, string name, int index, ITypeConverter converter, out object? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index, isTryGet: true); if (fieldIndex == -1) { field = (type.GetTypeInfo().IsValueType ? ObjectResolver.Current.Resolve(type) : null); return false; } return TryGetField(type, fieldIndex, converter, out field); } public virtual bool TryGetField<T>(int index, out T? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return TryGetField<T>(index, converter, out field); } public virtual bool TryGetField<T>(string name, out T? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return TryGetField<T>(name, converter, out field); } public virtual bool TryGetField<T>(string name, int index, out T? field) { CheckHasBeenRead(); ITypeConverter converter = context.TypeConverterCache.GetConverter<T>(); return TryGetField<T>(name, index, converter, out field); } public virtual bool TryGetField<T>(int index, ITypeConverter converter, out T? field) { CheckHasBeenRead(); try { field = GetField<T>(index, converter); return true; } catch { field = default(T); return false; } } public virtual bool TryGetField<T>(string name, ITypeConverter converter, out T? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, 0, isTryGet: true); if (fieldIndex == -1) { field = default(T); return false; } return TryGetField<T>(fieldIndex, converter, out field); } public virtual bool TryGetField<T>(string name, int index, ITypeConverter converter, out T? field) { CheckHasBeenRead(); int fieldIndex = GetFieldIndex(name, index, isTryGet: true); if (fieldIndex == -1) { field = default(T); return false; } return TryGetField<T>(fieldIndex, converter, out field); } public virtual bool TryGetField<T, TConverter>(int index, out T? field) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return TryGetField<T>(index, val, out field); } public virtual bool TryGetField<T, TConverter>(string name, out T? field) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return TryGetField<T>(name, val, out field); } public virtual bool TryGetField<T, TConverter>(string name, int index, out T? field) where TConverter : ITypeConverter { CheckHasBeenRead(); TConverter val = ObjectResolver.Current.Resolve<TConverter>(Array.Empty<object>()); return TryGetField<T>(name, index, val, out field); } public virtual T GetRecord<T>() { CheckHasBeenRead(); if (headerRecord == null && hasHeaderRecord) { ReadHeader(); ValidateHeader<T>(); if (!Read()) { throw new ReaderException(context, "There are no records."); } } try { return recordManager.Value.GetReadDelegate<T>(typeof(T))(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? obj = readingExceptionOccurred; if (obj == null || obj(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } return (T)args.Record; } } public virtual T GetRecord<T>(T anonymousTypeDefinition) { if (anonymousTypeDefinition == null) { throw new ArgumentNullException("anonymousTypeDefinition"); } if (!anonymousTypeDefinition.GetType().IsAnonymous()) { throw new ArgumentException("Argument is not an anonymous type.", "anonymousTypeDefinition"); } return GetRecord<T>(); } public virtual object GetRecord(Type type) { CheckHasBeenRead(); if (headerRecord == null && hasHeaderRecord) { ReadHeader(); ValidateHeader(type); if (!Read()) { throw new ReaderException(context, "There are no records."); } } try { return recordManager.Value.GetReadDelegate<object>(type)(); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); ReadingExceptionOccurred? obj = readingExceptionOccurred; if (obj == null || obj(args)) { if (ex is CsvHelperException) { throw; } throw ex2; } return args.Record; } } [IteratorStateMachine(typeof(<GetRecords>d__87<>))] public virtual IEnumerable<T> GetRecords<T>() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRecords>d__87<T>(-2) { <>4__this = this }; } public virtual IEnumerable<T> GetRecords<T>(T anonymousTypeDefinition) { if (anonymousTypeDefinition == null) { throw new ArgumentNullException("anonymousTypeDefinition"); } if (!anonymousTypeDefinition.GetType().IsAnonymous()) { throw new ArgumentException("Argument is not an anonymous type.", "anonymousTypeDefinition"); } return GetRecords<T>(); } [IteratorStateMachine(typeof(<GetRecords>d__89))] public virtual IEnumerable<object> GetRecords(Type type) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <GetRecords>d__89(-2) { <>4__this = this, <>3__type = type }; } [IteratorStateMachine(typeof(<EnumerateRecords>d__90<>))] public virtual IEnumerable<T> EnumerateRecords<T>(T record) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateRecords>d__90<T>(-2) { <>4__this = this, <>3__record = record }; } [AsyncIteratorStateMachine(typeof(<GetRecordsAsync>d__91<>))] public virtual IAsyncEnumerable<T> GetRecordsAsync<T>([EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetRecordsAsync>d__91<T>(-2) { <>4__this = this, <>3__cancellationToken = cancellationToken }; } public virtual IAsyncEnumerable<T> GetRecordsAsync<T>(T anonymousTypeDefinition, CancellationToken cancellationToken = default(CancellationToken)) { if (anonymousTypeDefinition == null) { throw new ArgumentNullException("anonymousTypeDefinition"); } if (!anonymousTypeDefinition.GetType().IsAnonymous()) { throw new ArgumentException("Argument is not an anonymous type.", "anonymousTypeDefinition"); } return GetRecordsAsync<T>(cancellationToken); } [AsyncIteratorStateMachine(typeof(<GetRecordsAsync>d__93))] public virtual IAsyncEnumerable<object> GetRecordsAsync(Type type, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { return new <GetRecordsAsync>d__93(-2) { <>4__this = this, <>3__type = type, <>3__cancellationToken = cancellationToken }; } public virtual async IAsyncEnumerable<T> EnumerateRecordsAsync<T>(T record, [EnumeratorCancellation] CancellationToken cancellationToken = default(CancellationToken)) { if (disposed) { throw new ObjectDisposedException("CsvReader", "GetRecords<T>() returns an IEnumerable<T> that yields records. This means that the method isn't actually called until you try and access the values. Did you create CsvReader inside a using block and are now trying to access the records outside of that using block?"); } if (hasHeaderRecord && headerRecord == null) { if (!(await ReadAsync().ConfigureAwait(continueOnCapturedContext: false))) { yield break; } ReadHeader(); ValidateHeader<T>(); } while (await ReadAsync().ConfigureAwait(continueOnCapturedContext: false)) { cancellationToken.ThrowIfCancellationRequested(); try { recordManager.Value.Hydrate(record); } catch (Exception ex) { CsvHelperException ex2 = (ex as CsvHelperException) ?? new ReaderException(context, "An unexpected error occurred.", ex); ReadingExceptionOccurredArgs args = new ReadingExceptionOccurredArgs(ex2); if (readingExceptionOccurred?.Invoke(args) ?? true) { if (ex is CsvHelperException) { throw; } throw ex2; } continue; } yield return record; } } public virtual int GetFieldIndex(string name, int index = 0, bool isTryGet = false) { return GetFieldIndex(new string[1] { name }, index, isTryGet); } public virtual int GetFieldIndex(IEnumerable<string> names, int index = 0, bool isTryGet = false, bool isOptional = false) { if (names == null) { throw new ArgumentNullException("names"); } if (!hasHeaderRecord) { throw new ReaderException(context, "There is no header record to determine the index by name."); } if (headerRecord == null) { throw new ReaderException(context, "The header has not been read. You must call ReadHeader() before any fields can be retrieved by name."); } string key = string.Join("_", names) + index; if (namedIndexCache.TryGetValue(key, out (string, int) value)) { var (key2, index2) = value; return namedIndexes[key2][index2]; } string text = null; int num = 0; foreach (string name in names) { PrepareHeaderForMatchArgs args = new PrepareHeaderForMatchArgs(name, num); string text2 = prepareHeaderForMatch(args); if (namedIndexes.ContainsKey(text2 ?? string.Empty)) { text = text2; break; } num++; } if (text == null || index >= namedIndexes[text].Count) { if (!isTryGet && !isOptional) { MissingFieldFoundArgs args2 = new MissingFieldFoundArgs(names.ToArray(), index, context); missingFieldFound?.Invoke(args2); } return -1; } namedIndexCache.Add(key, (text, index)); return namedIndexes[text][index]; } public virtual bool CanRead(MemberMap memberMap) { bool flag = memberMap.Data.Ignore; PropertyInfo propertyInfo = memberMap.Data.Member as PropertyInfo; if (propertyInfo != null) { flag = flag || (propertyInfo.GetSetMethod() == null && !includePrivateMembers) || propertyInfo.GetSetMethod(nonPublic: true) == null; } return !flag; } public virtual bool CanRead(MemberReferenceMap memberReferenceMap) { bool flag = false; PropertyInfo propertyInfo = memberReferenceMap.Data.Member as PropertyInfo; if (propertyInfo != null) { flag = (propertyInfo.GetSetMethod() == null && !includePrivateMembers) || propertyInfo.GetSetMethod(nonPublic: true) == null; } return !flag; } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { parser.Dispose(); } disposed = true; } } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected virtual void CheckHasBeenRead() { if (!hasBeenRead) { throw new ReaderException(context, "You must call read on the reader before accessing its data."); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected virtual void ParseNamedIndexes() { if (headerRecord == null) { throw new ReaderException(context, "No header record was found."); } namedIndexes.Clear(); namedIndexCache.Clear(); for (int i = 0; i < headerRecord.Length; i++) { PrepareHeaderForMatchArgs args = new PrepareHeaderForMatchArgs(headerRecord[i], i); string key = prepareHeaderForMatch(args); if (namedIndexes.TryGetValue(key, out List<int> value)) { value.Add(i); continue; } namedIndexes[key] = new List<int> { i }; } } } public class CsvWriter : IWriter, IWriterRow, IDisposable, IAsyncDisposable { private readonly TextWriter writer; private readonly CsvContext context; private readonly Lazy<RecordManager> recordManager; private readonly TypeConverterCache typeConverterCache; private readonly TrimOptions trimOptions; private readonly ShouldQuote shouldQuote; private readonly MemberMapData reusableMemberMapData = new MemberMapData(null); private readonly Dictionary<Type, TypeConverterOptions> typeConverterOptionsCache = new Dictionary<Type, TypeConverterOptions>(); private readonly string quoteString; private readonly char quote; private readonly CultureInfo cultureInfo; private readonly char comment; private readonly bool hasHeaderRecord; private readonly bool includePrivateMembers; private readonly IComparer<string>? dynamicPropertySort; private readonly string delimiter; private readonly bool leaveOpen; private readonly string newLine; private readonly char[] injectionCharacters; private readonly char injectionEscapeCharacter; private readonly InjectionOptions injectionOptions; private readonly CsvMode mode; private readonly string escapeString; private readonly string escapeQuoteString; private readonly string escapeDelimiterString; private readonly string escapeNewlineString; private readonly string escapeEscapeString; private bool disposed; private bool hasHeaderBeenWritten; private int row = 1; private int index; private char[] buffer; private int bufferSize; private int bufferPosition; private Type? fieldType; public virtual string?[]? HeaderRecord { get; private set; } public virtual int Row => row; public virtual int Index => index; public virtual CsvContext Context => context; public virtual IWriterConfiguration Configuration { get; private set; } public CsvWriter(TextWriter writer, CultureInfo culture, bool leaveOpen = false) : this(writer, new CsvConfiguration(culture), leaveOpen) { } public CsvWriter(TextWriter writer, IWriterConfiguration configuration, bool leaveOpen = false) { IWriterConfiguration configuration2 = configuration; base..ctor(); CsvWriter csvWriter = this; configuration2.Validate(); this.writer = writer; Configuration = configuration2; context = new CsvContext(this); typeConverterCache = context.TypeConverterCache; recordManager = new Lazy<RecordManager>(() => ObjectResolver.Current.Resolve<RecordManager>(new object[1] { csvWriter })); comment = configuration2.Comment; bufferSize = configuration2.BufferSize; delimiter = configuration2.Delimiter; cultureInfo = configuration2.CultureInfo; dynamicPropertySort = configuration2.DynamicPropertySort; escapeDelimiterString = new string(configuration2.Delimiter.SelectMany((char c) => new char[2] { configuration2.Escape, c }).ToArray()); escapeNewlineString = new string(configuration2.NewLine.SelectMany((char c) => new char[2] { configuration2.Escape, c }).ToArray()); escapeQuoteString = new string(new char[2] { configuration2.Escape, configuration2.Quote }); escapeEscapeString = new string(new char[2] { configuration2.Escape, configuration2.Escape }); hasHeaderRecord = configuration2.HasHeaderRecord; includePrivateMembers = configuration2.IncludePrivateMembers; injectionCharacters = configuration2.InjectionCharacters; injectionEscapeCharacter = configuration2.InjectionEscapeCharacter; this.leaveOpen = leaveOpen; mode = configuration2.Mode; newLine = configuration2.NewLine; quote = configuration2.Quote; quoteString = configuration2.Quote.ToString(); escapeString = configuration2.Escape.ToString(); injectionOptions = configuration2.InjectionOptions; shouldQuote = configuration2.ShouldQuote; trimOptions = configuration2.TrimOptions; buffer = new char[bufferSize]; } public virtual void WriteConvertedField(string? field, Type fieldType) { this.fieldType = fieldType; if (field != null) { WriteField(field); } } public virtual void WriteField(string? field) { if (field != null && (trimOptions & TrimOptions.Trim) == TrimOptions.Trim) { field = field.Trim(); } if ((object)fieldType == null) { fieldType = typeof(string); } ShouldQuoteArgs args = new ShouldQuoteArgs(field, fieldType, this); bool flag = shouldQuote(args); WriteField(field, flag); } public virtual void WriteField(string? field, bool shouldQuote) { if (mode == CsvMode.RFC4180) { if (shouldQuote) { if (escapeString != quoteString) { field = field?.Replace(escapeString, escapeEscapeString); } field = field?.Replace(quoteString, escapeQuoteString); char c = quote; string text = c.ToString(); string? text2 = field; c = quote; field = text + text2 + c; } } else if (mode == CsvMode.Escape) { field = field?.Replace(escapeString, escapeEscapeString).Replace(quoteString, escapeQuoteString).Replace(delimiter, escapeDelimiterString) .Replace(newLine, escapeNewlineString); } if (injectionOptions != 0) { field = SanitizeForInjection(field); } if (index > 0) { WriteToBuffer(delimiter); } WriteToBuffer(field); index++; fieldType = null; } public virtual void WriteField<T>(T? field) { Type type = ((field == null) ? typeof(string) : field.GetType()); ITypeConverter converter = typeConverterCache.GetConverter(type); WriteField(field, converter); } public virtual void WriteField<T>(T? field, ITypeConverter converter) { Type type = ((field == null) ? typeof(string) : field.GetType()); reusableMemberMapData.TypeConverter = converter; if (!typeConverterOptionsCache.TryGetValue(type, out TypeConverterOptions value)) { value = TypeConverterOptions.Merge(new TypeConverterOptions { CultureInfo = cultureInfo }, context.TypeConverterOptionsCache.GetOptions(type)); typeConverterOptionsCache.Add(type, value); } reusableMemberMapData.TypeConverterOptions = value; string field2 = converter.ConvertToString(field, this, reusableMemberMapData); Wr