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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
21 package org
.apache
.thrift
.protocol
;
23 import java
.io
.UnsupportedEncodingException
;
24 import java
.nio
.ByteBuffer
;
25 import java
.nio
.charset
.StandardCharsets
;
27 import org
.apache
.thrift
.TException
;
28 import org
.apache
.thrift
.transport
.TTransport
;
31 * TCompactProtocol2 is the Java implementation of the compact protocol specified
32 * in THRIFT-110. The fundamental approach to reducing the overhead of
33 * structures is a) use variable-length integers all over the place and b) make
34 * use of unused bits wherever possible. Your savings will obviously vary
35 * based on the specific makeup of your structs, but in general, the more
36 * fields, nested structures, short strings and collections, and low-value i32
37 * and i64 fields you have, the more benefit you'll see.
39 public class TCompactProtocol
extends TProtocol
{
40 private final static byte[] EMPTY_BYTES
= new byte[0];
41 private final static ByteBuffer EMPTY_BUFFER
= ByteBuffer
.wrap(EMPTY_BYTES
);
43 private final static long NO_LENGTH_LIMIT
= -1;
45 private final static TStruct ANONYMOUS_STRUCT
= new TStruct("");
46 private final static TField TSTOP
= new TField("", TType
.STOP
, (short)0);
48 private final static byte[] ttypeToCompactType
= new byte[16];
51 ttypeToCompactType
[TType
.STOP
] = TType
.STOP
;
52 ttypeToCompactType
[TType
.BOOL
] = Types
.BOOLEAN_TRUE
;
53 ttypeToCompactType
[TType
.BYTE
] = Types
.BYTE
;
54 ttypeToCompactType
[TType
.I16
] = Types
.I16
;
55 ttypeToCompactType
[TType
.I32
] = Types
.I32
;
56 ttypeToCompactType
[TType
.I64
] = Types
.I64
;
57 ttypeToCompactType
[TType
.DOUBLE
] = Types
.DOUBLE
;
58 ttypeToCompactType
[TType
.STRING
] = Types
.BINARY
;
59 ttypeToCompactType
[TType
.LIST
] = Types
.LIST
;
60 ttypeToCompactType
[TType
.SET
] = Types
.SET
;
61 ttypeToCompactType
[TType
.MAP
] = Types
.MAP
;
62 ttypeToCompactType
[TType
.STRUCT
] = Types
.STRUCT
;
66 * TProtocolFactory that produces TCompactProtocols.
68 public static class Factory
implements TProtocolFactory
{
69 private final long stringLengthLimit_
;
70 private final long containerLengthLimit_
;
73 this(NO_LENGTH_LIMIT
, NO_LENGTH_LIMIT
);
76 public Factory(long stringLengthLimit
) {
77 this(stringLengthLimit
, NO_LENGTH_LIMIT
);
80 public Factory(long stringLengthLimit
, long containerLengthLimit
) {
81 this.containerLengthLimit_
= containerLengthLimit
;
82 this.stringLengthLimit_
= stringLengthLimit
;
85 public TProtocol
getProtocol(TTransport trans
) {
86 return new TCompactProtocol(trans
, stringLengthLimit_
, containerLengthLimit_
);
90 private static final byte PROTOCOL_ID
= (byte)0x82;
91 private static final byte VERSION
= 1;
92 private static final byte VERSION_MASK
= 0x1f; // 0001 1111
93 private static final byte TYPE_MASK
= (byte)0xE0; // 1110 0000
94 private static final byte TYPE_BITS
= 0x07; // 0000 0111
95 private static final int TYPE_SHIFT_AMOUNT
= 5;
98 * All of the on-wire type codes.
100 private static class Types
{
101 public static final byte BOOLEAN_TRUE
= 0x01;
102 public static final byte BOOLEAN_FALSE
= 0x02;
103 public static final byte BYTE
= 0x03;
104 public static final byte I16
= 0x04;
105 public static final byte I32
= 0x05;
106 public static final byte I64
= 0x06;
107 public static final byte DOUBLE
= 0x07;
108 public static final byte BINARY
= 0x08;
109 public static final byte LIST
= 0x09;
110 public static final byte SET
= 0x0A;
111 public static final byte MAP
= 0x0B;
112 public static final byte STRUCT
= 0x0C;
116 * Used to keep track of the last field for the current and previous structs,
117 * so we can do the delta stuff.
119 private ShortStack lastField_
= new ShortStack(15);
121 private short lastFieldId_
= 0;
124 * If we encounter a boolean field begin, save the TField here so it can
125 * have the value incorporated.
127 private TField booleanField_
= null;
130 * If we read a field header, and it's a boolean field, save the boolean
131 * value here so that readBool can use it.
133 private Boolean boolValue_
= null;
136 * The maximum number of bytes to read from the transport for
137 * variable-length fields (such as strings or binary) or {@link #NO_LENGTH_LIMIT} for
140 private final long stringLengthLimit_
;
143 * The maximum number of elements to read from the network for
144 * containers (maps, sets, lists), or {@link #NO_LENGTH_LIMIT} for unlimited.
146 private final long containerLengthLimit_
;
149 * Temporary buffer used for various operations that would otherwise require a
152 private final byte[] temp
= new byte[10];
155 * Create a TCompactProtocol.
157 * @param transport the TTransport object to read from or write to.
158 * @param stringLengthLimit the maximum number of bytes to read for
159 * variable-length fields.
160 * @param containerLengthLimit the maximum number of elements to read
163 public TCompactProtocol(TTransport transport
, long stringLengthLimit
, long containerLengthLimit
) {
165 this.stringLengthLimit_
= stringLengthLimit
;
166 this.containerLengthLimit_
= containerLengthLimit
;
170 * Create a TCompactProtocol.
172 * @param transport the TTransport object to read from or write to.
173 * @param stringLengthLimit the maximum number of bytes to read for
174 * variable-length fields.
175 * @deprecated Use constructor specifying both string limit and container limit instead
178 public TCompactProtocol(TTransport transport
, long stringLengthLimit
) {
179 this(transport
, stringLengthLimit
, NO_LENGTH_LIMIT
);
183 * Create a TCompactProtocol.
185 * @param transport the TTransport object to read from or write to.
187 public TCompactProtocol(TTransport transport
) {
188 this(transport
, NO_LENGTH_LIMIT
, NO_LENGTH_LIMIT
);
192 public void reset() {
198 // Public Writing methods.
202 * Write a message header to the wire. Compact Protocol messages contain the
203 * protocol version so we can migrate forwards in the future if need be.
206 public void writeMessageBegin(TMessage message
) throws TException
{
207 writeByteDirect(PROTOCOL_ID
);
208 writeByteDirect((VERSION
& VERSION_MASK
) | ((message
.type
<< TYPE_SHIFT_AMOUNT
) & TYPE_MASK
));
209 writeVarint32(message
.seqid
);
210 writeString(message
.name
);
214 * Write a struct begin. This doesn't actually put anything on the wire. We
215 * use it as an opportunity to put special placeholder markers on the field
216 * stack so we can get the field id deltas correct.
219 public void writeStructBegin(TStruct struct
) throws TException
{
220 lastField_
.push(lastFieldId_
);
225 * Write a struct end. This doesn't actually put anything on the wire. We use
226 * this as an opportunity to pop the last field from the current struct off
227 * of the field stack.
229 public void writeStructEnd() throws TException
{
230 lastFieldId_
= lastField_
.pop();
234 * Write a field header containing the field id and field type. If the
235 * difference between the current field id and the last one is small (< 15),
236 * then the field id will be encoded in the 4 MSB as a delta. Otherwise, the
237 * field id will follow the type header as a zigzag varint.
239 public void writeFieldBegin(TField field
) throws TException
{
240 if (field
.type
== TType
.BOOL
) {
241 // we want to possibly include the value, so we'll wait.
242 booleanField_
= field
;
244 writeFieldBeginInternal(field
, (byte)-1);
249 * The workhorse of writeFieldBegin. It has the option of doing a
250 * 'type override' of the type header. This is used specifically in the
251 * boolean field case.
253 private void writeFieldBeginInternal(TField field
, byte typeOverride
) throws TException
{
254 // short lastField = lastField_.pop();
256 // if there's a type override, use that.
257 byte typeToWrite
= typeOverride
== -1 ?
getCompactType(field
.type
) : typeOverride
;
259 // check if we can use delta encoding for the field id
260 if (field
.id
> lastFieldId_
&& field
.id
- lastFieldId_
<= 15) {
261 // write them together
262 writeByteDirect((field
.id
- lastFieldId_
) << 4 | typeToWrite
);
264 // write them separate
265 writeByteDirect(typeToWrite
);
269 lastFieldId_
= field
.id
;
270 // lastField_.push(field.id);
274 * Write the STOP symbol so we know there are no more fields in this struct.
276 public void writeFieldStop() throws TException
{
277 writeByteDirect(TType
.STOP
);
281 * Write a map header. If the map is empty, omit the key and value type
282 * headers, as we don't need any additional information to skip it.
284 public void writeMapBegin(TMap map
) throws TException
{
288 writeVarint32(map
.size
);
289 writeByteDirect(getCompactType(map
.keyType
) << 4 | getCompactType(map
.valueType
));
294 * Write a list header.
296 public void writeListBegin(TList list
) throws TException
{
297 writeCollectionBegin(list
.elemType
, list
.size
);
301 * Write a set header.
303 public void writeSetBegin(TSet set
) throws TException
{
304 writeCollectionBegin(set
.elemType
, set
.size
);
308 * Write a boolean value. Potentially, this could be a boolean field, in
309 * which case the field header info isn't written yet. If so, decide what the
310 * right type header is for the value and then write the field header.
311 * Otherwise, write a single byte.
313 public void writeBool(boolean b
) throws TException
{
314 if (booleanField_
!= null) {
315 // we haven't written the field header yet
316 writeFieldBeginInternal(booleanField_
, b ? Types
.BOOLEAN_TRUE
: Types
.BOOLEAN_FALSE
);
317 booleanField_
= null;
319 // we're not part of a field, so just write the value.
320 writeByteDirect(b ? Types
.BOOLEAN_TRUE
: Types
.BOOLEAN_FALSE
);
325 * Write a byte. Nothing to see here!
327 public void writeByte(byte b
) throws TException
{
332 * Write an I16 as a zigzag varint.
334 public void writeI16(short i16
) throws TException
{
335 writeVarint32(intToZigZag(i16
));
339 * Write an i32 as a zigzag varint.
341 public void writeI32(int i32
) throws TException
{
342 writeVarint32(intToZigZag(i32
));
346 * Write an i64 as a zigzag varint.
348 public void writeI64(long i64
) throws TException
{
349 writeVarint64(longToZigzag(i64
));
353 * Write a double to the wire as 8 bytes.
355 public void writeDouble(double dub
) throws TException
{
356 fixedLongToBytes(Double
.doubleToLongBits(dub
), temp
, 0);
357 trans_
.write(temp
, 0, 8);
361 * Write a string to the wire with a varint size preceding.
363 public void writeString(String str
) throws TException
{
364 byte[] bytes
= str
.getBytes(StandardCharsets
.UTF_8
);
365 writeBinary(bytes
, 0, bytes
.length
);
369 * Write a byte array, using a varint for the size.
371 public void writeBinary(ByteBuffer bin
) throws TException
{
372 int length
= bin
.limit() - bin
.position();
373 writeBinary(bin
.array(), bin
.position() + bin
.arrayOffset(), length
);
376 private void writeBinary(byte[] buf
, int offset
, int length
) throws TException
{
377 writeVarint32(length
);
378 trans_
.write(buf
, offset
, length
);
382 // These methods are called by structs, but don't actually have any wire
383 // output or purpose.
386 public void writeMessageEnd() throws TException
{}
387 public void writeMapEnd() throws TException
{}
388 public void writeListEnd() throws TException
{}
389 public void writeSetEnd() throws TException
{}
390 public void writeFieldEnd() throws TException
{}
393 // Internal writing methods
397 * Abstract method for writing the start of lists and sets. List and sets on
398 * the wire differ only by the type indicator.
400 protected void writeCollectionBegin(byte elemType
, int size
) throws TException
{
402 writeByteDirect(size
<< 4 | getCompactType(elemType
));
404 writeByteDirect(0xf0 | getCompactType(elemType
));
410 * Write an i32 as a varint. Results in 1-5 bytes on the wire.
411 * TODO: make a permanent buffer like writeVarint64?
413 private void writeVarint32(int n
) throws TException
{
416 if ((n
& ~
0x7F) == 0) {
417 temp
[idx
++] = (byte)n
;
418 // writeByteDirect((byte)n);
422 temp
[idx
++] = (byte)((n
& 0x7F) | 0x80);
423 // writeByteDirect((byte)((n & 0x7F) | 0x80));
427 trans_
.write(temp
, 0, idx
);
431 * Write an i64 as a varint. Results in 1-10 bytes on the wire.
433 private void writeVarint64(long n
) throws TException
{
436 if ((n
& ~
0x7FL
) == 0) {
437 temp
[idx
++] = (byte)n
;
440 temp
[idx
++] = ((byte)((n
& 0x7F) | 0x80));
444 trans_
.write(temp
, 0, idx
);
448 * Convert l into a zigzag long. This allows negative numbers to be
449 * represented compactly as a varint.
451 private long longToZigzag(long l
) {
452 return (l
<< 1) ^
(l
>> 63);
456 * Convert n into a zigzag int. This allows negative numbers to be
457 * represented compactly as a varint.
459 private int intToZigZag(int n
) {
460 return (n
<< 1) ^
(n
>> 31);
464 * Convert a long into little-endian bytes in buf starting at off and going
467 private void fixedLongToBytes(long n
, byte[] buf
, int off
) {
468 buf
[off
+0] = (byte)( n
& 0xff);
469 buf
[off
+1] = (byte)((n
>> 8 ) & 0xff);
470 buf
[off
+2] = (byte)((n
>> 16) & 0xff);
471 buf
[off
+3] = (byte)((n
>> 24) & 0xff);
472 buf
[off
+4] = (byte)((n
>> 32) & 0xff);
473 buf
[off
+5] = (byte)((n
>> 40) & 0xff);
474 buf
[off
+6] = (byte)((n
>> 48) & 0xff);
475 buf
[off
+7] = (byte)((n
>> 56) & 0xff);
479 * Writes a byte without any possibility of all that field header nonsense.
480 * Used internally by other writing methods that know they need to write a byte.
482 private void writeByteDirect(byte b
) throws TException
{
484 trans_
.write(temp
, 0, 1);
488 * Writes a byte without any possibility of all that field header nonsense.
490 private void writeByteDirect(int n
) throws TException
{
491 writeByteDirect((byte)n
);
500 * Read a message header.
502 public TMessage
readMessageBegin() throws TException
{
503 byte protocolId
= readByte();
504 if (protocolId
!= PROTOCOL_ID
) {
505 throw new TProtocolException("Expected protocol id " + Integer
.toHexString(PROTOCOL_ID
) + " but got " + Integer
.toHexString(protocolId
));
507 byte versionAndType
= readByte();
508 byte version
= (byte)(versionAndType
& VERSION_MASK
);
509 if (version
!= VERSION
) {
510 throw new TProtocolException("Expected version " + VERSION
+ " but got " + version
);
512 byte type
= (byte)((versionAndType
>> TYPE_SHIFT_AMOUNT
) & TYPE_BITS
);
513 int seqid
= readVarint32();
514 String messageName
= readString();
515 return new TMessage(messageName
, type
, seqid
);
519 * Read a struct begin. There's nothing on the wire for this, but it is our
520 * opportunity to push a new struct begin marker onto the field stack.
522 public TStruct
readStructBegin() throws TException
{
523 lastField_
.push(lastFieldId_
);
525 return ANONYMOUS_STRUCT
;
529 * Doesn't actually consume any wire data, just removes the last field for
530 * this struct from the field stack.
532 public void readStructEnd() throws TException
{
533 // consume the last field we read off the wire.
534 lastFieldId_
= lastField_
.pop();
538 * Read a field header off the wire.
540 public TField
readFieldBegin() throws TException
{
541 byte type
= readByte();
543 // if it's a stop, then we can return immediately, as the struct is over.
544 if (type
== TType
.STOP
) {
550 // mask off the 4 MSB of the type header. it could contain a field id delta.
551 short modifier
= (short)((type
& 0xf0) >> 4);
553 // not a delta. look ahead for the zigzag varint field id.
556 // has a delta. add the delta to the last read field id.
557 fieldId
= (short)(lastFieldId_
+ modifier
);
560 TField field
= new TField("", getTType((byte)(type
& 0x0f)), fieldId
);
562 // if this happens to be a boolean field, the value is encoded in the type
563 if (isBoolType(type
)) {
564 // save the boolean value in a special instance variable.
565 boolValue_
= (byte)(type
& 0x0f) == Types
.BOOLEAN_TRUE ? Boolean
.TRUE
: Boolean
.FALSE
;
568 // push the new field onto the field stack so we can keep the deltas going.
569 lastFieldId_
= field
.id
;
574 * Read a map header off the wire. If the size is zero, skip reading the key
575 * and value type. This means that 0-length maps will yield TMaps without the
578 public TMap
readMapBegin() throws TException
{
579 int size
= readVarint32();
580 checkContainerReadLength(size
);
581 byte keyAndValueType
= size
== 0 ?
0 : readByte();
582 return new TMap(getTType((byte)(keyAndValueType
>> 4)), getTType((byte)(keyAndValueType
& 0xf)), size
);
586 * Read a list header off the wire. If the list size is 0-14, the size will
587 * be packed into the element type header. If it's a longer list, the 4 MSB
588 * of the element type header will be 0xF, and a varint will follow with the
591 public TList
readListBegin() throws TException
{
592 byte size_and_type
= readByte();
593 int size
= (size_and_type
>> 4) & 0x0f;
595 size
= readVarint32();
597 checkContainerReadLength(size
);
598 byte type
= getTType(size_and_type
);
599 return new TList(type
, size
);
603 * Read a set header off the wire. If the set size is 0-14, the size will
604 * be packed into the element type header. If it's a longer set, the 4 MSB
605 * of the element type header will be 0xF, and a varint will follow with the
608 public TSet
readSetBegin() throws TException
{
609 return new TSet(readListBegin());
613 * Read a boolean off the wire. If this is a boolean field, the value should
614 * already have been read during readFieldBegin, so we'll just consume the
615 * pre-stored value. Otherwise, read a byte.
617 public boolean readBool() throws TException
{
618 if (boolValue_
!= null) {
619 boolean result
= boolValue_
.booleanValue();
623 return readByte() == Types
.BOOLEAN_TRUE
;
627 * Read a single byte off the wire. Nothing interesting here.
629 public byte readByte() throws TException
{
631 if (trans_
.getBytesRemainingInBuffer() > 0) {
632 b
= trans_
.getBuffer()[trans_
.getBufferPosition()];
633 trans_
.consumeBuffer(1);
635 trans_
.readAll(temp
, 0, 1);
642 * Read an i16 from the wire as a zigzag varint.
644 public short readI16() throws TException
{
645 return (short)zigzagToInt(readVarint32());
649 * Read an i32 from the wire as a zigzag varint.
651 public int readI32() throws TException
{
652 return zigzagToInt(readVarint32());
656 * Read an i64 from the wire as a zigzag varint.
658 public long readI64() throws TException
{
659 return zigzagToLong(readVarint64());
663 * No magic here - just read a double off the wire.
665 public double readDouble() throws TException
{
666 trans_
.readAll(temp
, 0, 8);
667 return Double
.longBitsToDouble(bytesToLong(temp
));
671 * Reads a byte[] (via readBinary), and then UTF-8 decodes it.
673 public String
readString() throws TException
{
674 int length
= readVarint32();
675 checkStringReadLength(length
);
682 if (trans_
.getBytesRemainingInBuffer() >= length
) {
683 str
= new String(trans_
.getBuffer(), trans_
.getBufferPosition(),
684 length
, StandardCharsets
.UTF_8
);
685 trans_
.consumeBuffer(length
);
687 str
= new String(readBinary(length
), StandardCharsets
.UTF_8
);
693 * Read a byte[] from the wire.
695 public ByteBuffer
readBinary() throws TException
{
696 int length
= readVarint32();
697 checkStringReadLength(length
);
698 if (length
== 0) return EMPTY_BUFFER
;
700 if (trans_
.getBytesRemainingInBuffer() >= length
) {
701 ByteBuffer bb
= ByteBuffer
.wrap(trans_
.getBuffer(), trans_
.getBufferPosition(), length
);
702 trans_
.consumeBuffer(length
);
706 byte[] buf
= new byte[length
];
707 trans_
.readAll(buf
, 0, length
);
708 return ByteBuffer
.wrap(buf
);
712 * Read a byte[] of a known length from the wire.
714 private byte[] readBinary(int length
) throws TException
{
715 if (length
== 0) return EMPTY_BYTES
;
717 byte[] buf
= new byte[length
];
718 trans_
.readAll(buf
, 0, length
);
722 private void checkStringReadLength(int length
) throws TProtocolException
{
724 throw new TProtocolException(TProtocolException
.NEGATIVE_SIZE
,
725 "Negative length: " + length
);
727 if (stringLengthLimit_
!= NO_LENGTH_LIMIT
&& length
> stringLengthLimit_
) {
728 throw new TProtocolException(TProtocolException
.SIZE_LIMIT
,
729 "Length exceeded max allowed: " + length
);
733 private void checkContainerReadLength(int length
) throws TProtocolException
{
735 throw new TProtocolException(TProtocolException
.NEGATIVE_SIZE
,
736 "Negative length: " + length
);
738 if (containerLengthLimit_
!= NO_LENGTH_LIMIT
&& length
> containerLengthLimit_
) {
739 throw new TProtocolException(TProtocolException
.SIZE_LIMIT
,
740 "Length exceeded max allowed: " + length
);
745 // These methods are here for the struct to call, but don't have any wire
748 public void readMessageEnd() throws TException
{}
749 public void readFieldEnd() throws TException
{}
750 public void readMapEnd() throws TException
{}
751 public void readListEnd() throws TException
{}
752 public void readSetEnd() throws TException
{}
755 // Internal reading methods
759 * Read an i32 from the wire as a varint. The MSB of each byte is set
760 * if there is another byte to follow. This can read up to 5 bytes.
762 private int readVarint32() throws TException
{
765 if (trans_
.getBytesRemainingInBuffer() >= 5) {
766 byte[] buf
= trans_
.getBuffer();
767 int pos
= trans_
.getBufferPosition();
770 byte b
= buf
[pos
+off
];
771 result
|= (int) (b
& 0x7f) << shift
;
772 if ((b
& 0x80) != 0x80) break;
776 trans_
.consumeBuffer(off
+1);
780 result
|= (int) (b
& 0x7f) << shift
;
781 if ((b
& 0x80) != 0x80) break;
789 * Read an i64 from the wire as a proper varint. The MSB of each byte is set
790 * if there is another byte to follow. This can read up to 10 bytes.
792 private long readVarint64() throws TException
{
795 if (trans_
.getBytesRemainingInBuffer() >= 10) {
796 byte[] buf
= trans_
.getBuffer();
797 int pos
= trans_
.getBufferPosition();
800 byte b
= buf
[pos
+off
];
801 result
|= (long) (b
& 0x7f) << shift
;
802 if ((b
& 0x80) != 0x80) break;
806 trans_
.consumeBuffer(off
+1);
810 result
|= (long) (b
& 0x7f) << shift
;
811 if ((b
& 0x80) != 0x80) break;
823 * Convert from zigzag int to int.
825 private int zigzagToInt(int n
) {
826 return (n
>>> 1) ^
-(n
& 1);
830 * Convert from zigzag long to long.
832 private long zigzagToLong(long n
) {
833 return (n
>>> 1) ^
-(n
& 1);
837 * Note that it's important that the mask bytes are long literals,
838 * otherwise they'll default to ints, and when you shift an int left 56 bits,
839 * you just get a messed up int.
841 private long bytesToLong(byte[] bytes
) {
843 ((bytes
[7] & 0xffL
) << 56) |
844 ((bytes
[6] & 0xffL
) << 48) |
845 ((bytes
[5] & 0xffL
) << 40) |
846 ((bytes
[4] & 0xffL
) << 32) |
847 ((bytes
[3] & 0xffL
) << 24) |
848 ((bytes
[2] & 0xffL
) << 16) |
849 ((bytes
[1] & 0xffL
) << 8) |
850 ((bytes
[0] & 0xffL
));
854 // type testing and converting
857 private boolean isBoolType(byte b
) {
858 int lowerNibble
= b
& 0x0f;
859 return lowerNibble
== Types
.BOOLEAN_TRUE
|| lowerNibble
== Types
.BOOLEAN_FALSE
;
863 * Given a TCompactProtocol.Types constant, convert it to its corresponding
866 private byte getTType(byte type
) throws TProtocolException
{
867 switch ((byte)(type
& 0x0f)) {
870 case Types
.BOOLEAN_FALSE
:
871 case Types
.BOOLEAN_TRUE
:
894 throw new TProtocolException("don't know what type: " + (byte)(type
& 0x0f));
899 * Given a TType value, find the appropriate TCompactProtocol.Types constant.
901 private byte getCompactType(byte ttype
) {
902 return ttypeToCompactType
[ttype
];