org.lealone.plugins.mysql.server.protocol.PacketInput Maven / Gradle / Ivy
/*
* 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 org.lealone.plugins.mysql.server.protocol;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.Calendar;
import org.lealone.common.exceptions.DbException;
/**
* @author xianmao.hexm
* @author zhh
*/
public class PacketInput {
private static final long NULL_LENGTH = -1;
private static final byte[] EMPTY_BYTES = new byte[0];
private final byte[] b;
private final int length;
private int position;
public PacketInput(byte[] b) {
this.b = b;
this.length = b.length;
this.position = 0;
}
public int type() {
return b[4];
}
public int length() {
return length;
}
public int position() {
return position;
}
public byte[] bytes() {
return b;
}
public void move(int i) {
position += i;
}
public void position(int i) {
this.position = i;
}
public boolean hasRemaining() {
return length > position;
}
public byte read(int i) {
return b[i];
}
public byte read() {
return b[position++];
}
public int readUB2() {
int i = b[position++] & 0xff;
i |= (b[position++] & 0xff) << 8;
return i;
}
public int readUB3() {
int i = b[position++] & 0xff;
i |= (b[position++] & 0xff) << 8;
i |= (b[position++] & 0xff) << 16;
return i;
}
public long readUB4() {
long l = b[position++] & 0xff;
l |= (long) (b[position++] & 0xff) << 8;
l |= (long) (b[position++] & 0xff) << 16;
l |= (long) (b[position++] & 0xff) << 24;
return l;
}
public int readInt() {
int i = b[position++] & 0xff;
i |= (b[position++] & 0xff) << 8;
i |= (b[position++] & 0xff) << 16;
i |= (b[position++] & 0xff) << 24;
return i;
}
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
public long readLong() {
long l = 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 double readDouble() {
return Double.longBitsToDouble(readLong());
}
public long readLength() {
int length = b[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() {
if (position >= length) {
return EMPTY_BYTES;
}
byte[] ab = new byte[length - position];
System.arraycopy(b, position, ab, 0, ab.length);
position = length;
return ab;
}
public byte[] readBytes(int length) {
byte[] ab = new byte[length];
System.arraycopy(b, position, ab, 0, length);
position += length;
return ab;
}
public byte[] readBytesWithNull() {
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(b, position, ab, 0, ab.length);
position += length;
return ab;
}
public String readString() {
if (position >= length) {
return null;
}
String s = new String(b, position, length - position);
position = length;
return s;
}
public String readString(String charset) {
if (position >= length) {
return null;
}
String s = newString(b, position, length - position, charset);
position = length;
return s;
}
public String readStringWithNull() {
if (position >= length) {
return null;
}
int offset = -1;
for (int i = position; i < length; i++) {
if (b[i] == 0) {
offset = i;
break;
}
}
if (offset == -1) {
String s = new String(b, position, length - position);
position = length;
return s;
}
if (offset > position) {
String s = new String(b, position, offset - position);
position = offset + 1;
return s;
} else {
position++;
return null;
}
}
public String readStringWithNull(String charset) {
if (position >= length) {
return null;
}
int offset = -1;
for (int i = position; i < length; i++) {
if (b[i] == 0) {
offset = i;
break;
}
}
switch (offset) {
case -1:
String s1 = newString(b, position, length - position, charset);
position = length;
return s1;
case 0:
position++;
return null;
default:
String s2 = newString(b, position, offset - position, charset);
position = offset + 1;
return s2;
}
}
public String readStringWithLength() {
int length = (int) readLength();
if (length <= 0) {
return null;
}
String s = new String(b, position, length);
position += length;
return s;
}
public String readStringWithLength(String charset) {
int length = (int) readLength();
if (length <= 0) {
return null;
}
String s = newString(b, position, length, charset);
position += length;
return s;
}
public Time readTime() {
move(6);
int hour = read();
int minute = read();
int second = read();
Calendar cal = getLocalCalendar();
cal.set(0, 0, 0, hour, minute, second);
return new Time(cal.getTimeInMillis());
}
public java.util.Date readDate() {
byte length = read();
int year = readUB2();
byte month = read();
byte date = read();
int hour = read();
int minute = read();
int second = read();
if (length == 11) {
long nanos = readUB4();
Calendar cal = getLocalCalendar();
cal.set(year, --month, date, hour, minute, second);
Timestamp time = new Timestamp(cal.getTimeInMillis());
time.setNanos((int) nanos);
return time;
} else {
Calendar cal = getLocalCalendar();
cal.set(year, --month, date, hour, minute, second);
return new java.sql.Date(cal.getTimeInMillis());
}
}
public BigDecimal readBigDecimal() {
String src = readStringWithLength();
return src == null ? null : new BigDecimal(src);
}
@Override
public String toString() {
return Arrays.toString(b);
}
private static String newString(byte[] bytes, int offset, int length, String charsetName) {
try {
return new String(bytes, offset, length, charsetName);
} catch (UnsupportedEncodingException e) {
throw DbException.convert(e);
}
}
private static final ThreadLocal localCalendar = new ThreadLocal();
private static final Calendar getLocalCalendar() {
Calendar cal = localCalendar.get();
if (cal == null) {
cal = Calendar.getInstance();
localCalendar.set(cal);
}
return cal;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy