您的位置:首页 > 编程语言 > Java开发

MySQL通信协议栈Java实现-(1)数据类型

2016-04-14 17:01 429 查看

最新官网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(ByteBuffe
24000
r 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;
}
}
<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐