<commit_before>using System;
using System.Buffers;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using MySql.Data.Types;
using MySqlConnector.Protocol;
using MySqlConnector.Protocol.Payloads;
using MySqlConnector.Protocol.Serialization;
using MySqlConnector.Utilities;

namespace MySqlConnector.Core
{
	internal sealed class ResultSet
	{
		public ResultSet(MySqlDataReader dataReader)
		{
			DataReader = dataReader;
		}

		public void Reset()
		{
			// ResultSet can be re-used, so initialize everything
			BufferState = ResultSetState.None;
			ColumnDefinitions = null;
			ColumnTypes = null;
			LastInsertId = 0;
			RecordsAffected = null;
			WarningCount = 0;
			State = ResultSetState.None;
			ContainsCommandParameters = false;
			m_columnDefinitionPayloadUsedBytes = 0;
			m_readBuffer?.Clear();
			m_row = null;
			m_hasRows = false;
			ReadResultSetHeaderException = null;
		}

		public async Task ReadResultSetHeaderAsync(IOBehavior ioBehavior)
		{
			Reset();

			try
			{
				while (true)
				{
					var payload = await Session.ReceiveReplyAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);

					var firstByte = payload.HeaderByte;
					if (firstByte == OkPayload.Signature)
					{
						var ok = OkPayload.Create(payload.Span, Session.SupportsDeprecateEof, Session.SupportsSessionTrack);
						RecordsAffected = (RecordsAffected ?? 0) + ok.AffectedRowCount;
						LastInsertId = unchecked((long) ok.LastInsertId);
						WarningCount = ok.WarningCount;
						if (ok.NewSchema is object)
							Connection.Session.DatabaseOverride = ok.NewSchema;
						ColumnDefinitions = null;
						ColumnTypes = null;
						State = (ok.ServerStatus & ServerStatus.MoreResultsExist) == 0
							? ResultSetState.NoMoreData
							: ResultSetState.HasMoreData;
						if (State == ResultSetState.NoMoreData)
							break;
					}
					else if (firstByte == LocalInfilePayload.Signature)
					{
						try
						{
							if (!Connection.AllowLoadLocalInfile)
								throw new NotSupportedException("To use LOAD DATA LOCAL INFILE, set AllowLoadLocalInfile=true in the connection string. See https://fl.vu/mysql-load-data");
							var localInfile = LocalInfilePayload.Create(payload.Span);
							var hasSourcePrefix = localInfile.FileName.StartsWith(MySqlBulkLoader.SourcePrefix, StringComparison.Ordinal);
							if (!IsHostVerified(Connection) && !hasSourcePrefix)
								throw new NotSupportedException("Use SourceStream or SslMode >= VerifyCA for LOAD DATA LOCAL INFILE. See https://fl.vu/mysql-load-data");

							var source = hasSourcePrefix ?
								MySqlBulkLoader.GetAndRemoveSource(localInfile.FileName) :
								File.OpenRead(localInfile.FileName);

							IDisposable? disposable = null;
							byte[]? buffer = null;
							try
							{
								switch (source)
								{
								case Stream stream:
									disposable = stream;
									buffer = ArrayPool<byte>.Shared.Rent(1048576);
									int byteCount;
									while ((byteCount = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
									{
										payload = new PayloadData(new ArraySegment<byte>(buffer, 0, byteCount));
										await Session.SendReplyAsync(payload, ioBehavior, CancellationToken.None).ConfigureAwait(false);
									}
									break;

								case MySqlBulkCopy bulkCopy:
									await bulkCopy.SendDataReaderAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);
									break;

								default:
									throw new InvalidOperationException("Unsupported Source type: {0}".FormatInvariant(source.GetType().Name));
								}
							}
							finally
							{
								if (buffer is object)
									ArrayPool<byte>.Shared.Return(buffer);
								disposable?.Dispose();
							}
						}
						catch (Exception ex)
						{
							// store the exception, to be thrown after reading the response packet from the server
							ReadResultSetHeaderException = new MySqlException("Error during LOAD DATA LOCAL INFILE", ex);
						}

						await Session.SendReplyAsync(EmptyPayload.Instance, ioBehavior, CancellationToken.None).ConfigureAwait(false);
					}
					else
					{
						int ReadColumnCount(ReadOnlySpan<byte> span)
						{
							var reader = new ByteArrayReader(span);
							var columnCount_ = (int) reader.ReadLengthEncodedInteger();
							if (reader.BytesRemaining != 0)
								throw new MySqlException("Unexpected data at end of column_count packet; see https://github.com/mysql-net/MySqlConnector/issues/324");
							return columnCount_;
						}
						var columnCount = ReadColumnCount(payload.Span);

						// reserve adequate space to hold a copy of all column definitions (but note that this can be resized below if we guess too small)
						Utility.Resize(ref m_columnDefinitionPayloads, columnCount * 96);

						ColumnDefinitions = new ColumnDefinitionPayload[columnCount];
						ColumnTypes = new MySqlDbType[columnCount];<commit_msg>Simplify code that's only used in one case.<commit_after>using System;
using System.Buffers;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MySql.Data.MySqlClient;
using MySql.Data.Types;
using MySqlConnector.Protocol;
using MySqlConnector.Protocol.Payloads;
using MySqlConnector.Protocol.Serialization;
using MySqlConnector.Utilities;

namespace MySqlConnector.Core
{
	internal sealed class ResultSet
	{
		public ResultSet(MySqlDataReader dataReader)
		{
			DataReader = dataReader;
		}

		public void Reset()
		{
			// ResultSet can be re-used, so initialize everything
			BufferState = ResultSetState.None;
			ColumnDefinitions = null;
			ColumnTypes = null;
			LastInsertId = 0;
			RecordsAffected = null;
			WarningCount = 0;
			State = ResultSetState.None;
			ContainsCommandParameters = false;
			m_columnDefinitionPayloadUsedBytes = 0;
			m_readBuffer?.Clear();
			m_row = null;
			m_hasRows = false;
			ReadResultSetHeaderException = null;
		}

		public async Task ReadResultSetHeaderAsync(IOBehavior ioBehavior)
		{
			Reset();

			try
			{
				while (true)
				{
					var payload = await Session.ReceiveReplyAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);

					var firstByte = payload.HeaderByte;
					if (firstByte == OkPayload.Signature)
					{
						var ok = OkPayload.Create(payload.Span, Session.SupportsDeprecateEof, Session.SupportsSessionTrack);
						RecordsAffected = (RecordsAffected ?? 0) + ok.AffectedRowCount;
						LastInsertId = unchecked((long) ok.LastInsertId);
						WarningCount = ok.WarningCount;
						if (ok.NewSchema is object)
							Connection.Session.DatabaseOverride = ok.NewSchema;
						ColumnDefinitions = null;
						ColumnTypes = null;
						State = (ok.ServerStatus & ServerStatus.MoreResultsExist) == 0
							? ResultSetState.NoMoreData
							: ResultSetState.HasMoreData;
						if (State == ResultSetState.NoMoreData)
							break;
					}
					else if (firstByte == LocalInfilePayload.Signature)
					{
						try
						{
							if (!Connection.AllowLoadLocalInfile)
								throw new NotSupportedException("To use LOAD DATA LOCAL INFILE, set AllowLoadLocalInfile=true in the connection string. See https://fl.vu/mysql-load-data");
							var localInfile = LocalInfilePayload.Create(payload.Span);
							var hasSourcePrefix = localInfile.FileName.StartsWith(MySqlBulkLoader.SourcePrefix, StringComparison.Ordinal);
							if (!IsHostVerified(Connection) && !hasSourcePrefix)
								throw new NotSupportedException("Use SourceStream or SslMode >= VerifyCA for LOAD DATA LOCAL INFILE. See https://fl.vu/mysql-load-data");

							var source = hasSourcePrefix ?
								MySqlBulkLoader.GetAndRemoveSource(localInfile.FileName) :
								File.OpenRead(localInfile.FileName);
							switch (source)
							{
							case Stream stream:
								var buffer = ArrayPool<byte>.Shared.Rent(1048576);
								try
								{
									int byteCount;
									while ((byteCount = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false)) > 0)
									{
										payload = new PayloadData(new ArraySegment<byte>(buffer, 0, byteCount));
										await Session.SendReplyAsync(payload, ioBehavior, CancellationToken.None).ConfigureAwait(false);
									}
								}
								finally
								{
									ArrayPool<byte>.Shared.Return(buffer);
									stream.Dispose();
								}
								break;

							case MySqlBulkCopy bulkCopy:
								await bulkCopy.SendDataReaderAsync(ioBehavior, CancellationToken.None).ConfigureAwait(false);
								break;

							default:
								throw new InvalidOperationException("Unsupported Source type: {0}".FormatInvariant(source.GetType().Name));
							}
						}
						catch (Exception ex)
						{
							// store the exception, to be thrown after reading the response packet from the server
							ReadResultSetHeaderException = new MySqlException("Error during LOAD DATA LOCAL INFILE", ex);
						}

						await Session.SendReplyAsync(EmptyPayload.Instance, ioBehavior, CancellationToken.None).ConfigureAwait(false);
					}
					else
					{
						int ReadColumnCount(ReadOnlySpan<byte> span)
						{
							var reader = new ByteArrayReader(span);
							var columnCount_ = (int) reader.ReadLengthEncodedInteger();
							if (reader.BytesRemaining != 0)
								throw new MySqlException("Unexpected data at end of column_count packet; see https://github.com/mysql-net/MySqlConnector/issues/324");
							return columnCount_;
						}
						var columnCount = ReadColumnCount(payload.Span);

						// reserve adequate space to hold a copy of all column definitions (but note that this can be resized below if we guess too small)
						Utility.Resize(ref m_columnDefinitionPayloads, columnCount * 96);

						ColumnDefinitions = new ColumnDefinitionPayload[columnCount];
						ColumnTypes = new MySqlDbType[columnCount];
{'fraction_non_alphanumeric': 0.08827960228984634, 'fraction_numerical': 0.004419001707341569, 'mean_word_length': 3.2356444066354744, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5547063', 'n_tokens_mistral': 3860, 'n_tokens_neox': 2785, 'n_words': 659}