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>
相关文章推荐
- MySQL通信协议栈Java实现-(1)数据类型
- MySQL通信协议栈Java实现-(1)数据类型
- Java容器-引用数据类型排序+TreeSet、TreeMap底层实现
- java中数据类型间的最大值,最小值及转换程序代码实现
- Java中不同转换符实现不同数据类型到字符串的转换
- Java容器-引用数据类型排序+TreeSet、TreeMap底层实现
- 多态的运用 实现java 数据类型判断
- 【算法】哈希摘要算法,CRC冗余算法,MD摘要算法,纯JAVA基本数据类型代码实现,面向对象
- Java的IO操作(二) - 带缓冲区的流对象、写入基本数据类型、实现命令行中的copy命令
- fastjson:实现对java.nio.ByteBuffer数据类型的支持
- Java的IO操作(二) - 带缓冲区的流对象、写入基本数据类型、实现命令行中的copy命令
- Java中不同转换符实现不同数据类型到字符串的转换
- 【java基础】在Java中实现基本数据类型与字符、字符串之间的转换
- Java的IO操作(二) - 带缓冲区的流对象、写入基本数据类型、实现命令行中的copy命令
- java 引用数据类型实现 对象的克隆
- java用重载实现获取元素的数据类型
- java实现基础数据类型中二进制位操作算法
- Java 基础数据类型 和 深度克隆对象的2种方法(实现Cloneable接口或者实现对象序列化)
- 怎样在Java中实现基本数据类型与字符之间的转换
- Gsoap调用java实现的webservice时,如何传递复杂数据类型?