/*
* Copyright 2015 Liu Huanting.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package fm.liu.timo.mysql.packet;
import java.nio.ByteBuffer;
import fm.liu.timo.mysql.BufferUtil;
import fm.liu.timo.mysql.MySQLMessage;
public abstract class MySQLPacket {
//
public static final int PACKET_HEADER_SIZE = 4; // 固定值
public static final int MAX_PACKET_SIZE = 16 * 1024 * 1024;// 固定值2^24,3个字节的最大值
protected int packetLength;
public byte packetId;
/**
* 计算数据包大小,不包含包头长度。
*/
public abstract int calcPacketSize();
/**
* 取得数据包信息
*/
protected abstract String getPacketInfo();
@Override
public String toString() {
return new StringBuilder().append(getPacketInfo()).append("{length=").append(packetLength)
.append(",id=").append(packetId).append('}').toString();
}
/**
* 获得MySQL PacketLength
*
* @param buffer
* @param offset
* @return
*/
public static int getPacketLength(ByteBuffer buffer, int offset) {
if (buffer.position() < offset + MySQLPacket.PACKET_HEADER_SIZE) {
return -1;
} else {
int length = buffer.get(offset) & 0xff;
length |= (buffer.get(++offset) & 0xff) << 8;
length |= (buffer.get(++offset) & 0xff) << 16;
return length + MySQLPacket.PACKET_HEADER_SIZE;
}
}
public void read(byte[] data) {
MySQLMessage mm = new MySQLMessage(data);
packetLength = mm.readUB3();
packetId = mm.read();
readBody(mm);
}
protected abstract void readBody(MySQLMessage mm);
/**
* 把mysql packet的内容写入到buffer中; 调用者已分配足够大的buffer空间,由调用者保证buffer.remaining() >= size,
* 不会出现一个packet分散写入多个buffer的情况,一个完整的mysql packet最多占用一个buffer。
*
* @param buffer
* @param size
*/
public void write(ByteBuffer buffer, int size) {
BufferUtil.writeUB3(buffer, size);
buffer.put(packetId);
writeBody(buffer);
}
protected abstract void writeBody(ByteBuffer buffer);
}