public CommandResult(Packet p, Driver d)
		{
			driver = d;
			packet = p;
			fieldCount = (int)p.ReadLenInteger();
			if (fieldCount == 0)
				affectedRows =(int)p.ReadLenInteger();
		}
		public MySqlField GetField()
		{
			MySqlField f = new MySqlField( driver.Encoding );
			packet = driver.ReadPacket();

			f.TableName = packet.ReadLenString();
			f.ColumnName = packet.ReadLenString();
			f.ColumnLength = (int)packet.ReadNBytes();
			f.Type = (MySqlDbType)packet.ReadNBytes();
			packet.ReadByte();									// this is apparently 2 -- not sure what it is for
			f.Flags = (ColumnFlags)packet.ReadInteger(2);		//(short)(d.ReadByte() & 0xff);
			f.NumericScale = packet.ReadByte();
			fieldsRead++;
			return f;
		}
		/// <summary>
		/// Send a single packet to the server.
		/// </summary>
		/// <param name="packet">Packet to send to the server</param>
		/// <remarks>This method will send a single packet to the server
		/// possibly breaking the packet up into smaller packets that are
		/// smaller than max_allowed_packet.  This method will always send at
		/// least one packet to the server</remarks>
        protected void SendPacket(Packet packet)
		{
			byte[]	buf = packet.GetBuffer();
			int		len = packet.Length;
			int		index = 0;
			bool	oneSent = false;

			// make sure we are not trying to send too much
			if (packet.Length > maxPacketSize && maxPacketSize > 0)
				throw new MySqlException("Packet size too large.  This MySQL server cannot accept rows larger than " + maxPacketSize + " bytes.");

			try 
			{
				while (len > 0 || ! oneSent) 
				{
					int lenToSend = Math.Min( len, MAX_PACKET_SIZE );

					// send the data
					if (useCompression)
						SendCompressedBuffer( buf, index, lenToSend );
					else 
					{
						WriteInteger( lenToSend, 3 );
						writer.WriteByte( packetSeq++ );
						writer.Write( buf, index, lenToSend );
						writer.Flush();
					}

					len -= lenToSend;
					index += lenToSend;
					oneSent = true;
				}
				writer.Flush();
			}
			catch (Exception ex)
			{
				Console.WriteLine( ex.Message );
			}
		}
		/// <summary>
		/// Reads a single packet off the stream
		/// </summary>
		/// <returns></returns>
		public Packet ReadPacket()
		{
			// if we have peeked at a packet, then return it
			if (peekedPacket != null)
			{
				Packet packet = peekedPacket;
				peekedPacket = null;
				return packet;
			}

			Packet p = ReadPacketFromServer();

			// if this is an error packet, then throw the exception
			if (p[0] == 0xff)
			{
				p.ReadByte();
				int errorCode = (int)p.ReadInteger(2);
				string msg = p.ReadString();
				throw new MySqlException( msg, errorCode );
			}
			
			return p;
		}
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public Packet PeekPacket()
		{
			if (peekedPacket != null)
				return peekedPacket;

			peekedPacket = ReadPacket();
			return peekedPacket;
		}
		/// <summary>
		/// AuthenticateSecurity implements the new 4.1 authentication scheme
		/// </summary>
		/// <param name="packet">The in-progress packet we use to complete the authentication</param>
		/// <param name="password">The password of the user to use</param>
		private void AuthenticateSecurely( Packet packet, string password )
		{
			packet.WriteString("xxxxxxxx", encoding );
			SendPacket(packet);

			packet = ReadPacket();

			// compute pass1 hash
			string newPass = password.Replace(" ","").Replace("\t","");
			SHA1 sha = new SHA1CryptoServiceProvider(); 
			byte[] firstPassBytes = sha.ComputeHash( System.Text.Encoding.Default.GetBytes(newPass));

			byte[] salt = packet.GetBuffer();
			byte[] input = new byte[ firstPassBytes.Length + 4 ];
			salt.CopyTo( input, 0 );
			firstPassBytes.CopyTo( input, 4 );
			byte[] outPass = new byte[100];
			byte[] secondPassBytes = sha.ComputeHash( input );

			byte[] cryptSalt = new byte[20];
			Security.ArrayCrypt( salt, 4, cryptSalt, 0, secondPassBytes, 20 );

			Security.ArrayCrypt( cryptSalt, 0, firstPassBytes, 0, firstPassBytes, 20 );

			// send the packet
			packet = CreatePacket(null);
			packet.Write( firstPassBytes, 0, 20 );
			SendPacket(packet);
		}
		public void Append( Packet p )
		{
			long oldPos = Position;
			Position = Length;
			this.Write( p.GetBuffer(), 0, p.Length );
			Position = oldPos;
		}
		public Packet ReadPacket()
		{
			if (! HasMoreData) return null;

			int len = this.ReadInteger(3);
			byte seq = (byte)this.ReadByte();
			byte[] buf = new byte[ len ];
			this.Read( buf, 0, len );
			Packet p = new Packet( buf, LongInts );
			p.Sequence = seq;
			p.Encoding = this.Encoding;
			return p;
		}
		/// <summary>
		/// Checks to see if there are any row packets coming
		/// </summary>
		/// <returns>True if there are row packets available, false if not</returns>
		public bool CheckForRows()
		{
			// first read off any unread field defs
			while (fieldsRead < fieldCount)
				GetField();

			// read off the end of schema packet
			packet = driver.ReadPacket();
			if ( ! packet.IsLastPacket())
				throw new MySqlException("Expected end of schema packet");
			readSchema = true;

			packet = driver.PeekPacket();
			return ! packet.IsLastPacket();
		}
		public bool ReadDataRow()
		{
			packet = driver.ReadPacket();
			if (packet.IsLastPacket())
			{
				readRows = true;
				return false;
			}
			fieldsRead = 0;
			fieldLength = 0;
			NextField();
			return true;
		}