Decompiled source of CSV Helper v1.0.0

BepInEx/patchers/CsvHelper.dll

Decompiled 2 months ago
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
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