module ThriftClient::Simple

This is a simplified form of thrift, useful for clients only, and not making any attempt to have good performance. It's intended to be used by small command-line tools that don't want to install a dozen ruby files.

Constants

EXCEPTION
FORMATS
LIST
ListType
MapType
SIZES
SetType
StructType
VERSION_1

Public Class Methods

make_struct(name, *fields) click to toggle source
# File lib/thrift_client/simple.rb, line 220
def self.make_struct(name, *fields)
  st_name = "ST_#{name}"
  if Struct.constants.include?(st_name)
    warn "#{caller[0]}: Struct::#{st_name} is already defined; returning original class."
    Struct.const_get(st_name)
  else
    names = fields.map { |f| f.name.to_sym }
    klass = Struct.new(st_name, *names)
    klass.send(:include, ThriftStruct::Include)
    klass.send(:extend, ThriftStruct::Extend)
    klass._fields = fields
    klass
  end
end
make_type(type_id, name, *args) click to toggle source
# File lib/thrift_client/simple.rb, line 55
def self.make_type(type_id, name, *args)
  klass = Struct.new("STT_#{name}", *args)
  klass.send(:extend, ComplexType::Extends)
  klass.send(:include, ComplexType::Includes)
  klass.type_id = type_id
  klass
end
pack_request(method_name, arg_struct, request_id=0) click to toggle source
# File lib/thrift_client/simple.rb, line 90
def pack_request(method_name, arg_struct, request_id=0)
  [ VERSION_1, CALL, method_name.to_s.size, method_name.to_s, request_id, arg_struct._pack ].pack("nnNa*Na*")
end
pack_value(type, value) click to toggle source
# File lib/thrift_client/simple.rb, line 69
def pack_value(type, value)
  case type
  when BOOL
    [ value ? 1 : 0 ].pack("c")
  when STRING
    [ value.size, value ].pack("Na*")
  when I64
    [ value >> 32, value & 0xffffffff ].pack("NN")
  when ListType
    [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("")
  when MapType
    [ type.key_type.to_i, type.value_type.to_i, value.size ].pack("ccN") + value.map { |k, v| pack_value(type.key_type, k) + pack_value(type.value_type, v) }.join("")
  when SetType
    [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("")
  when StructType
    value._pack
  else
    [ value ].pack(FORMATS[type])
  end
end
read_list(s, element_type=nil) click to toggle source
# File lib/thrift_client/simple.rb, line 130
def read_list(s, element_type=nil)
  etype, len = s.read(5).unpack("cN")
  expected_type = (element_type and element_type.to_i == etype.to_i) ? element_type : etype
  rv = []
  len.times do
    rv << read_value(s, expected_type)
  end
  rv
end
read_map(s, key_type=nil, value_type=nil) click to toggle source
# File lib/thrift_client/simple.rb, line 140
def read_map(s, key_type=nil, value_type=nil)
  ktype, vtype, len = s.read(6).unpack("ccN")
  rv = {}
  expected_key_type, expected_value_type = if key_type and value_type and key_type.to_i == ktype and value_type.to_i == vtype
    [ key_type, value_type ]
  else
    [ ktype, vtype ]
  end
  len.times do
    key = read_value(s, expected_key_type)
    value = read_value(s, expected_value_type)
    rv[key] = value
  end
  rv
end
read_response(s, rv_class) click to toggle source
# File lib/thrift_client/simple.rb, line 168
def read_response(s, rv_class)
  version, message_type, method_name_len = s.read(8).unpack("nnN")
  method_name = s.read(method_name_len)
  seq_id = s.read(4).unpack("N").first
  [ method_name, seq_id, read_struct(s, rv_class).rv ]
end
read_struct(s, struct_class=nil) click to toggle source
# File lib/thrift_client/simple.rb, line 156
def read_struct(s, struct_class=nil)
  rv = struct_class.new()
  while true
    type = s.read(1).unpack("c").first
    return rv if type == STOP
    fid = s.read(2).unpack("n").first
    field = struct_class ? struct_class._fields.find { |f| (f.fid == fid) and (f.type.to_i == type) } : nil
    value = read_value(s, field ? field.type : type)
    rv[field.name] = value if field
  end
end
read_value(s, type) click to toggle source
# File lib/thrift_client/simple.rb, line 94
def read_value(s, type)
  case type
  when BOOL
    s.read(1).unpack("c").first != 0
  when STRING
    len = s.read(4).unpack("N").first
    s.read(len)
  when I64
    hi, lo = s.read(8).unpack("NN")
    rv = (hi << 32) | lo
    (rv >= (1 << 63)) ? (rv - (1 << 64)) : rv
  when LIST
    read_list(s)
  when MAP
    read_map(s)
  when STRUCT
    read_struct(s)
  when ListType
    read_list(s, type.element_type)
  when MapType
    read_map(s, type.key_type, type.value_type)
  when StructType
    read_struct(s, type.struct_class)
  else
    rv = s.read(SIZES[type]).unpack(FORMATS[type]).first
    case type
    when I16
      (rv >= (1 << 15)) ? (rv - (1 << 16)) : rv
    when I32
      (rv >= (1 << 31)) ? (rv - (1 << 32)) : rv
    else
      rv
    end
  end
end