6 // Todd Berman <tberman@imeem.com>
7 // Will Palmeri <will@imeem.com>
9 // Distributed under the Thrift Software License
11 // See accompanying file LICENSE or visit the Thrift site at:
12 // http://developers.facebook.com/thrift/using
15 using System
.Collections
.Generic
;
17 using Thrift
.Transport
;
19 namespace Thrift
.Protocol
21 public class TBinaryProtocol
: TProtocol
23 protected const uint VERSION_MASK
= 0xffff0000;
24 protected const uint VERSION_1
= 0x80010000;
26 protected bool strictRead_
= false;
27 protected bool strictWrite_
= true;
29 protected int readLength_
;
30 protected bool checkReadLength_
= false;
33 #region BinaryProtocol Factory
37 public class Factory
: TProtocolFactory
{
39 protected bool strictRead_
= false;
40 protected bool strictWrite_
= true;
47 public Factory(bool strictRead
, bool strictWrite
)
49 strictRead_
= strictRead
;
50 strictWrite_
= strictWrite
;
53 public TProtocol
GetProtocol(TTransport trans
) {
54 return new TBinaryProtocol(trans
, strictRead_
, strictWrite_
);
60 public TBinaryProtocol(TTransport trans
)
61 : this(trans
, false, true)
65 public TBinaryProtocol(TTransport trans
, bool strictRead
, bool strictWrite
)
68 strictRead_
= strictRead
;
69 strictWrite_
= strictWrite
;
74 public override void WriteMessageBegin(TMessage message
)
78 uint version
= VERSION_1
| (uint)(message
.Type
);
79 WriteI32((int)version
);
80 WriteString(message
.Name
);
81 WriteI32(message
.SeqID
);
85 WriteString(message
.Name
);
86 WriteByte((byte)message
.Type
);
87 WriteI32(message
.SeqID
);
91 public override void WriteMessageEnd()
95 public override void WriteStructBegin(TStruct struc
)
99 public override void WriteStructEnd()
103 public override void WriteFieldBegin(TField field
)
105 WriteByte((byte)field
.Type
);
109 public override void WriteFieldEnd()
113 public override void WriteFieldStop()
115 WriteByte((byte)TType
.Stop
);
118 public override void WriteMapBegin(TMap map
)
120 WriteByte((byte)map
.KeyType
);
121 WriteByte((byte)map
.ValueType
);
125 public override void WriteMapEnd()
129 public override void WriteListBegin(TList list
)
131 WriteByte((byte)list
.ElementType
);
132 WriteI32(list
.Count
);
135 public override void WriteListEnd()
139 public override void WriteSetBegin(TSet
set)
141 WriteByte((byte)set.ElementType
);
145 public override void WriteSetEnd()
149 public override void WriteBool(bool b
)
151 WriteByte(b
? (byte)1 : (byte)0);
154 private byte[] bout
= new byte[1];
155 public override void WriteByte(byte b
)
158 trans
.Write(bout
, 0, 1);
161 private byte[] i16out
= new byte[2];
162 public override void WriteI16(short s
)
164 i16out
[0] = (byte)(0xff & (s
>> 8));
165 i16out
[1] = (byte)(0xff & s
);
166 trans
.Write(i16out
, 0, 2);
169 private byte[] i32out
= new byte[4];
170 public override void WriteI32(int i32
)
172 i32out
[0] = (byte)(0xff & (i32
>> 24));
173 i32out
[1] = (byte)(0xff & (i32
>> 16));
174 i32out
[2] = (byte)(0xff & (i32
>> 8));
175 i32out
[3] = (byte)(0xff & i32
);
176 trans
.Write(i32out
, 0, 4);
179 private byte[] i64out
= new byte[8];
180 public override void WriteI64(long i64
)
182 i64out
[0] = (byte)(0xff & (i64
>> 56));
183 i64out
[1] = (byte)(0xff & (i64
>> 48));
184 i64out
[2] = (byte)(0xff & (i64
>> 40));
185 i64out
[3] = (byte)(0xff & (i64
>> 32));
186 i64out
[4] = (byte)(0xff & (i64
>> 24));
187 i64out
[5] = (byte)(0xff & (i64
>> 16));
188 i64out
[6] = (byte)(0xff & (i64
>> 8));
189 i64out
[7] = (byte)(0xff & i64
);
190 trans
.Write(i64out
, 0, 8);
193 public override void WriteDouble(double d
)
195 WriteI64(BitConverter
.DoubleToInt64Bits(d
));
198 public override void WriteString(string s
)
200 byte[] b
= Encoding
.UTF8
.GetBytes(s
);
202 trans
.Write(b
, 0, b
.Length
);
209 public override TMessage
ReadMessageBegin()
211 TMessage message
= new TMessage();
212 int size
= ReadI32();
215 uint version
= (uint)size
& VERSION_MASK
;
216 if (version
!= VERSION_1
)
218 throw new TProtocolException(TProtocolException
.BAD_VERSION
, "Bad version in ReadMessageBegin: " + version
);
220 message
.Type
= (TMessageType
)(size
& 0x000000ff);
221 message
.Name
= ReadString();
222 message
.SeqID
= ReadI32();
228 throw new TProtocolException(TProtocolException
.BAD_VERSION
, "Missing version in readMessageBegin, old client?");
230 message
.Name
= ReadStringBody(size
);
231 message
.Type
= (TMessageType
)ReadByte();
232 message
.SeqID
= ReadI32();
237 public override void ReadMessageEnd()
241 public override TStruct
ReadStructBegin()
243 return new TStruct();
246 public override void ReadStructEnd()
250 public override TField
ReadFieldBegin()
252 TField field
= new TField();
253 field
.Type
= (TType
)ReadByte();
255 if (field
.Type
!= TType
.Stop
)
257 field
.ID
= ReadI16();
263 public override void ReadFieldEnd()
267 public override TMap
ReadMapBegin()
269 TMap map
= new TMap();
270 map
.KeyType
= (TType
)ReadByte();
271 map
.ValueType
= (TType
)ReadByte();
272 map
.Count
= ReadI32();
277 public override void ReadMapEnd()
281 public override TList
ReadListBegin()
283 TList list
= new TList();
284 list
.ElementType
= (TType
)ReadByte();
285 list
.Count
= ReadI32();
290 public override void ReadListEnd()
294 public override TSet
ReadSetBegin()
296 TSet
set = new TSet();
297 set.ElementType
= (TType
)ReadByte();
298 set.Count
= ReadI32();
303 public override void ReadSetEnd()
307 public override bool ReadBool()
309 return ReadByte() == 1;
312 private byte[] bin
= new byte[1];
313 public override byte ReadByte()
319 private byte[] i16in
= new byte[2];
320 public override short ReadI16()
322 ReadAll(i16in
, 0, 2);
323 return (short)(((i16in
[0] & 0xff) << 8) | ((i16in
[1] & 0xff)));
326 private byte[] i32in
= new byte[4];
327 public override int ReadI32()
329 ReadAll(i32in
, 0, 4);
330 return (int)(((i32in
[0] & 0xff) << 24) | ((i32in
[1] & 0xff) << 16) | ((i32in
[2] & 0xff) << 8) | ((i32in
[3] & 0xff)));
333 private byte[] i64in
= new byte[8];
334 public override long ReadI64()
336 ReadAll(i64in
, 0, 8);
337 return (long)(((long)(i64in
[0] & 0xff) << 56) | ((long)(i64in
[1] & 0xff) << 48) | ((long)(i64in
[2] & 0xff) << 40) | ((long)(i64in
[3] & 0xff) << 32) |
338 ((long)(i64in
[4] & 0xff) << 24) | ((long)(i64in
[5] & 0xff) << 16) | ((long)(i64in
[6] & 0xff) << 8) | ((long)(i64in
[7] & 0xff)));
341 public override double ReadDouble()
343 return BitConverter
.Int64BitsToDouble(ReadI64());
346 public void SetReadLength(int readLength
)
348 readLength_
= readLength
;
349 checkReadLength_
= true;
352 protected void CheckReadLength(int length
)
354 if (checkReadLength_
)
356 readLength_
-= length
;
359 throw new Exception("Message length exceeded: " + length
);
364 public override string ReadString()
366 int size
= ReadI32();
367 return ReadStringBody(size
);
370 public string ReadStringBody(int size
)
372 CheckReadLength(size
);
373 byte[] buf
= new byte[size
];
374 trans
.ReadAll(buf
, 0, size
);
375 return Encoding
.UTF8
.GetString(buf
);
378 private int ReadAll(byte[] buf
, int off
, int len
)
380 CheckReadLength(len
);
381 return trans
.ReadAll(buf
, off
, len
);