Rev 30 | Blame | Compare with Previous | Last modification | View Log | RSS feed
## 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 Thriftclass BinaryProtocol < BaseProtocolVERSION_MASK = 0xffff0000VERSION_1 = 0x80010000TYPE_MASK = 0x000000ffattr_reader :strict_read, :strict_writedef initialize(trans, strict_read=true, strict_write=true)super(trans)@strict_read = strict_read@strict_write = strict_writeenddef write_message_begin(name, type, seqid)# this is necessary because we added (needed) bounds checking to# write_i32, and 0x80010000 is too big for that.if strict_writewrite_i16(VERSION_1 >> 16)write_i16(type)write_string(name)write_i32(seqid)elsewrite_string(name)write_byte(type)write_i32(seqid)endenddef write_struct_begin(name); nil; enddef write_field_begin(name, type, id)write_byte(type)write_i16(id)enddef write_field_stopwrite_byte(Thrift::Types::STOP)enddef write_map_begin(ktype, vtype, size)write_byte(ktype)write_byte(vtype)write_i32(size)enddef write_list_begin(etype, size)write_byte(etype)write_i32(size)enddef write_set_begin(etype, size)write_byte(etype)write_i32(size)enddef write_bool(bool)write_byte(bool ? 1 : 0)enddef write_byte(byte)raise RangeError if byte < -2**31 || byte >= 2**32trans.write([byte].pack('c'))enddef write_i16(i16)trans.write([i16].pack('n'))enddef write_i32(i32)raise RangeError if i32 < -2**31 || i32 >= 2**31trans.write([i32].pack('N'))enddef write_i64(i64)raise RangeError if i64 < -2**63 || i64 >= 2**64hi = i64 >> 32lo = i64 & 0xfffffffftrans.write([hi, lo].pack('N2'))enddef write_double(dub)trans.write([dub].pack('G'))enddef write_string(str)write_i32(str.length)trans.write(str)enddef read_message_beginversion = read_i32if version < 0if (version & VERSION_MASK != VERSION_1)raise ProtocolException.new(ProtocolException::BAD_VERSION, 'Missing version identifier')endtype = version & TYPE_MASKname = read_stringseqid = read_i32[name, type, seqid]elseif strict_readraise ProtocolException.new(ProtocolException::BAD_VERSION, 'No version identifier, old protocol client?')endname = trans.read_all(version)type = read_byteseqid = read_i32[name, type, seqid]endenddef read_struct_begin; nil; enddef read_field_begintype = read_byteif (type == Types::STOP)[nil, type, 0]elseid = read_i16[nil, type, id]endenddef read_map_beginktype = read_bytevtype = read_bytesize = read_i32[ktype, vtype, size]enddef read_list_beginetype = read_bytesize = read_i32[etype, size]enddef read_set_beginetype = read_bytesize = read_i32[etype, size]enddef read_boolbyte = read_bytebyte != 0enddef read_bytedat = trans.read_all(1)val = dat[0].ordif (val > 0x7f)val = 0 - ((val - 1) ^ 0xff)endvalenddef read_i16dat = trans.read_all(2)val, = dat.unpack('n')if (val > 0x7fff)val = 0 - ((val - 1) ^ 0xffff)endvalenddef read_i32dat = trans.read_all(4)val, = dat.unpack('N')if (val > 0x7fffffff)val = 0 - ((val - 1) ^ 0xffffffff)endvalenddef read_i64dat = trans.read_all(8)hi, lo = dat.unpack('N2')if (hi > 0x7fffffff)hi ^= 0xfffffffflo ^= 0xffffffff0 - (hi << 32) - lo - 1else(hi << 32) + loendenddef read_doubledat = trans.read_all(8)val = dat.unpack('G').firstvalenddef read_stringsz = read_i32dat = trans.read_all(sz)datendendclass BinaryProtocolFactory < BaseProtocolFactorydef get_protocol(trans)return Thrift::BinaryProtocol.new(trans)endendend