r1460@opsdev009 (orig r77478): dreiss | 2008-01-11 12:59:12 -0800
[amiethrift.git] / lib / csharp / src / Protocol / TBinaryProtocol.cs
blob36f03d0e2438c5a05d93879d0e4bc55e449991f5
1 //
2 // TBinaryProtocol.cs
3 //
4 // Begin: Aug 19, 2007
5 // Authors:
6 // Todd Berman <tberman@imeem.com>
7 // Will Palmeri <will@imeem.com>
8 //
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
14 using System;
15 using System.Collections.Generic;
16 using System.Text;
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
34 /**
35 * Factory
37 public class Factory : TProtocolFactory {
39 protected bool strictRead_ = false;
40 protected bool strictWrite_ = true;
42 public Factory()
43 :this(false, 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_);
58 #endregion
60 public TBinaryProtocol(TTransport trans)
61 : this(trans, false, true)
65 public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
66 :base(trans)
68 strictRead_ = strictRead;
69 strictWrite_ = strictWrite;
72 #region Write Methods
74 public override void WriteMessageBegin(TMessage message)
76 if (strictWrite_)
78 uint version = VERSION_1 | (uint)(message.Type);
79 WriteI32((int)version);
80 WriteString(message.Name);
81 WriteI32(message.SeqID);
83 else
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);
106 WriteI16(field.ID);
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);
122 WriteI32(map.Count);
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);
142 WriteI32(set.Count);
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)
157 bout[0] = 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);
201 WriteI32(b.Length);
202 trans.Write(b, 0, b.Length);
205 #endregion
207 #region ReadMethods
209 public override TMessage ReadMessageBegin()
211 TMessage message = new TMessage();
212 int size = ReadI32();
213 if (size < 0)
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();
224 else
226 if (strictRead_)
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();
234 return message;
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();
260 return field;
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();
274 return map;
277 public override void ReadMapEnd()
281 public override TList ReadListBegin()
283 TList list = new TList();
284 list.ElementType = (TType)ReadByte();
285 list.Count = ReadI32();
287 return list;
290 public override void ReadListEnd()
294 public override TSet ReadSetBegin()
296 TSet set = new TSet();
297 set.ElementType = (TType)ReadByte();
298 set.Count = ReadI32();
300 return set;
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()
315 ReadAll(bin, 0, 1);
316 return bin[0];
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;
357 if (readLength_ < 0)
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);
384 #endregion