概述
最新官网MySQL通信协议栈说明地址:http://dev.mysql.com/doc/internals/en/client-server-protocol.html
1. 数据类型
1.1 整型
1.1.1 定长整型
定长整型最小位在最前,一共有如下几种定长整型:
int<1>
int<2>
int<3>
int<4>
int<6>
int<8>
例如:int<3>表示1为:
01 00 00
1.1.2 长度编码整型
int<lenenc>
根据长度不同,长度编码整型有不同的编码:
如果值<251,则存储为1字节整型
如果值≥251并<2^16,则存储为以0xfc开头+2字节整型
如果值≥2^16并<2^24,则存储为以0xfd开头+3字节整型
如果值≥2^24并<2^64,则存储为以0xfe开头+8字节整型
举例:
fa -- 250
fc fb 00 -- 251
1.1.3 实现
Int.java:
package io.timberwolf.net.protocols.mysql.data;
import com.google.common.base.Preconditions;
import java.nio.ByteBuffer;
/**
* MySQL protocol DataType - Integer Types
*
* @author Hash Zhang
* @version 0.0.0
* @see @http://dev.mysql.com/doc/internals/en/integer.html
*/
public class Int {
//定长整型数据编码解码
public static int writeLength1(ByteBuffer buffer, int num) {
Preconditions.checkArgument(num < 0x100);
buffer.put((byte) num);
return 1;
}
public static int readLength1(ByteBuffer buffer) {
Preconditions.checkNotNull(buffer);
return (int) buffer.get();
}
public static int writeLength2(ByteBuffer buffer, int num) {
Preconditions.checkArgument(num < 0x10000);
buffer.put((byte) (num));
buffer.put((byte) (num >>> 8));
return 2;
}
public static int readLength2(ByteBuffer buffer) {
Preconditions.checkNotNull(buffer);
int result = (int) buffer.get();
result += ((int) buffer.get()) << 8;
return result;
}
public static int writeLength3(ByteBuffer buffer, int num) {
Preconditions.checkArgument(num < 0x1000000);
buffer.put((byte) (num));
buffer.put((byte) (num >>> 8));
buffer.put((byte) (num >>> 16));
return 3;
}
public static int readLength3(ByteBuffer buffer) {
Preconditions.checkNotNull(buffer);
int result = (int) buffer.get();
result += ((int) buffer.get()) << 8;
result += ((int) buffer.get()) << 16;
return result;
}
public static int writeLength4(ByteBuffer buffer, long num) {
Preconditions.checkArgument(num < 0x100000000L);
buffer.put((byte) (num));
buffer.put((byte) (num >>> 8));
buffer.put((byte) (num >>> 16));
buffer.put((byte) (num >>> 24));
return 4;
}
public static long readLength4(ByteBuffer buffer) {
Preconditions.checkNotNull(buffer);
long result = (long) buffer.get();
result += ((long) buffer.get()) << 8;
result += ((long) buffer.get()) << 16;
result += ((long) buffer.get()) << 24;
return result;
}
public static int wrietLength6(ByteBuffer buffer, long num) {
Preconditions.checkArgument(num <= 0x1000000000000L);
buffer.put((byte) (num));
buffer.put((byte) (num >>> 8));
buffer.put((byte) (num >>> 16));
buffer.put((byte) (num >>> 24));
buffer.put((byte) (num >>> 32));
buffer.put((byte) (num >>> 40));
return 6;
}
public static long readLength6(ByteBuffer buffer) {
Preconditions.checkNotNull(buffer);
long result = (long) buffer.get();
result += ((long) buffer.get()) << 8;
result += ((long) buffer.get()) << 16;
result += ((long) buffer.get()) << 24;
result += ((long) buffer.get()) << 32;
result += ((long) buffer.get()) << 40;
return result;
}
public static int writeLength8(ByteBuffer buffer, long num) {
buffer.put((byte) num);
buffer.put((byte) (num >>> 8));
buffer.put((byte) (num >>> 16));
buffer.put((byte) (num >>> 24));
buffer.put((byte) (num >>> 32));
buffer.put((byte) (num >>> 40));
buffer.put((byte) (num >>> 48));
buffer.put((byte) (num >>> 56));
return 8;
}
public static long readLength8(ByteBuffer buffer) {
Preconditions.checkNotNull(buffer);
long result = (long) buffer.get();
result += ((long) buffer.get()) << 8;
result += ((long) buffer.get()) << 16;
result += ((long) buffer.get()) << 24;
result += ((long) buffer.get()) << 32;
result += ((long) buffer.get()) << 40;
result += ((long) buffer.get()) << 48;
result += ((long) buffer.get()) << 56;
return result;
}
//长度编码整型数据编码解码
public static int writeLengthEncoded(ByteBuffer buffer, long num) {
if (num < 0xfb) {
writeLength1(buffer, (int) num);
return 1;
} else if (num < 0x10000) {
buffer.put((byte) 0xfc);
writeLength2(buffer, (int) num);
return 3;
} else if (num < 0x10000) {
buffer.put((byte) 0xfd);
writeLength3(buffer, (int) num);
return 4;
} else {
buffer.put((byte) 0xfe);
writeLength8(buffer, num);
return 9;
}
}
public static long readLengthEncoded(ByteBuffer buffer) {
int num = readLength1(buffer);
long result = 0;
if(num < 0xfb){
result += num;
} else if(num == 0xfc){
result += readLength2(buffer);
} else if(num == 0xfd){
result += readLength3(buffer);
} else{
result +=readLength8(buffer);
}
return result;
}
}
1.2 字符串类型
1.2.1定长字符串
定长字符串拥有已知的固定的长度
1.2.2null截止字符串
字符串用[00]字节截止
1.2.3变长字符串
字符串长度由另一域值决定
1.2.4长度编码字符串
长度编码整型+定长字符串(长度为前面整型代表的数值)
1.2.5剩余长度字符串
如果字符串是包最后一个元素,它的长度可以由包长度减去当前位置决定。
string<lenenc> Protocol::LengthEncodedString
string<fix> Protocol::FixedLengthString
string<var> Protocol::VariableLengthString:
string<EOF> Protocol::RestOfPacketString
string<NUL> Protocol::NulTerminatedString
package io.timberwolf.net.protocols.mysql.data;
import com.google.common.base.Preconditions;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
/**
* MySQL protocol DataType - String Types
*
* @author Hash Zhang
* @version 0.0.0
* @see @http://dev.mysql.com/doc/internals/en/string.html
*/
public class Str {
public static int lengthEncoded(ByteBuffer buffer, String string, String charSet) throws UnsupportedEncodingException {
Preconditions.checkNotNull(string);
int length = string.getBytes(charSet).length;
length += Int.writeLengthEncoded(buffer,length);
buffer.put(string.getBytes(charSet));
return length;
}
}
最后
以上就是畅快超短裙为你收集整理的MySQL通信协议栈Java实现-(1)数据类型的全部内容,希望文章能够帮你解决MySQL通信协议栈Java实现-(1)数据类型所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复