summaryrefslogtreecommitdiffstats
path: root/vendor/thrift/protocol/compact_protocol.rb
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/thrift/protocol/compact_protocol.rb')
-rw-r--r--vendor/thrift/protocol/compact_protocol.rb426
1 files changed, 0 insertions, 426 deletions
diff --git a/vendor/thrift/protocol/compact_protocol.rb b/vendor/thrift/protocol/compact_protocol.rb
deleted file mode 100644
index ede82f2..0000000
--- a/vendor/thrift/protocol/compact_protocol.rb
+++ /dev/null
@@ -1,426 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#
-
-module Thrift
- class CompactProtocol < BaseProtocol
-
- PROTOCOL_ID = [0x82].pack('c').unpack('c').first
- VERSION = 1
- VERSION_MASK = 0x1f
- TYPE_MASK = 0xE0
- TYPE_SHIFT_AMOUNT = 5
-
- TSTOP = ["", Types::STOP, 0]
-
- #
- # All of the on-wire type codes.
- #
- class CompactTypes
- BOOLEAN_TRUE = 0x01
- BOOLEAN_FALSE = 0x02
- BYTE = 0x03
- I16 = 0x04
- I32 = 0x05
- I64 = 0x06
- DOUBLE = 0x07
- BINARY = 0x08
- LIST = 0x09
- SET = 0x0A
- MAP = 0x0B
- STRUCT = 0x0C
-
- def self.is_bool_type?(b)
- (b & 0x0f) == BOOLEAN_TRUE || (b & 0x0f) == BOOLEAN_FALSE
- end
-
- COMPACT_TO_TTYPE = {
- Types::STOP => Types::STOP,
- BOOLEAN_FALSE => Types::BOOL,
- BOOLEAN_TRUE => Types::BOOL,
- BYTE => Types::BYTE,
- I16 => Types::I16,
- I32 => Types::I32,
- I64 => Types::I64,
- DOUBLE => Types::DOUBLE,
- BINARY => Types::STRING,
- LIST => Types::LIST,
- SET => Types::SET,
- MAP => Types::MAP,
- STRUCT => Types::STRUCT
- }
-
- TTYPE_TO_COMPACT = {
- Types::STOP => Types::STOP,
- Types::BOOL => BOOLEAN_TRUE,
- Types::BYTE => BYTE,
- Types::I16 => I16,
- Types::I32 => I32,
- Types::I64 => I64,
- Types::DOUBLE => DOUBLE,
- Types::STRING => BINARY,
- Types::LIST => LIST,
- Types::SET => SET,
- Types::MAP => MAP,
- Types::STRUCT => STRUCT
- }
-
- def self.get_ttype(compact_type)
- val = COMPACT_TO_TTYPE[compact_type & 0x0f]
- raise "don't know what type: #{compact_type & 0x0f}" unless val
- val
- end
-
- def self.get_compact_type(ttype)
- val = TTYPE_TO_COMPACT[ttype]
- raise "don't know what type: #{ttype & 0x0f}" unless val
- val
- end
- end
-
- def initialize(transport)
- super(transport)
-
- @last_field = [0]
- @boolean_value = nil
-
- # Pre-allocated read buffer for read_double().
- @rbuf = "\0" * 8
- @rbuf.force_encoding("BINARY") if @rbuf.respond_to?(:force_encoding)
- end
-
- def write_message_begin(name, type, seqid)
- write_byte(PROTOCOL_ID)
- write_byte((VERSION & VERSION_MASK) | ((type << TYPE_SHIFT_AMOUNT) & TYPE_MASK))
- write_varint32(seqid)
- write_string(name)
- nil
- end
-
- def write_struct_begin(name)
- @last_field.push(0)
- nil
- end
-
- def write_struct_end
- @last_field.pop
- nil
- end
-
- def write_field_begin(name, type, id)
- if type == Types::BOOL
- # we want to possibly include the value, so we'll wait.
- @boolean_field = [type, id]
- else
- write_field_begin_internal(type, id)
- end
- nil
- end
-
- #
- # The workhorse of writeFieldBegin. It has the option of doing a
- # 'type override' of the type header. This is used specifically in the
- # boolean field case.
- #
- def write_field_begin_internal(type, id, type_override=nil)
- last_id = @last_field.pop
-
- # if there's a type override, use that.
- typeToWrite = type_override || CompactTypes.get_compact_type(type)
-
- # check if we can use delta encoding for the field id
- if id > last_id && id - last_id <= 15
- # write them together
- write_byte((id - last_id) << 4 | typeToWrite)
- else
- # write them separate
- write_byte(typeToWrite)
- write_i16(id)
- end
-
- @last_field.push(id)
- nil
- end
-
- def write_field_stop
- write_byte(Types::STOP)
- end
-
- def write_map_begin(ktype, vtype, size)
- if (size == 0)
- write_byte(0)
- else
- write_varint32(size)
- write_byte(CompactTypes.get_compact_type(ktype) << 4 | CompactTypes.get_compact_type(vtype))
- end
- end
-
- def write_list_begin(etype, size)
- write_collection_begin(etype, size)
- end
-
- def write_set_begin(etype, size)
- write_collection_begin(etype, size);
- end
-
- def write_bool(bool)
- type = bool ? CompactTypes::BOOLEAN_TRUE : CompactTypes::BOOLEAN_FALSE
- unless @boolean_field.nil?
- # we haven't written the field header yet
- write_field_begin_internal(@boolean_field.first, @boolean_field.last, type)
- @boolean_field = nil
- else
- # we're not part of a field, so just write the value.
- write_byte(type)
- end
- end
-
- def write_byte(byte)
- @trans.write([byte].pack('c'))
- end
-
- def write_i16(i16)
- write_varint32(int_to_zig_zag(i16))
- end
-
- def write_i32(i32)
- write_varint32(int_to_zig_zag(i32))
- end
-
- def write_i64(i64)
- write_varint64(long_to_zig_zag(i64))
- end
-
- def write_double(dub)
- @trans.write([dub].pack("G").reverse)
- end
-
- def write_string(str)
- write_varint32(str.length)
- @trans.write(str)
- end
-
- def read_message_begin
- protocol_id = read_byte()
- if protocol_id != PROTOCOL_ID
- raise ProtocolException.new("Expected protocol id #{PROTOCOL_ID} but got #{protocol_id}")
- end
-
- version_and_type = read_byte()
- version = version_and_type & VERSION_MASK
- if (version != VERSION)
- raise ProtocolException.new("Expected version #{VERSION} but got #{version}");
- end
-
- type = (version_and_type >> TYPE_SHIFT_AMOUNT) & 0x03
- seqid = read_varint32()
- messageName = read_string()
- [messageName, type, seqid]
- end
-
- def read_struct_begin
- @last_field.push(0)
- ""
- end
-
- def read_struct_end
- @last_field.pop()
- nil
- end
-
- def read_field_begin
- type = read_byte()
-
- # if it's a stop, then we can return immediately, as the struct is over.
- if (type & 0x0f) == Types::STOP
- TSTOP
- else
- field_id = nil
-
- # mask off the 4 MSB of the type header. it could contain a field id delta.
- modifier = (type & 0xf0) >> 4
- if modifier == 0
- # not a delta. look ahead for the zigzag varint field id.
- @last_field.pop
- field_id = read_i16()
- else
- # has a delta. add the delta to the last read field id.
- field_id = @last_field.pop + modifier
- end
-
- # if this happens to be a boolean field, the value is encoded in the type
- if CompactTypes.is_bool_type?(type)
- # save the boolean value in a special instance variable.
- @bool_value = (type & 0x0f) == CompactTypes::BOOLEAN_TRUE
- end
-
- # push the new field onto the field stack so we can keep the deltas going.
- @last_field.push(field_id)
- ["", CompactTypes.get_ttype(type & 0x0f), field_id]
- end
- end
-
- def read_map_begin
- size = read_varint32()
- key_and_value_type = size == 0 ? 0 : read_byte()
- [CompactTypes.get_ttype(key_and_value_type >> 4), CompactTypes.get_ttype(key_and_value_type & 0xf), size]
- end
-
- def read_list_begin
- size_and_type = read_byte()
- size = (size_and_type >> 4) & 0x0f
- if size == 15
- size = read_varint32()
- end
- type = CompactTypes.get_ttype(size_and_type)
- [type, size]
- end
-
- def read_set_begin
- read_list_begin
- end
-
- def read_bool
- unless @bool_value.nil?
- bv = @bool_value
- @bool_value = nil
- bv
- else
- read_byte() == CompactTypes::BOOLEAN_TRUE
- end
- end
-
- def read_byte
- val = trans.read_byte
- if (val > 0x7f)
- val = 0 - ((val - 1) ^ 0xff)
- end
- val
- end
-
- def read_i16
- zig_zag_to_int(read_varint32())
- end
-
- def read_i32
- zig_zag_to_int(read_varint32())
- end
-
- def read_i64
- zig_zag_to_long(read_varint64())
- end
-
- def read_double
- trans.read_into_buffer(@rbuf, 8)
- val = @rbuf.reverse.unpack('G').first
- val
- end
-
- def read_string
- size = read_varint32()
- trans.read_all(size)
- end
-
-
- private
-
- #
- # Abstract method for writing the start of lists and sets. List and sets on
- # the wire differ only by the type indicator.
- #
- def write_collection_begin(elem_type, size)
- if size <= 14
- write_byte(size << 4 | CompactTypes.get_compact_type(elem_type))
- else
- write_byte(0xf0 | CompactTypes.get_compact_type(elem_type))
- write_varint32(size)
- end
- end
-
- def write_varint32(n)
- # int idx = 0;
- while true
- if (n & ~0x7F) == 0
- # i32buf[idx++] = (byte)n;
- write_byte(n)
- break
- # return;
- else
- # i32buf[idx++] = (byte)((n & 0x7F) | 0x80);
- write_byte((n & 0x7F) | 0x80)
- n = n >> 7
- end
- end
- # trans_.write(i32buf, 0, idx);
- end
-
- SEVEN_BIT_MASK = 0x7F
- EVERYTHING_ELSE_MASK = ~SEVEN_BIT_MASK
-
- def write_varint64(n)
- while true
- if (n & EVERYTHING_ELSE_MASK) == 0 #TODO need to find a way to make this into a long...
- write_byte(n)
- break
- else
- write_byte((n & SEVEN_BIT_MASK) | 0x80)
- n >>= 7
- end
- end
- end
-
- def read_varint32()
- read_varint64()
- end
-
- def read_varint64()
- shift = 0
- result = 0
- while true
- b = read_byte()
- result |= (b & 0x7f) << shift
- break if (b & 0x80) != 0x80
- shift += 7
- end
- result
- end
-
- def int_to_zig_zag(n)
- (n << 1) ^ (n >> 31)
- end
-
- def long_to_zig_zag(l)
- # puts "zz encoded #{l} to #{(l << 1) ^ (l >> 63)}"
- (l << 1) ^ (l >> 63)
- end
-
- def zig_zag_to_int(n)
- (n >> 1) ^ -(n & 1)
- end
-
- def zig_zag_to_long(n)
- (n >> 1) ^ -(n & 1)
- end
- end
-
- class CompactProtocolFactory < BaseProtocolFactory
- def get_protocol(trans)
- CompactProtocol.new(trans)
- end
- end
-end