Subversion Repositories SmartDukaan

Rev

Rev 30 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
30 ashish 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
		protected int readLength_;
39
		protected bool checkReadLength_ = false;
40
 
41
 
42
		#region BinaryProtocol Factory
43
		 /**
44
		  * Factory
45
		  */
46
		  public class Factory : TProtocolFactory {
47
 
48
			  protected bool strictRead_ = false;
49
			  protected bool strictWrite_ = true;
50
 
51
			  public Factory()
52
				  :this(false, true)
53
			  {
54
			  }
55
 
56
			  public Factory(bool strictRead, bool strictWrite)
57
			  {
58
				  strictRead_ = strictRead;
59
				  strictWrite_ = strictWrite;
60
			  }
61
 
62
			public TProtocol GetProtocol(TTransport trans) {
63
			  return new TBinaryProtocol(trans, strictRead_, strictWrite_);
64
			}
65
		  }
66
 
67
		#endregion
68
 
69
		public TBinaryProtocol(TTransport trans)
70
			: this(trans, false, true)
71
		{
72
		}
73
 
74
		public TBinaryProtocol(TTransport trans, bool strictRead, bool strictWrite)
75
			:base(trans)
76
		{
77
			strictRead_ = strictRead;
78
			strictWrite_ = strictWrite;
79
		}
80
 
81
		#region Write Methods
82
 
83
		public override void WriteMessageBegin(TMessage message)
84
		{
85
			if (strictWrite_)
86
			{
87
				uint version = VERSION_1 | (uint)(message.Type);
88
				WriteI32((int)version);
89
				WriteString(message.Name);
90
				WriteI32(message.SeqID);
91
			}
92
			else
93
			{
94
				WriteString(message.Name);
95
				WriteByte((byte)message.Type);
96
				WriteI32(message.SeqID);
97
			}
98
		}
99
 
100
		public override void WriteMessageEnd()
101
		{
102
		}
103
 
104
		public override void WriteStructBegin(TStruct struc)
105
		{
106
		}
107
 
108
		public override void WriteStructEnd()
109
		{
110
		}
111
 
112
		public override void WriteFieldBegin(TField field)
113
		{
114
			WriteByte((byte)field.Type);
115
			WriteI16(field.ID);
116
		}
117
 
118
		public override void WriteFieldEnd()
119
		{
120
		}
121
 
122
		public override void WriteFieldStop()
123
		{
124
			WriteByte((byte)TType.Stop);
125
		}
126
 
127
		public override void WriteMapBegin(TMap map)
128
		{
129
			WriteByte((byte)map.KeyType);
130
			WriteByte((byte)map.ValueType);
131
			WriteI32(map.Count);
132
		}
133
 
134
		public override void WriteMapEnd()
135
		{
136
		}
137
 
138
		public override void WriteListBegin(TList list)
139
		{
140
			WriteByte((byte)list.ElementType);
141
			WriteI32(list.Count);
142
		}
143
 
144
		public override void WriteListEnd()
145
		{
146
		}
147
 
148
		public override void WriteSetBegin(TSet set)
149
		{
150
			WriteByte((byte)set.ElementType);
151
			WriteI32(set.Count);
152
		}
153
 
154
		public override void WriteSetEnd()
155
		{
156
		}
157
 
158
		public override void WriteBool(bool b)
159
		{
160
			WriteByte(b ? (byte)1 : (byte)0);
161
		}
162
 
163
		private byte[] bout = new byte[1];
164
		public override void WriteByte(byte b)
165
		{
166
			bout[0] = b;
167
			trans.Write(bout, 0, 1);
168
		}
169
 
170
		private byte[] i16out = new byte[2];
171
		public override void WriteI16(short s)
172
		{
173
			i16out[0] = (byte)(0xff & (s >> 8));
174
			i16out[1] = (byte)(0xff & s);
175
			trans.Write(i16out, 0, 2);
176
		}
177
 
178
		private byte[] i32out = new byte[4];
179
		public override void WriteI32(int i32)
180
		{
181
			i32out[0] = (byte)(0xff & (i32 >> 24));
182
			i32out[1] = (byte)(0xff & (i32 >> 16));
183
			i32out[2] = (byte)(0xff & (i32 >> 8));
184
			i32out[3] = (byte)(0xff & i32);
185
			trans.Write(i32out, 0, 4);
186
		}
187
 
188
		private byte[] i64out = new byte[8];
189
		public override void WriteI64(long i64)
190
		{
191
			i64out[0] = (byte)(0xff & (i64 >> 56));
192
			i64out[1] = (byte)(0xff & (i64 >> 48));
193
			i64out[2] = (byte)(0xff & (i64 >> 40));
194
			i64out[3] = (byte)(0xff & (i64 >> 32));
195
			i64out[4] = (byte)(0xff & (i64 >> 24));
196
			i64out[5] = (byte)(0xff & (i64 >> 16));
197
			i64out[6] = (byte)(0xff & (i64 >> 8));
198
			i64out[7] = (byte)(0xff & i64);
199
			trans.Write(i64out, 0, 8);
200
		}
201
 
202
		public override void WriteDouble(double d)
203
		{
204
			WriteI64(BitConverter.DoubleToInt64Bits(d));
205
		}
206
 
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
 
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
 
245
		public override void ReadMessageEnd()
246
		{
247
		}
248
 
249
		public override TStruct ReadStructBegin()
250
		{
251
			return new TStruct();
252
		}
253
 
254
		public override void ReadStructEnd()
255
		{
256
		}
257
 
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
 
271
		public override void ReadFieldEnd()
272
		{
273
		}
274
 
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
 
285
		public override void ReadMapEnd()
286
		{
287
		}
288
 
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
 
298
		public override void ReadListEnd()
299
		{
300
		}
301
 
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
 
311
		public override void ReadSetEnd()
312
		{
313
		}
314
 
315
		public override bool ReadBool()
316
		{
317
			return ReadByte() == 1;
318
		}
319
 
320
		private byte[] bin = new byte[1];
321
		public override byte ReadByte()
322
		{
323
			ReadAll(bin, 0, 1);
324
			return bin[0];
325
		}
326
 
327
		private byte[] i16in = new byte[2];
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];
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
		private byte[] i64in = new byte[8];
342
		public override long ReadI64()
343
		{
344
			ReadAll(i64in, 0, 8);
345
			return (long)(((long)(i64in[0] & 0xff) << 56) | ((long)(i64in[1] & 0xff) << 48) | ((long)(i64in[2] & 0xff) << 40) | ((long)(i64in[3] & 0xff) << 32) |
346
				((long)(i64in[4] & 0xff) << 24) | ((long)(i64in[5] & 0xff) << 16) | ((long)(i64in[6] & 0xff) << 8) | ((long)(i64in[7] & 0xff)));
347
		}
348
 
349
		public override double ReadDouble()
350
		{
351
			return BitConverter.Int64BitsToDouble(ReadI64());
352
		}
353
 
354
		public void SetReadLength(int readLength)
355
		{
356
			readLength_ = readLength;
357
			checkReadLength_ = true;
358
		}
359
 
360
		protected void CheckReadLength(int length)
361
		{
362
			if (checkReadLength_)
363
			{
364
				readLength_ -= length;
365
				if (readLength_ < 0)
366
				{
367
					throw new Exception("Message length exceeded: " + length);
368
				}
369
			}
370
		}
371
 
372
		public override byte[] ReadBinary()
373
		{
374
			int size = ReadI32();
375
			CheckReadLength(size);
376
			byte[] buf = new byte[size];
377
			trans.ReadAll(buf, 0, size);
378
			return buf;
379
		}
380
		private  string ReadStringBody(int size)
381
		{
382
			CheckReadLength(size);
383
			byte[] buf = new byte[size];
384
			trans.ReadAll(buf, 0, size);
385
			return Encoding.UTF8.GetString(buf);
386
		}
387
 
388
		private int ReadAll(byte[] buf, int off, int len)
389
		{
390
			CheckReadLength(len);
391
			return trans.ReadAll(buf, off, len);
392
		}
393
 
394
		#endregion
395
	}
396
}