⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysqlpacketbuffer.java

📁 mysql集群
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * 	This program is free software; you can redistribute it and/or modify it under the terms of 
 * the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, 
 * or (at your option) any later version. 
 * 
 * 	This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details. 
 * 	You should have received a copy of the GNU General Public License along with this program; 
 * if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package com.meidusa.amoeba.mysql.net.packet;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import java.sql.SQLException;

import com.meidusa.amoeba.mysql.io.Constants;
import com.meidusa.amoeba.mysql.io.MySqlPacketConstant;
import com.meidusa.amoeba.mysql.util.MysqlStringUtil;
import com.meidusa.amoeba.mysql.util.SingleByteCharsetConverter;
import com.meidusa.amoeba.net.Connection;
import com.meidusa.amoeba.net.DatabaseConnection;
import com.meidusa.amoeba.net.packet.AbstractPacketBuffer;
import com.meidusa.amoeba.util.StringUtil;

/**
 * 
 * 该类负责 发送、接收 socket 输入流,并且可以根据包头信息,构造出ByteBuffer
 * @author <a href=mailto:piratebase@sina.com>Struct chen</a>
 */
public class MysqlPacketBuffer extends AbstractPacketBuffer{
	static final int MAX_BYTES_TO_DUMP = 512;

	static final int NO_LENGTH_LIMIT = -1;

	static final long NULL_LENGTH = -1;

	protected boolean wasMultiPacket = false;
	
	/**
	 * buf 中含包头信息
	 * @param buf
	 */
	public MysqlPacketBuffer(byte[] buf) {
		
		super(buf);
		this.position = MySqlPacketConstant.HEADER_SIZE;
	}
	
	public void init(Connection conn){
		super.init(conn);
	}
	
	public DatabaseConnection getConnection(){
		return (DatabaseConnection)this.conn;
	}
	
	public int getPacketLength(){
		if(buffer == null || buffer.length <4){
			return 0;
		}else{
			int packetLength = (buffer[0] & 0xff) +
            ((buffer[1] & 0xff) << 8) +
            ((buffer[2] & 0xff) << 16);
			return packetLength;
		}
	}
	
	public static int getPacketLength(byte[] byteBuffer){
		if(byteBuffer == null || byteBuffer.length <4){
			return 0;
		}else{
			int packetLength = (byteBuffer[0] & 0xff) +
            ((byteBuffer[1] & 0xff) << 8) +
            ((byteBuffer[2] & 0xff) << 16);
			return packetLength;
		}
	}
	
	public MysqlPacketBuffer(int size) {
		super(size);
		this.position = MySqlPacketConstant.HEADER_SIZE;
	}

	final void clear() {
		this.position = MySqlPacketConstant.HEADER_SIZE;
	}

	final void dump() {
		dump(getBufLength());
	}

	final String dump(int numBytes) {
		return StringUtil.dumpAsHex(getBytes(0,
				numBytes > getBufLength() ? getBufLength() : numBytes),
				numBytes > getBufLength() ? getBufLength() : numBytes);
	}

	final String dumpClampedBytes(int numBytes) {
		int numBytesToDump = numBytes < MAX_BYTES_TO_DUMP ? numBytes
				: MAX_BYTES_TO_DUMP;

		String dumped = StringUtil.dumpAsHex(getBytes(0,
				numBytesToDump > getBufLength() ? getBufLength()
						: numBytesToDump),
				numBytesToDump > getBufLength() ? getBufLength()
						: numBytesToDump);

		if (numBytesToDump < numBytes) {
			return dumped + " ....(packet exceeds max. dump length)";
		}

		return dumped;
	}

	final void dumpHeader() {
		for (int i = 0; i < MySqlPacketConstant.HEADER_SIZE; i++) {
			String hexVal = Integer.toHexString(readByte(i) & 0xff);

			if (hexVal.length() == 1) {
				hexVal = "0" + hexVal; //$NON-NLS-1$
			}

			System.out.print(hexVal + " "); //$NON-NLS-1$
		}
	}

	final void dumpNBytes(int start, int nBytes) {
		StringBuffer asciiBuf = new StringBuffer();

		for (int i = start; (i < (start + nBytes)) && (i < getBufLength()); i++) {
			String hexVal = Integer.toHexString(readByte(i) & 0xff);

			if (hexVal.length() == 1) {
				hexVal = "0" + hexVal; //$NON-NLS-1$
			}

			System.out.print(hexVal + " "); //$NON-NLS-1$

			if ((readByte(i) > 32) && (readByte(i) < 127)) {
				asciiBuf.append((char) readByte(i));
			} else {
				asciiBuf.append("."); //$NON-NLS-1$
			}

			asciiBuf.append(" "); //$NON-NLS-1$
		}

		System.out.println("    " + asciiBuf.toString()); //$NON-NLS-1$
	}

	protected void ensureCapacity(int additionalData){
		if ((this.position + additionalData) > getBufLength()) {
			if ((this.position + additionalData) < this.buffer.length) {
				// byteBuffer.length is != getBufLength() all of the time
				// due to re-using of packets (we don't shrink them)
				//
				// If we can, don't re-alloc, just set buffer length
				// to size of current buffer
				setBufLength(this.buffer.length);
			} else {
				//
				// Otherwise, re-size, and pad so we can avoid
				// allocing again in the near future
				//
				int newLength = this.position + (int)(additionalData * 1.5) + 1;
				while(newLength<this.position + additionalData +1){
					newLength = (int) (newLength * 1.5);
				}
				byte[] newBytes = new byte[newLength];

				System.arraycopy(this.buffer, 0, newBytes, 0,
						this.buffer.length);
				this.buffer = newBytes;
				setBufLength(this.buffer.length);
			}
		}
	}

	/**
	 * Skip over a length-encoded string
	 * 
	 * @return The position past the end of the string
	 */
	public int fastSkipLenString() {
		long len = this.readFieldLength();

		this.position += len;

		return (int) len;
	}

	public void fastSkipLenByteArray() {
		long len = this.readFieldLength();

		if (len == NULL_LENGTH || len == 0) {
			return;
		}
		
		this.position += len;
	}
	
	protected final byte[] getBufferSource() {
		return this.buffer;
	}

	int getBufLength() {
		return this.length;
	}

	/**
	 * Returns the array of bytes this Buffer is using to read from.
	 * 
	 * @return byte array being read from
	 */
	public byte[] getByteBuffer() {
		return this.buffer;
	}

	public final byte[] getBytes(int len) {
		byte[] b = new byte[len];
		System.arraycopy(this.buffer, this.position, b, 0, len);
		this.position += len; // update cursor

		return b;
	}

	public byte[] getBytes(int offset, int len) {
		byte[] dest = new byte[len];
		System.arraycopy(this.buffer, offset, dest, 0, len);

		return dest;
	}

	int getCapacity() {
		return this.buffer.length;
	}


	final boolean isLastDataPacket() {
		return ((getBufLength() < 9) && ((this.buffer[4] & 0xff) == 254));
	}

	final long newReadLength() {
		int sw = this.buffer[this.position++] & 0xff;

		switch (sw) {
		case 251:
			return 0;

		case 252:
			return readInt();

		case 253:
			return readLongInt();

		case 254: // changed for 64 bit lengths
			return readLongLong();

		default:
			return sw;
		}
	}

	final long readFieldLength() {
		int sw = this.buffer[this.position++] & 0xff;

		switch (sw) {
		case 251:
			return NULL_LENGTH;

		case 252:
			return readInt();

		case 253:
			return readLongInt();

		case 254:
			return readLongLong();

		default:
			return sw;
		}
	}

	final int readInt() {
		byte[] b = this.buffer; // a little bit optimization

		return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8);
	}

	final int readIntAsLong() {
		byte[] b = this.buffer;

		return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8)
				| ((b[this.position++] & 0xff) << 16)
				| ((b[this.position++] & 0xff) << 24);
	}

	final byte[] readLenByteArray(int offset) {
		long len = this.readFieldLength();

		if (len == NULL_LENGTH) {
			return null;
		}

		if (len == 0) {
			return Constants.EMPTY_BYTE_ARRAY;
		}

		this.position += offset;

		return getBytes((int) len);
	}

	final long readLength() {
		int sw = this.buffer[this.position++] & 0xff;

		switch (sw) {
		case 251:
			return 0;

		case 252:
			return readInt();

		case 253:
			return readLongInt();

		case 254:
			return readLong();

		default:
			return sw;
		}
	}

	final long readLong() {
		byte[] b = this.buffer;

		return ((long) b[this.position++] & 0xff)
				| (((long) b[this.position++] & 0xff) << 8)
				| ((long) (b[this.position++] & 0xff) << 16)
				| ((long) (b[this.position++] & 0xff) << 24);
	}

	final int readLongInt() {
		byte[] b = this.buffer;

		return (b[this.position++] & 0xff) | ((b[this.position++] & 0xff) << 8)
				| ((b[this.position++] & 0xff) << 16);
	}

	final long readLongLong() {
		byte[] b = this.buffer;

		return (b[this.position++] & 0xff)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -