]> git.proxmox.com Git - ceph.git/blame - ceph/src/jaegertracing/thrift/lib/csharp/src/Protocol/TCompactProtocol.cs
buildsys: switch source download to quincy
[ceph.git] / ceph / src / jaegertracing / thrift / lib / csharp / src / Protocol / TCompactProtocol.cs
CommitLineData
f67539c2
TL
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
24using System;
25using System.Text;
26using Thrift.Transport;
27using System.Collections;
28using System.IO;
29using System.Collections.Generic;
30
31namespace Thrift.Protocol
32{
33 public class TCompactProtocol : TProtocol
34 {
35 private static TStruct ANONYMOUS_STRUCT = new TStruct("");
36 private static TField TSTOP = new TField("", TType.Stop, (short)0);
37
38 private static byte[] ttypeToCompactType = new byte[16];
39
40 private const byte PROTOCOL_ID = 0x82;
41 private const byte VERSION = 1;
42 private const byte VERSION_MASK = 0x1f; // 0001 1111
43 private const byte TYPE_MASK = 0xE0; // 1110 0000
44 private const byte TYPE_BITS = 0x07; // 0000 0111
45 private const int TYPE_SHIFT_AMOUNT = 5;
46
47 /// <summary>
48 /// All of the on-wire type codes.
49 /// </summary>
50 private static class Types
51 {
52 public const byte STOP = 0x00;
53 public const byte BOOLEAN_TRUE = 0x01;
54 public const byte BOOLEAN_FALSE = 0x02;
55 public const byte BYTE = 0x03;
56 public const byte I16 = 0x04;
57 public const byte I32 = 0x05;
58 public const byte I64 = 0x06;
59 public const byte DOUBLE = 0x07;
60 public const byte BINARY = 0x08;
61 public const byte LIST = 0x09;
62 public const byte SET = 0x0A;
63 public const byte MAP = 0x0B;
64 public const byte STRUCT = 0x0C;
65 }
66
67 /// <summary>
68 /// Used to keep track of the last field for the current and previous structs,
69 /// so we can do the delta stuff.
70 /// </summary>
71 private Stack<short> lastField_ = new Stack<short>(15);
72
73 private short lastFieldId_ = 0;
74
75 /// <summary>
76 /// If we encounter a boolean field begin, save the TField here so it can
77 /// have the value incorporated.
78 /// </summary>
79 private Nullable<TField> booleanField_;
80
81 /// <summary>
82 /// If we Read a field header, and it's a boolean field, save the boolean
83 /// value here so that ReadBool can use it.
84 /// </summary>
85 private Nullable<Boolean> boolValue_;
86
87
88 #region CompactProtocol Factory
89
90 public class Factory : TProtocolFactory
91 {
92 public Factory() { }
93
94 public TProtocol GetProtocol(TTransport trans)
95 {
96 return new TCompactProtocol(trans);
97 }
98 }
99
100 #endregion
101
102 public TCompactProtocol(TTransport trans)
103 : base(trans)
104 {
105 ttypeToCompactType[(int)TType.Stop] = Types.STOP;
106 ttypeToCompactType[(int)TType.Bool] = Types.BOOLEAN_TRUE;
107 ttypeToCompactType[(int)TType.Byte] = Types.BYTE;
108 ttypeToCompactType[(int)TType.I16] = Types.I16;
109 ttypeToCompactType[(int)TType.I32] = Types.I32;
110 ttypeToCompactType[(int)TType.I64] = Types.I64;
111 ttypeToCompactType[(int)TType.Double] = Types.DOUBLE;
112 ttypeToCompactType[(int)TType.String] = Types.BINARY;
113 ttypeToCompactType[(int)TType.List] = Types.LIST;
114 ttypeToCompactType[(int)TType.Set] = Types.SET;
115 ttypeToCompactType[(int)TType.Map] = Types.MAP;
116 ttypeToCompactType[(int)TType.Struct] = Types.STRUCT;
117 }
118
119 public void reset()
120 {
121 lastField_.Clear();
122 lastFieldId_ = 0;
123 }
124
125 #region Write Methods
126
127 /// <summary>
128 /// Writes a byte without any possibility of all that field header nonsense.
129 /// Used internally by other writing methods that know they need to Write a byte.
130 /// </summary>
131 private byte[] byteDirectBuffer = new byte[1];
132
133 private void WriteByteDirect(byte b)
134 {
135 byteDirectBuffer[0] = b;
136 trans.Write(byteDirectBuffer);
137 }
138
139 /// <summary>
140 /// Writes a byte without any possibility of all that field header nonsense.
141 /// </summary>
142 private void WriteByteDirect(int n)
143 {
144 WriteByteDirect((byte)n);
145 }
146
147 /// <summary>
148 /// Write an i32 as a varint. Results in 1-5 bytes on the wire.
149 /// TODO: make a permanent buffer like WriteVarint64?
150 /// </summary>
151 byte[] i32buf = new byte[5];
152
153 private void WriteVarint32(uint n)
154 {
155 int idx = 0;
156 while (true)
157 {
158 if ((n & ~0x7F) == 0)
159 {
160 i32buf[idx++] = (byte)n;
161 // WriteByteDirect((byte)n);
162 break;
163 // return;
164 }
165 else
166 {
167 i32buf[idx++] = (byte)((n & 0x7F) | 0x80);
168 // WriteByteDirect((byte)((n & 0x7F) | 0x80));
169 n >>= 7;
170 }
171 }
172 trans.Write(i32buf, 0, idx);
173 }
174
175 /// <summary>
176 /// Write a message header to the wire. Compact Protocol messages contain the
177 /// protocol version so we can migrate forwards in the future if need be.
178 /// </summary>
179 public override void WriteMessageBegin(TMessage message)
180 {
181 WriteByteDirect(PROTOCOL_ID);
182 WriteByteDirect((byte)((VERSION & VERSION_MASK) | ((((uint)message.Type) << TYPE_SHIFT_AMOUNT) & TYPE_MASK)));
183 WriteVarint32((uint)message.SeqID);
184 WriteString(message.Name);
185 }
186
187 /// <summary>
188 /// Write a struct begin. This doesn't actually put anything on the wire. We
189 /// use it as an opportunity to put special placeholder markers on the field
190 /// stack so we can get the field id deltas correct.
191 /// </summary>
192 public override void WriteStructBegin(TStruct strct)
193 {
194 lastField_.Push(lastFieldId_);
195 lastFieldId_ = 0;
196 }
197
198 /// <summary>
199 /// Write a struct end. This doesn't actually put anything on the wire. We use
200 /// this as an opportunity to pop the last field from the current struct off
201 /// of the field stack.
202 /// </summary>
203 public override void WriteStructEnd()
204 {
205 lastFieldId_ = lastField_.Pop();
206 }
207
208 /// <summary>
209 /// Write a field header containing the field id and field type. If the
210 /// difference between the current field id and the last one is small (&lt; 15),
211 /// then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
212 /// field id will follow the type header as a zigzag varint.
213 /// </summary>
214 public override void WriteFieldBegin(TField field)
215 {
216 if (field.Type == TType.Bool)
217 {
218 // we want to possibly include the value, so we'll wait.
219 booleanField_ = field;
220 }
221 else
222 {
223 WriteFieldBeginInternal(field, 0xFF);
224 }
225 }
226
227 /// <summary>
228 /// The workhorse of WriteFieldBegin. It has the option of doing a
229 /// 'type override' of the type header. This is used specifically in the
230 /// boolean field case.
231 /// </summary>
232 private void WriteFieldBeginInternal(TField field, byte typeOverride)
233 {
234 // short lastField = lastField_.Pop();
235
236 // if there's a type override, use that.
237 byte typeToWrite = typeOverride == 0xFF ? getCompactType(field.Type) : typeOverride;
238
239 // check if we can use delta encoding for the field id
240 if (field.ID > lastFieldId_ && field.ID - lastFieldId_ <= 15)
241 {
242 // Write them together
243 WriteByteDirect((field.ID - lastFieldId_) << 4 | typeToWrite);
244 }
245 else
246 {
247 // Write them separate
248 WriteByteDirect(typeToWrite);
249 WriteI16(field.ID);
250 }
251
252 lastFieldId_ = field.ID;
253 // lastField_.push(field.id);
254 }
255
256 /// <summary>
257 /// Write the STOP symbol so we know there are no more fields in this struct.
258 /// </summary>
259 public override void WriteFieldStop()
260 {
261 WriteByteDirect(Types.STOP);
262 }
263
264 /// <summary>
265 /// Write a map header. If the map is empty, omit the key and value type
266 /// headers, as we don't need any additional information to skip it.
267 /// </summary>
268 public override void WriteMapBegin(TMap map)
269 {
270 if (map.Count == 0)
271 {
272 WriteByteDirect(0);
273 }
274 else
275 {
276 WriteVarint32((uint)map.Count);
277 WriteByteDirect(getCompactType(map.KeyType) << 4 | getCompactType(map.ValueType));
278 }
279 }
280
281 /// <summary>
282 /// Write a list header.
283 /// </summary>
284 public override void WriteListBegin(TList list)
285 {
286 WriteCollectionBegin(list.ElementType, list.Count);
287 }
288
289 /// <summary>
290 /// Write a set header.
291 /// </summary>
292 public override void WriteSetBegin(TSet set)
293 {
294 WriteCollectionBegin(set.ElementType, set.Count);
295 }
296
297 /// <summary>
298 /// Write a boolean value. Potentially, this could be a boolean field, in
299 /// which case the field header info isn't written yet. If so, decide what the
300 /// right type header is for the value and then Write the field header.
301 /// Otherwise, Write a single byte.
302 /// </summary>
303 public override void WriteBool(Boolean b)
304 {
305 if (booleanField_ != null)
306 {
307 // we haven't written the field header yet
308 WriteFieldBeginInternal(booleanField_.Value, b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
309 booleanField_ = null;
310 }
311 else
312 {
313 // we're not part of a field, so just Write the value.
314 WriteByteDirect(b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE);
315 }
316 }
317
318 /// <summary>
319 /// Write a byte. Nothing to see here!
320 /// </summary>
321 public override void WriteByte(sbyte b)
322 {
323 WriteByteDirect((byte)b);
324 }
325
326 /// <summary>
327 /// Write an I16 as a zigzag varint.
328 /// </summary>
329 public override void WriteI16(short i16)
330 {
331 WriteVarint32(intToZigZag(i16));
332 }
333
334 /// <summary>
335 /// Write an i32 as a zigzag varint.
336 /// </summary>
337 public override void WriteI32(int i32)
338 {
339 WriteVarint32(intToZigZag(i32));
340 }
341
342 /// <summary>
343 /// Write an i64 as a zigzag varint.
344 /// </summary>
345 public override void WriteI64(long i64)
346 {
347 WriteVarint64(longToZigzag(i64));
348 }
349
350 /// <summary>
351 /// Write a double to the wire as 8 bytes.
352 /// </summary>
353 public override void WriteDouble(double dub)
354 {
355 byte[] data = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 };
356 fixedLongToBytes(BitConverter.DoubleToInt64Bits(dub), data, 0);
357 trans.Write(data);
358 }
359
360 /// <summary>
361 /// Write a string to the wire with a varint size preceding.
362 /// </summary>
363 public override void WriteString(string str)
364 {
365 byte[] bytes = UTF8Encoding.UTF8.GetBytes(str);
366 WriteBinary(bytes, 0, bytes.Length);
367 }
368
369 /// <summary>
370 /// Write a byte array, using a varint for the size.
371 /// </summary>
372 public override void WriteBinary(byte[] bin)
373 {
374 WriteBinary(bin, 0, bin.Length);
375 }
376
377 private void WriteBinary(byte[] buf, int offset, int length)
378 {
379 WriteVarint32((uint)length);
380 trans.Write(buf, offset, length);
381 }
382
383 //
384 // These methods are called by structs, but don't actually have any wire
385 // output or purpose.
386 //
387
388 public override void WriteMessageEnd() { }
389 public override void WriteMapEnd() { }
390 public override void WriteListEnd() { }
391 public override void WriteSetEnd() { }
392 public override void WriteFieldEnd() { }
393
394 //
395 // Internal writing methods
396 //
397
398 /// <summary>
399 /// Abstract method for writing the start of lists and sets. List and sets on
400 /// the wire differ only by the type indicator.
401 /// </summary>
402 protected void WriteCollectionBegin(TType elemType, int size)
403 {
404 if (size <= 14)
405 {
406 WriteByteDirect(size << 4 | getCompactType(elemType));
407 }
408 else
409 {
410 WriteByteDirect(0xf0 | getCompactType(elemType));
411 WriteVarint32((uint)size);
412 }
413 }
414
415 /// <summary>
416 /// Write an i64 as a varint. Results in 1-10 bytes on the wire.
417 /// </summary>
418 byte[] varint64out = new byte[10];
419 private void WriteVarint64(ulong n)
420 {
421 int idx = 0;
422 while (true)
423 {
424 if ((n & ~(ulong)0x7FL) == 0)
425 {
426 varint64out[idx++] = (byte)n;
427 break;
428 }
429 else
430 {
431 varint64out[idx++] = ((byte)((n & 0x7F) | 0x80));
432 n >>= 7;
433 }
434 }
435 trans.Write(varint64out, 0, idx);
436 }
437
438 /// <summary>
439 /// Convert l into a zigzag long. This allows negative numbers to be
440 /// represented compactly as a varint.
441 /// </summary>
442 private ulong longToZigzag(long n)
443 {
444 return (ulong)(n << 1) ^ (ulong)(n >> 63);
445 }
446
447 /// <summary>
448 /// Convert n into a zigzag int. This allows negative numbers to be
449 /// represented compactly as a varint.
450 /// </summary>
451 private uint intToZigZag(int n)
452 {
453 return (uint)(n << 1) ^ (uint)(n >> 31);
454 }
455
456 /// <summary>
457 /// Convert a long into little-endian bytes in buf starting at off and going
458 /// until off+7.
459 /// </summary>
460 private void fixedLongToBytes(long n, byte[] buf, int off)
461 {
462 buf[off + 0] = (byte)(n & 0xff);
463 buf[off + 1] = (byte)((n >> 8) & 0xff);
464 buf[off + 2] = (byte)((n >> 16) & 0xff);
465 buf[off + 3] = (byte)((n >> 24) & 0xff);
466 buf[off + 4] = (byte)((n >> 32) & 0xff);
467 buf[off + 5] = (byte)((n >> 40) & 0xff);
468 buf[off + 6] = (byte)((n >> 48) & 0xff);
469 buf[off + 7] = (byte)((n >> 56) & 0xff);
470 }
471
472 #endregion
473
474 #region ReadMethods
475
476 /// <summary>
477 /// Read a message header.
478 /// </summary>
479 public override TMessage ReadMessageBegin()
480 {
481 byte protocolId = (byte)ReadByte();
482 if (protocolId != PROTOCOL_ID)
483 {
484 throw new TProtocolException("Expected protocol id " + PROTOCOL_ID.ToString("X") + " but got " + protocolId.ToString("X"));
485 }
486 byte versionAndType = (byte)ReadByte();
487 byte version = (byte)(versionAndType & VERSION_MASK);
488 if (version != VERSION)
489 {
490 throw new TProtocolException("Expected version " + VERSION + " but got " + version);
491 }
492 byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & TYPE_BITS);
493 int seqid = (int)ReadVarint32();
494 string messageName = ReadString();
495 return new TMessage(messageName, (TMessageType)type, seqid);
496 }
497
498 /// <summary>
499 /// Read a struct begin. There's nothing on the wire for this, but it is our
500 /// opportunity to push a new struct begin marker onto the field stack.
501 /// </summary>
502 public override TStruct ReadStructBegin()
503 {
504 lastField_.Push(lastFieldId_);
505 lastFieldId_ = 0;
506 return ANONYMOUS_STRUCT;
507 }
508
509 /// <summary>
510 /// Doesn't actually consume any wire data, just removes the last field for
511 /// this struct from the field stack.
512 /// </summary>
513 public override void ReadStructEnd()
514 {
515 // consume the last field we Read off the wire.
516 lastFieldId_ = lastField_.Pop();
517 }
518
519 /// <summary>
520 /// Read a field header off the wire.
521 /// </summary>
522 public override TField ReadFieldBegin()
523 {
524 byte type = (byte)ReadByte();
525
526 // if it's a stop, then we can return immediately, as the struct is over.
527 if (type == Types.STOP)
528 {
529 return TSTOP;
530 }
531
532 short fieldId;
533
534 // mask off the 4 MSB of the type header. it could contain a field id delta.
535 short modifier = (short)((type & 0xf0) >> 4);
536 if (modifier == 0)
537 {
538 // not a delta. look ahead for the zigzag varint field id.
539 fieldId = ReadI16();
540 }
541 else
542 {
543 // has a delta. add the delta to the last Read field id.
544 fieldId = (short)(lastFieldId_ + modifier);
545 }
546
547 TField field = new TField("", getTType((byte)(type & 0x0f)), fieldId);
548
549 // if this happens to be a boolean field, the value is encoded in the type
550 if (isBoolType(type))
551 {
552 // save the boolean value in a special instance variable.
553 boolValue_ = (byte)(type & 0x0f) == Types.BOOLEAN_TRUE ? true : false;
554 }
555
556 // push the new field onto the field stack so we can keep the deltas going.
557 lastFieldId_ = field.ID;
558 return field;
559 }
560
561 /// <summary>
562 /// Read a map header off the wire. If the size is zero, skip Reading the key
563 /// and value type. This means that 0-length maps will yield TMaps without the
564 /// "correct" types.
565 /// </summary>
566 public override TMap ReadMapBegin()
567 {
568 int size = (int)ReadVarint32();
569 byte keyAndValueType = size == 0 ? (byte)0 : (byte)ReadByte();
570 return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size);
571 }
572
573 /// <summary>
574 /// Read a list header off the wire. If the list size is 0-14, the size will
575 /// be packed into the element type header. If it's a longer list, the 4 MSB
576 /// of the element type header will be 0xF, and a varint will follow with the
577 /// true size.
578 /// </summary>
579 public override TList ReadListBegin()
580 {
581 byte size_and_type = (byte)ReadByte();
582 int size = (size_and_type >> 4) & 0x0f;
583 if (size == 15)
584 {
585 size = (int)ReadVarint32();
586 }
587 TType type = getTType(size_and_type);
588 return new TList(type, size);
589 }
590
591 /// <summary>
592 /// Read a set header off the wire. If the set size is 0-14, the size will
593 /// be packed into the element type header. If it's a longer set, the 4 MSB
594 /// of the element type header will be 0xF, and a varint will follow with the
595 /// true size.
596 /// </summary>
597 public override TSet ReadSetBegin()
598 {
599 return new TSet(ReadListBegin());
600 }
601
602 /// <summary>
603 /// Read a boolean off the wire. If this is a boolean field, the value should
604 /// already have been Read during ReadFieldBegin, so we'll just consume the
605 /// pre-stored value. Otherwise, Read a byte.
606 /// </summary>
607 public override Boolean ReadBool()
608 {
609 if (boolValue_ != null)
610 {
611 bool result = boolValue_.Value;
612 boolValue_ = null;
613 return result;
614 }
615 return ReadByte() == Types.BOOLEAN_TRUE;
616 }
617
618 byte[] byteRawBuf = new byte[1];
619 /// <summary>
620 /// Read a single byte off the wire. Nothing interesting here.
621 /// </summary>
622 public override sbyte ReadByte()
623 {
624 trans.ReadAll(byteRawBuf, 0, 1);
625 return (sbyte)byteRawBuf[0];
626 }
627
628 /// <summary>
629 /// Read an i16 from the wire as a zigzag varint.
630 /// </summary>
631 public override short ReadI16()
632 {
633 return (short)zigzagToInt(ReadVarint32());
634 }
635
636 /// <summary>
637 /// Read an i32 from the wire as a zigzag varint.
638 /// </summary>
639 public override int ReadI32()
640 {
641 return zigzagToInt(ReadVarint32());
642 }
643
644 /// <summary>
645 /// Read an i64 from the wire as a zigzag varint.
646 /// </summary>
647 public override long ReadI64()
648 {
649 return zigzagToLong(ReadVarint64());
650 }
651
652 /// <summary>
653 /// No magic here - just Read a double off the wire.
654 /// </summary>
655 public override double ReadDouble()
656 {
657 byte[] longBits = new byte[8];
658 trans.ReadAll(longBits, 0, 8);
659 return BitConverter.Int64BitsToDouble(bytesToLong(longBits));
660 }
661
662 /// <summary>
663 /// Reads a byte[] (via ReadBinary), and then UTF-8 decodes it.
664 /// </summary>
665 public override string ReadString()
666 {
667 int length = (int)ReadVarint32();
668
669 if (length == 0)
670 {
671 return "";
672 }
673
674 return Encoding.UTF8.GetString(ReadBinary(length));
675 }
676
677 /// <summary>
678 /// Read a byte[] from the wire.
679 /// </summary>
680 public override byte[] ReadBinary()
681 {
682 int length = (int)ReadVarint32();
683 if (length == 0) return new byte[0];
684
685 byte[] buf = new byte[length];
686 trans.ReadAll(buf, 0, length);
687 return buf;
688 }
689
690 /// <summary>
691 /// Read a byte[] of a known length from the wire.
692 /// </summary>
693 private byte[] ReadBinary(int length)
694 {
695 if (length == 0) return new byte[0];
696
697 byte[] buf = new byte[length];
698 trans.ReadAll(buf, 0, length);
699 return buf;
700 }
701
702 //
703 // These methods are here for the struct to call, but don't have any wire
704 // encoding.
705 //
706 public override void ReadMessageEnd() { }
707 public override void ReadFieldEnd() { }
708 public override void ReadMapEnd() { }
709 public override void ReadListEnd() { }
710 public override void ReadSetEnd() { }
711
712 //
713 // Internal Reading methods
714 //
715
716 /// <summary>
717 /// Read an i32 from the wire as a varint. The MSB of each byte is set
718 /// if there is another byte to follow. This can Read up to 5 bytes.
719 /// </summary>
720 private uint ReadVarint32()
721 {
722 uint result = 0;
723 int shift = 0;
724 while (true)
725 {
726 byte b = (byte)ReadByte();
727 result |= (uint)(b & 0x7f) << shift;
728 if ((b & 0x80) != 0x80) break;
729 shift += 7;
730 }
731 return result;
732 }
733
734 /// <summary>
735 /// Read an i64 from the wire as a proper varint. The MSB of each byte is set
736 /// if there is another byte to follow. This can Read up to 10 bytes.
737 /// </summary>
738 private ulong ReadVarint64()
739 {
740 int shift = 0;
741 ulong result = 0;
742 while (true)
743 {
744 byte b = (byte)ReadByte();
745 result |= (ulong)(b & 0x7f) << shift;
746 if ((b & 0x80) != 0x80) break;
747 shift += 7;
748 }
749
750 return result;
751 }
752
753 #endregion
754
755 //
756 // encoding helpers
757 //
758
759 /// <summary>
760 /// Convert from zigzag int to int.
761 /// </summary>
762 private int zigzagToInt(uint n)
763 {
764 return (int)(n >> 1) ^ (-(int)(n & 1));
765 }
766
767 /// <summary>
768 /// Convert from zigzag long to long.
769 /// </summary>
770 private long zigzagToLong(ulong n)
771 {
772 return (long)(n >> 1) ^ (-(long)(n & 1));
773 }
774
775 /// <summary>
776 /// Note that it's important that the mask bytes are long literals,
777 /// otherwise they'll default to ints, and when you shift an int left 56 bits,
778 /// you just get a messed up int.
779 /// </summary>
780 private long bytesToLong(byte[] bytes)
781 {
782 return
783 ((bytes[7] & 0xffL) << 56) |
784 ((bytes[6] & 0xffL) << 48) |
785 ((bytes[5] & 0xffL) << 40) |
786 ((bytes[4] & 0xffL) << 32) |
787 ((bytes[3] & 0xffL) << 24) |
788 ((bytes[2] & 0xffL) << 16) |
789 ((bytes[1] & 0xffL) << 8) |
790 ((bytes[0] & 0xffL));
791 }
792
793 //
794 // type testing and converting
795 //
796
797 private Boolean isBoolType(byte b)
798 {
799 int lowerNibble = b & 0x0f;
800 return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE;
801 }
802
803 /// <summary>
804 /// Given a TCompactProtocol.Types constant, convert it to its corresponding
805 /// TType value.
806 /// </summary>
807 private TType getTType(byte type)
808 {
809 switch ((byte)(type & 0x0f))
810 {
811 case Types.STOP:
812 return TType.Stop;
813 case Types.BOOLEAN_FALSE:
814 case Types.BOOLEAN_TRUE:
815 return TType.Bool;
816 case Types.BYTE:
817 return TType.Byte;
818 case Types.I16:
819 return TType.I16;
820 case Types.I32:
821 return TType.I32;
822 case Types.I64:
823 return TType.I64;
824 case Types.DOUBLE:
825 return TType.Double;
826 case Types.BINARY:
827 return TType.String;
828 case Types.LIST:
829 return TType.List;
830 case Types.SET:
831 return TType.Set;
832 case Types.MAP:
833 return TType.Map;
834 case Types.STRUCT:
835 return TType.Struct;
836 default:
837 throw new TProtocolException("don't know what type: " + (byte)(type & 0x0f));
838 }
839 }
840
841 /// <summary>
842 /// Given a TType value, find the appropriate TCompactProtocol.Types constant.
843 /// </summary>
844 private byte getCompactType(TType ttype)
845 {
846 return ttypeToCompactType[(int)ttype];
847 }
848 }
849}