/* * 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.jdbc.util; import java.util.Arrays; /** * @author xianmao.hexm */ public class MySQLMessage { private static final long NULL_LENGTH = -1; private static final byte[] EMPTY_BYTES = new byte[0]; private final byte[] data; private final int length; private int position; public MySQLMessage(byte[] data) { this.data = data; this.length = data.length; this.position = 0; } public int position() { return position; } public void move(int i) { position += i; } public boolean hasRemaining() { return length > position; } public byte read(int i) { return data[i]; } public byte read() { return data[position++]; } public int readUB2() { final byte[] b = this.data; int i = b[position++] & 0xff; i |= (b[position++] & 0xff) << 8; return i; } public int readUB3() { final byte[] b = this.data; int i = b[position++] & 0xff; i |= (b[position++] & 0xff) << 8; i |= (b[position++] & 0xff) << 16; return i; } public long readUB4() { final byte[] b = this.data; long l = (long) (b[position++] & 0xff); l |= (long) (b[position++] & 0xff) << 8; l |= (long) (b[position++] & 0xff) << 16; l |= (long) (b[position++] & 0xff) << 24; return l; } public long readLong() { final byte[] b = this.data; long l = (long) (b[position++] & 0xff); l |= (long) (b[position++] & 0xff) << 8; l |= (long) (b[position++] & 0xff) << 16; l |= (long) (b[position++] & 0xff) << 24; l |= (long) (b[position++] & 0xff) << 32; l |= (long) (b[position++] & 0xff) << 40; l |= (long) (b[position++] & 0xff) << 48; l |= (long) (b[position++] & 0xff) << 56; return l; } public long readLength() { int length = data[position++] & 0xff; switch (length) { case 251: return NULL_LENGTH; case 252: return readUB2(); case 253: return readUB3(); case 254: return readLong(); default: return length; } } public byte[] readBytes(int length) { byte[] ab = new byte[length]; System.arraycopy(data, position, ab, 0, length); position += length; return ab; } public byte[] readBytes() { if (position >= length) { return EMPTY_BYTES; } byte[] ab = new byte[length - position]; System.arraycopy(data, position, ab, 0, ab.length); position = length; return ab; } public byte[] readBytesWithNull() { final byte[] b = this.data; if (position >= length) { return EMPTY_BYTES; } int offset = -1; for (int i = position; i < length; i++) { if (b[i] == 0) { offset = i; break; } } switch (offset) { case -1: byte[] ab1 = new byte[length - position]; System.arraycopy(b, position, ab1, 0, ab1.length); position = length; return ab1; case 0: position++; return EMPTY_BYTES; default: byte[] ab2 = new byte[offset - position]; System.arraycopy(b, position, ab2, 0, ab2.length); position = offset + 1; return ab2; } } public byte[] readBytesWithLength() { int length = (int) readLength(); if (length <= 0) { return EMPTY_BYTES; } byte[] ab = new byte[length]; System.arraycopy(data, position, ab, 0, ab.length); position += length; return ab; } public String toString() { return new StringBuilder().append(Arrays.toString(data)).toString(); } }