Overview
For an RPC framework, it is essential to define a serialization protocol for network data, and the Thrift serialization protocol mainly includes the following: Tbinaryprotocol Tcompactprotocol tjsonprotocol Tsimplejsonprotocol Ttupleprotocol (inherited from Tcompactprotocol)
Just like the thrift Source Parsing (a) Main class overview of the class inheritance diagram, these serialization protocols are inherited from Tprotocol this abstract class (why thrift did not choose interface I also puzzled). basic methods for serializing Protocols
This article unifies the Thrift Source Code main Analysis Tbinaryprotocol realization method.
Let's look at the base class for these serialization protocols, Tprotocol, which contains some abstract functions as follows:
/** * Writing methods.
*/public abstract void Writemessagebegin (Tmessage message) throws Texception;
public abstract void Writemessageend () throws texception;
public abstract void Writestructbegin (tstruct struct) throws texception;
public abstract void Writestructend () throws texception;
public abstract void Writefieldbegin (Tfield field) throws Texception;
public abstract void Writefieldend () throws texception;
public abstract void Writefieldstop () throws texception;
public abstract void Writemapbegin (TMap map) throws texception;
public abstract void Writemapend () throws texception;
public abstract void Writelistbegin (TList list) throws Texception;
public abstract void Writelistend () throws texception;
public abstract void Writesetbegin (Tset set) throws Texception;
public abstract void Writesetend () throws texception;
public abstract void Writebool (Boolean B) throws texception; public abstract void WriteByte (Byte b) throws texception;
public abstract void writeI16 (short i16) throws texception;
public abstract void writeI32 (int i32) throws texception;
public abstract void writeI64 (Long i64) throws texception;
public abstract void Writedouble (Double dub) throws Texception;
public abstract void WriteString (String str) throws texception;
public abstract void Writebinary (Bytebuffer buf) throws texception;
/** * Reading methods.
*/Public abstract tmessage Readmessagebegin () throws texception;
public abstract void Readmessageend () throws texception;
Public abstract tstruct Readstructbegin () throws texception;
public abstract void Readstructend () throws texception;
Public abstract Tfield Readfieldbegin () throws texception;
public abstract void Readfieldend () throws texception;
Public abstract TMap Readmapbegin () throws texception;
public abstract void Readmapend () throws texception;
Public abstract TList Readlistbegin () throws texception; public abstract void ReadliStend () throws texception;
Public abstract Tset Readsetbegin () throws texception;
public abstract void Readsetend () throws texception;
Public abstract Boolean Readbool () throws texception;
public abstract byte ReadByte () throws texception;
Public abstract short readI16 () throws texception;
public abstract int readI32 () throws texception;
Public abstract long readI64 () throws texception;
public abstract double readdouble () throws texception;
Public abstract String readString () throws texception; Public abstract Bytebuffer Readbinary () throws texception;
The first half is write-related functions, the latter part is the read-related function, the write user serializes, and read is used for deserialization.
As we all know, the data types in thrift are as follows:
/**
* Type Constants in the Thrift protocol.
*/Public
final class Ttype {public
static final byte STOP = 0;
public static final byte VOID = 1;
public static final byte BOOL = 2;
public static final byte byte = 3;
public static final Byte DOUBLE = 4;
public static final byte I16 = 6;
public static final byte I32 = 8;
public static final byte I64 = ten;
public static final Byte STRING = one;
public static final Byte STRUCT = n;
public static final byte MAP =;
public static final byte SET = +;
public static final byte LIST =;
public static final byte ENUM = +;
}
Correspondingly, there are related write/read functions in the Tprotocol class.
Let's take a closer look at how these functions are implemented in Tbinaryprotocol. detailed Tbinaryprotocol
Here is the main code for TBINARYPROTOCOL:
public void Writemessagebegin (Tmessage message) throws Texception {if (strictwrite_) {int version = Version_1 |
Message.type;
WRITEI32 (version);
WriteString (Message.name);
WriteI32 (MESSAGE.SEQID);
} else {writestring (message.name);
WriteByte (Message.type);
WriteI32 (MESSAGE.SEQID); }} public void Writemessageend () {} public void Writestructbegin (tstruct struct) {} public void Writestructend
() {} public void Writefieldbegin (Tfield field) throws Texception {writebyte (field.type);
WriteI16 (field.id);
} public void Writefieldend () {} public void Writefieldstop () throws Texception {writebyte (ttype.stop);
} public void Writemapbegin (TMap map) throws Texception {writebyte (map.keytype);
WriteByte (Map.valuetype);
WriteI32 (map.size); } public void Writemapend () {} public void Writelistbegin (TList list) throws Texception {WriteByte (List.elemtyp
e);
WriteI32 (list.size);} public void Writelistend () {} public void Writesetbegin (Tset set) throws Texception {writebyte (set.elemtype);
WriteI32 (set.size); } public void Writesetend () {} public void Writebool (Boolean B) throws texception {WriteByte (b?
(byte) 1: (byte) 0);
} public void WriteByte (Byte b) throws Texception {inouttemp[0] = b;
Trans_.write (inouttemp, 0, 1);
public void writeI16 (short i16) throws Texception {inouttemp[0] = (byte) (0xFF & (i16 >> 8));
INOUTTEMP[1] = (byte) (0xFF & (I16));
Trans_.write (inouttemp, 0, 2);
} public void writeI32 (int i32) throws Texception {inouttemp[0] = (byte) (0xFF & (i32 >> 24));
INOUTTEMP[1] = (byte) (0xFF & (i32 >> 16));
INOUTTEMP[2] = (byte) (0xFF & (I32 >> 8));
INOUTTEMP[3] = (byte) (0xFF & (I32));
Trans_.write (inouttemp, 0, 4); } public void writeI64 (long i64) throws Texception {inouttemp[0] = (byte) (0xFF & (i64 >>
56));
INOUTTEMP[1] = (byte) (0xFF & (i64 >> 48));
INOUTTEMP[2] = (byte) (0xFF & (i64 >> 40));
INOUTTEMP[3] = (byte) (0xFF & (i64 >> 32));
INOUTTEMP[4] = (byte) (0xFF & (i64 >> 24));
INOUTTEMP[5] = (byte) (0xFF & (i64 >> 16));
INOUTTEMP[6] = (byte) (0xFF & (i64 >> 8));
INOUTTEMP[7] = (byte) (0xFF & (i64));
Trans_.write (inouttemp, 0, 8);
} public void Writedouble (double dub) throws Texception {writeI64 (double.doubletolongbits (Dub));
The public void WriteString (String str) throws Texception {try {byte[] dat = str.getbytes ("UTF-8");
WriteI32 (dat.length);
Trans_.write (DAT, 0, dat.length);
} catch (Unsupportedencodingexception Uex) {throw new Texception ("JVM DOES not support UTF-8");
}} public void Writebinary (Bytebuffer bin) throws texception {int length = Bin.limit ()-bin.position ();
writeI32 (length); Trans_.write (Bin.array (), BiN.position () + bin.arrayoffset (), length);
}/** * Reading methods.
*/Public Tmessage Readmessagebegin () throws texception {int size = readI32 ();
if (Size < 0) {int version = size & Version_mask; if (version! = version_1) {throw new Tprotocolexception (Tprotocolexception.bad_version, "bad version in Readmessa
Gebegin ");
} return new Tmessage (ReadString (), (byte) (Size & 0x000000ff), readI32 ()); } else {if (Strictread_) {throw new Tprotocolexception (Tprotocolexception.bad_version, "Missing VERSION in
Readmessagebegin, old client? ");
return new Tmessage (readstringbody (size), ReadByte (), readI32 ());
}} public void Readmessageend () {} public tstruct Readstructbegin () {return anonymous_struct;
} public void Readstructend () {} public Tfield Readfieldbegin () throws texception {byte type = ReadByte (); Short id = Type = = Ttype.stop?
0:readi16 (); return NEW Tfield ("", type, id); } public void Readfieldend () {} public TMap Readmapbegin () throws texception {TMap map = new TMap (ReadByte (), R
Eadbyte (), readI32 ());
Checkcontainerreadlength (map.size);
return map; } public void Readmapend () {} public TList Readlistbegin () throws texception {TList list = new TList (ReadByte ()
, readI32 ());
Checkcontainerreadlength (list.size);
return list; } public void Readlistend () {} public Tset Readsetbegin () throws Texception {Tset set = new Tset (ReadByte (), RE
AdI32 ());
Checkcontainerreadlength (set.size);
return set;
The public void Readsetend () {} public boolean Readbool () throws Texception {return (readbyte () = = 1); } public byte ReadByte () throws Texception {if (Trans_.getbytesremaininginbuffer () >= 1) {byte b = trans
_.getbuffer () [Trans_.getbufferposition ()];
Trans_.consumebuffer (1);
return b;
} readall (inouttemp, 0, 1); return inouttemp[0];
} public short readI16 () throws texception {byte[] buf = inouttemp;
int off = 0;
if (Trans_.getbytesremaininginbuffer () >= 2) {buf = Trans_.getbuffer ();
Off = Trans_.getbufferposition ();
Trans_.consumebuffer (2);
} else {ReadAll (inouttemp, 0, 2);
} return (short) (((Buf[off & 0xff) << 8) |
((Buf[off+1] & 0xff)));
} public int readI32 () throws texception {byte[] buf = inouttemp;
int off = 0;
if (Trans_.getbytesremaininginbuffer () >= 4) {buf = Trans_.getbuffer ();
Off = Trans_.getbufferposition ();
Trans_.consumebuffer (4);
} else {ReadAll (inouttemp, 0, 4);
} return ((Buf[off & 0xff) << 24) |
((Buf[off+1] & 0xff) << 16) |
((buf[off+2] & 0xff) << 8) |
((Buf[off+3] & 0xff));
} public long readI64 () throws texception {byte[] buf = inouttemp;
int off = 0; if (TranS_.getbytesremaininginbuffer () >= 8) {buf = Trans_.getbuffer ();
Off = Trans_.getbufferposition ();
Trans_.consumebuffer (8);
} else {ReadAll (inouttemp, 0, 8);
} return ((Long) (Buf[off] & 0xff) << 56) |
((Long) (Buf[off+1] & 0xff) << 48) |
((Long) (buf[off+2] & 0xff) << 40) |
((Long) (Buf[off+3] & 0xff) << 32) |
((Long) (Buf[off+4] & 0xff) << 24) |
((Long) (Buf[off+5] & 0xff) << 16) |
((Long) (Buf[off+6] & 0xff) << 8) |
((Long) (Buf[off+7] & 0xff));
} public double readdouble () throws Texception {return double.longbitstodouble (readI64 ());
} public String readString () throws texception {int size = readI32 ();
Checkstringreadlength (size); if (Trans_.getbytesremaininginbuffer () >= size) {try {string s = new String (Trans_.getbuffer (), Trans_.
Getbufferposition (), size, "UTF-8"); TrAns_.consumebuffer (size);
return s;
} catch (Unsupportedencodingexception e) {