我是靠谱客的博主 畅快超短裙,最近开发中收集的这篇文章主要介绍MySQL通信协议栈Java实现-(1)数据类型,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最新官网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)数据类型所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部