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