1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements. See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership. The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License. You may obtain a copy of the License at
9  *
10  *   http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied. See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  *
19  * Contains some contributions under the Thrift Software License.
20  * Please see doc/old-thrift-license.txt in the Thrift distribution for
21  * details.
22  */
23 
24 using System;
25 using System.Text;
26 using Thrift.Transport;
27 
28 namespace Thrift.Protocol
29 {
30     public class TBinaryProtocol : TProtocol
31     {
32         protected const uint VERSION_MASK = 0xffff0000;
33         protected const uint VERSION_1 = 0x80010000;
34 
35         protected bool strictRead_ = false;
36         protected bool strictWrite_ = true;
37 
38         #region BinaryProtocol Factory
39 
40         public class Factory : TProtocolFactory
41         {
42             protected bool strictRead_ = false;
43             protected bool strictWrite_ = true;
44 
Factory()45             public Factory()
46                 : this(false, true)
47             {
48             }
49 
Factory(bool strictRead, bool strictWrite)50             public Factory(bool strictRead, bool strictWrite)
51             {
52                 strictRead_ = strictRead;
53                 strictWrite_ = strictWrite;
54             }
55 
GetProtocol(TTransport trans)56             public TProtocol GetProtocol(TTransport trans)
57             {
58                 return new TBinaryProtocol(trans, strictRead_, strictWrite_);
59             }
60         }
61 
62         #endregion
63 
TBinaryProtocol(TTransport trans)64         public TBinaryProtocol(TTransport trans)
65             : this(trans, false, true)
66         {
67         }
68 
TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)69         public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
70             : base(trans)
71         {
72             strictRead_ = strictRead;
73             strictWrite_ = strictWrite;
74         }
75 
76         #region Write Methods
77 
WriteMessageBegin(TMessage message)78         public override void WriteMessageBegin(TMessage message)
79         {
80             if (strictWrite_)
81             {
82                 uint version = VERSION_1 | (uint)(message.Type);
83                 WriteI32((int)version);
84                 WriteString(message.Name);
85                 WriteI32(message.SeqID);
86             }
87             else
88             {
89                 WriteString(message.Name);
90                 WriteByte((sbyte)message.Type);
91                 WriteI32(message.SeqID);
92             }
93         }
94 
WriteMessageEnd()95         public override void WriteMessageEnd()
96         {
97         }
98 
WriteStructBegin(TStruct struc)99         public override void WriteStructBegin(TStruct struc)
100         {
101         }
102 
WriteStructEnd()103         public override void WriteStructEnd()
104         {
105         }
106 
WriteFieldBegin(TField field)107         public override void WriteFieldBegin(TField field)
108         {
109             WriteByte((sbyte)field.Type);
110             WriteI16(field.ID);
111         }
112 
WriteFieldEnd()113         public override void WriteFieldEnd()
114         {
115         }
116 
WriteFieldStop()117         public override void WriteFieldStop()
118         {
119             WriteByte((sbyte)TType.Stop);
120         }
121 
WriteMapBegin(TMap map)122         public override void WriteMapBegin(TMap map)
123         {
124             WriteByte((sbyte)map.KeyType);
125             WriteByte((sbyte)map.ValueType);
126             WriteI32(map.Count);
127         }
128 
WriteMapEnd()129         public override void WriteMapEnd()
130         {
131         }
132 
WriteListBegin(TList list)133         public override void WriteListBegin(TList list)
134         {
135             WriteByte((sbyte)list.ElementType);
136             WriteI32(list.Count);
137         }
138 
WriteListEnd()139         public override void WriteListEnd()
140         {
141         }
142 
WriteSetBegin(TSet set)143         public override void WriteSetBegin(TSet set)
144         {
145             WriteByte((sbyte)set.ElementType);
146             WriteI32(set.Count);
147         }
148 
WriteSetEnd()149         public override void WriteSetEnd()
150         {
151         }
152 
WriteBool(bool b)153         public override void WriteBool(bool b)
154         {
155             WriteByte(b ? (sbyte)1 : (sbyte)0);
156         }
157 
158         private byte[] bout = new byte[1];
WriteByte(sbyte b)159         public override void WriteByte(sbyte b)
160         {
161             bout[0] = (byte)b;
162             trans.Write(bout, 0, 1);
163         }
164 
165         private byte[] i16out = new byte[2];
WriteI16(short s)166         public override void WriteI16(short s)
167         {
168             i16out[0] = (byte)(0xff & (s >> 8));
169             i16out[1] = (byte)(0xff & s);
170             trans.Write(i16out, 0, 2);
171         }
172 
173         private byte[] i32out = new byte[4];
WriteI32(int i32)174         public override void WriteI32(int i32)
175         {
176             i32out[0] = (byte)(0xff & (i32 >> 24));
177             i32out[1] = (byte)(0xff & (i32 >> 16));
178             i32out[2] = (byte)(0xff & (i32 >> 8));
179             i32out[3] = (byte)(0xff & i32);
180             trans.Write(i32out, 0, 4);
181         }
182 
183         private byte[] i64out = new byte[8];
WriteI64(long i64)184         public override void WriteI64(long i64)
185         {
186             i64out[0] = (byte)(0xff & (i64 >> 56));
187             i64out[1] = (byte)(0xff & (i64 >> 48));
188             i64out[2] = (byte)(0xff & (i64 >> 40));
189             i64out[3] = (byte)(0xff & (i64 >> 32));
190             i64out[4] = (byte)(0xff & (i64 >> 24));
191             i64out[5] = (byte)(0xff & (i64 >> 16));
192             i64out[6] = (byte)(0xff & (i64 >> 8));
193             i64out[7] = (byte)(0xff & i64);
194             trans.Write(i64out, 0, 8);
195         }
196 
WriteDouble(double d)197         public override void WriteDouble(double d)
198         {
199 #if !SILVERLIGHT
200             WriteI64(BitConverter.DoubleToInt64Bits(d));
201 #else
202             var bytes = BitConverter.GetBytes(d);
203             WriteI64(BitConverter.ToInt64(bytes, 0));
204 #endif
205         }
206 
WriteBinary(byte[] b)207         public override void WriteBinary(byte[] b)
208         {
209             WriteI32(b.Length);
210             trans.Write(b, 0, b.Length);
211         }
212 
213         #endregion
214 
215         #region ReadMethods
216 
ReadMessageBegin()217         public override TMessage ReadMessageBegin()
218         {
219             TMessage message = new TMessage();
220             int size = ReadI32();
221             if (size < 0)
222             {
223                 uint version = (uint)size & VERSION_MASK;
224                 if (version != VERSION_1)
225                 {
226                     throw new TProtocolException(TProtocolException.BAD_VERSION, "Bad version in ReadMessageBegin: " + version);
227                 }
228                 message.Type = (TMessageType)(size & 0x000000ff);
229                 message.Name = ReadString();
230                 message.SeqID = ReadI32();
231             }
232             else
233             {
234                 if (strictRead_)
235                 {
236                     throw new TProtocolException(TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?");
237                 }
238                 message.Name = ReadStringBody(size);
239                 message.Type = (TMessageType)ReadByte();
240                 message.SeqID = ReadI32();
241             }
242             return message;
243         }
244 
ReadMessageEnd()245         public override void ReadMessageEnd()
246         {
247         }
248 
ReadStructBegin()249         public override TStruct ReadStructBegin()
250         {
251             return new TStruct();
252         }
253 
ReadStructEnd()254         public override void ReadStructEnd()
255         {
256         }
257 
ReadFieldBegin()258         public override TField ReadFieldBegin()
259         {
260             TField field = new TField();
261             field.Type = (TType)ReadByte();
262 
263             if (field.Type != TType.Stop)
264             {
265                 field.ID = ReadI16();
266             }
267 
268             return field;
269         }
270 
ReadFieldEnd()271         public override void ReadFieldEnd()
272         {
273         }
274 
ReadMapBegin()275         public override TMap ReadMapBegin()
276         {
277             TMap map = new TMap();
278             map.KeyType = (TType)ReadByte();
279             map.ValueType = (TType)ReadByte();
280             map.Count = ReadI32();
281 
282             return map;
283         }
284 
ReadMapEnd()285         public override void ReadMapEnd()
286         {
287         }
288 
ReadListBegin()289         public override TList ReadListBegin()
290         {
291             TList list = new TList();
292             list.ElementType = (TType)ReadByte();
293             list.Count = ReadI32();
294 
295             return list;
296         }
297 
ReadListEnd()298         public override void ReadListEnd()
299         {
300         }
301 
ReadSetBegin()302         public override TSet ReadSetBegin()
303         {
304             TSet set = new TSet();
305             set.ElementType = (TType)ReadByte();
306             set.Count = ReadI32();
307 
308             return set;
309         }
310 
ReadSetEnd()311         public override void ReadSetEnd()
312         {
313         }
314 
ReadBool()315         public override bool ReadBool()
316         {
317             return ReadByte() == 1;
318         }
319 
320         private byte[] bin = new byte[1];
ReadByte()321         public override sbyte ReadByte()
322         {
323             ReadAll(bin, 0, 1);
324             return (sbyte)bin[0];
325         }
326 
327         private byte[] i16in = new byte[2];
ReadI16()328         public override short ReadI16()
329         {
330             ReadAll(i16in, 0, 2);
331             return (short)(((i16in[0] & 0xff) << 8) | ((i16in[1] & 0xff)));
332         }
333 
334         private byte[] i32in = new byte[4];
ReadI32()335         public override int ReadI32()
336         {
337             ReadAll(i32in, 0, 4);
338             return (int)(((i32in[0] & 0xff) << 24) | ((i32in[1] & 0xff) << 16) | ((i32in[2] & 0xff) << 8) | ((i32in[3] & 0xff)));
339         }
340 
341 #pragma warning disable 675
342 
343         private byte[] i64in = new byte[8];
ReadI64()344         public override long ReadI64()
345         {
346             ReadAll(i64in, 0, 8);
347             unchecked
348             {
349                 return (long)(
350                     ((long)(i64in[0] & 0xff) << 56) |
351                     ((long)(i64in[1] & 0xff) << 48) |
352                     ((long)(i64in[2] & 0xff) << 40) |
353                     ((long)(i64in[3] & 0xff) << 32) |
354                     ((long)(i64in[4] & 0xff) << 24) |
355                     ((long)(i64in[5] & 0xff) << 16) |
356                     ((long)(i64in[6] & 0xff) << 8) |
357                     ((long)(i64in[7] & 0xff)));
358             }
359         }
360 
361 #pragma warning restore 675
362 
ReadDouble()363         public override double ReadDouble()
364         {
365 #if !SILVERLIGHT
366             return BitConverter.Int64BitsToDouble(ReadI64());
367 #else
368             var value = ReadI64();
369             var bytes = BitConverter.GetBytes(value);
370             return BitConverter.ToDouble(bytes, 0);
371 #endif
372         }
373 
ReadBinary()374         public override byte[] ReadBinary()
375         {
376             int size = ReadI32();
377             byte[] buf = new byte[size];
378             trans.ReadAll(buf, 0, size);
379             return buf;
380         }
ReadStringBody(int size)381         private string ReadStringBody(int size)
382         {
383             byte[] buf = new byte[size];
384             trans.ReadAll(buf, 0, size);
385             return Encoding.UTF8.GetString(buf, 0, buf.Length);
386         }
387 
ReadAll(byte[] buf, int off, int len)388         private int ReadAll(byte[] buf, int off, int len)
389         {
390             return trans.ReadAll(buf, off, len);
391         }
392 
393         #endregion
394     }
395 }
396