/* * Copyright 1999-2012 Alibaba Group. * * 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 com.alibaba.cobar.net.mysql; import java.nio.ByteBuffer; import com.alibaba.cobar.mysql.BufferUtil; import com.alibaba.cobar.mysql.MySQLMessage; import com.alibaba.cobar.net.FrontendConnection; /** * From Server To Client, part of Result Set Packets. One for each column in the * result set. Thus, if the value of field_columns in the Result Set Header * Packet is 3, then the Field Packet occurs 3 times. * * <pre> * Bytes Name * ----- ---- * n (Length Coded String) catalog * n (Length Coded String) db * n (Length Coded String) table * n (Length Coded String) org_table * n (Length Coded String) name * n (Length Coded String) org_name * 1 (filler) * 2 charsetNumber * 4 length * 1 type * 2 flags * 1 decimals * 2 (filler), always 0x00 * n (Length Coded Binary) default * * @see http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#Field_Packet * </pre> * * @author xianmao.hexm 2010-7-22 下午05:43:34 */ public class FieldPacket extends MySQLPacket { private static final byte[] DEFAULT_CATALOG = "def".getBytes(); private static final byte[] FILLER = new byte[2]; public byte[] catalog = DEFAULT_CATALOG; public byte[] db; public byte[] table; public byte[] orgTable; public byte[] name; public byte[] orgName; public int charsetIndex; public long length; public int type; public int flags; public byte decimals; public byte[] definition; /** * 把字节数组转变成FieldPacket */ public void read(byte[] data) { MySQLMessage mm = new MySQLMessage(data); this.packetLength = mm.readUB3(); this.packetId = mm.read(); readBody(mm); } /** * 把BinaryPacket转变成FieldPacket */ public void read(BinaryPacket bin) { this.packetLength = bin.packetLength; this.packetId = bin.packetId; readBody(new MySQLMessage(bin.data)); } @Override public ByteBuffer write(ByteBuffer buffer, FrontendConnection c) { int size = calcPacketSize(); buffer = c.checkWriteBuffer(buffer, c.getPacketHeaderSize() + size); BufferUtil.writeUB3(buffer, size); buffer.put(packetId); writeBody(buffer); return buffer; } @Override public int calcPacketSize() { int size = (catalog == null ? 1 : BufferUtil.getLength(catalog)); size += (db == null ? 1 : BufferUtil.getLength(db)); size += (table == null ? 1 : BufferUtil.getLength(table)); size += (orgTable == null ? 1 : BufferUtil.getLength(orgTable)); size += (name == null ? 1 : BufferUtil.getLength(name)); size += (orgName == null ? 1 : BufferUtil.getLength(orgName)); size += 13;// 1+2+4+1+2+1+2 if (definition != null) { size += BufferUtil.getLength(definition); } return size; } @Override protected String getPacketInfo() { return "MySQL Field Packet"; } private void readBody(MySQLMessage mm) { this.catalog = mm.readBytesWithLength(); this.db = mm.readBytesWithLength(); this.table = mm.readBytesWithLength(); this.orgTable = mm.readBytesWithLength(); this.name = mm.readBytesWithLength(); this.orgName = mm.readBytesWithLength(); mm.move(1); this.charsetIndex = mm.readUB2(); this.length = mm.readUB4(); this.type = mm.read() & 0xff; this.flags = mm.readUB2(); this.decimals = mm.read(); mm.move(FILLER.length); if (mm.hasRemaining()) { this.definition = mm.readBytesWithLength(); } } private void writeBody(ByteBuffer buffer) { byte nullVal = 0; BufferUtil.writeWithLength(buffer, catalog, nullVal); BufferUtil.writeWithLength(buffer, db, nullVal); BufferUtil.writeWithLength(buffer, table, nullVal); BufferUtil.writeWithLength(buffer, orgTable, nullVal); BufferUtil.writeWithLength(buffer, name, nullVal); BufferUtil.writeWithLength(buffer, orgName, nullVal); buffer.put((byte) 0x0C); BufferUtil.writeUB2(buffer, charsetIndex); BufferUtil.writeUB4(buffer, length); buffer.put((byte) (type & 0xff)); BufferUtil.writeUB2(buffer, flags); buffer.put(decimals); buffer.position(buffer.position() + FILLER.length); if (definition != null) { BufferUtil.writeWithLength(buffer, definition); } } }