Module | ThriftClient::Simple |
In: |
lib/thrift_client/simple.rb
lib/thrift_client/simple.rb |
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.
VERSION_1 | = | 0x8001 |
EXCEPTION | = | (1..3).to_a |
LIST | = | (0..15).to_a |
FORMATS | = | { BYTE => "c", DOUBLE => "G", I16 => "n", I32 => "N", } |
SIZES | = | { BYTE => 1, DOUBLE => 8, I16 => 2, I32 => 4, } |
ListType | = | make_type(LIST, "ListType", :element_type) |
MapType | = | make_type(MAP, "MapType", :key_type, :value_type) |
SetType | = | make_type(SET, "SetType", :element_type) |
StructType | = | make_type(STRUCT, "StructType", :struct_class) |
VERSION_1 | = | 0x8001 |
EXCEPTION | = | (1..3).to_a |
LIST | = | (0..15).to_a |
FORMATS | = | { BYTE => "c", DOUBLE => "G", I16 => "n", I32 => "N", } |
SIZES | = | { BYTE => 1, DOUBLE => 8, I16 => 2, I32 => 4, } |
ListType | = | make_type(LIST, "ListType", :element_type) |
MapType | = | make_type(MAP, "MapType", :key_type, :value_type) |
SetType | = | make_type(SET, "SetType", :element_type) |
StructType | = | make_type(STRUCT, "StructType", :struct_class) |
# File lib/thrift_client/simple.rb, line 220 220: def self.make_struct(name, *fields) 221: st_name = "ST_#{name}" 222: if Struct.constants.include?(st_name) 223: warn "#{caller[0]}: Struct::#{st_name} is already defined; returning original class." 224: Struct.const_get(st_name) 225: else 226: names = fields.map { |f| f.name.to_sym } 227: klass = Struct.new(st_name, *names) 228: klass.send(:include, ThriftStruct::Include) 229: klass.send(:extend, ThriftStruct::Extend) 230: klass._fields = fields 231: klass 232: end 233: end
# File lib/thrift_client/simple.rb, line 220 220: def self.make_struct(name, *fields) 221: st_name = "ST_#{name}" 222: if Struct.constants.include?(st_name) 223: warn "#{caller[0]}: Struct::#{st_name} is already defined; returning original class." 224: Struct.const_get(st_name) 225: else 226: names = fields.map { |f| f.name.to_sym } 227: klass = Struct.new(st_name, *names) 228: klass.send(:include, ThriftStruct::Include) 229: klass.send(:extend, ThriftStruct::Extend) 230: klass._fields = fields 231: klass 232: end 233: end
# File lib/thrift_client/simple.rb, line 55 55: def self.make_type(type_id, name, *args) 56: klass = Struct.new("STT_#{name}", *args) 57: klass.send(:extend, ComplexType::Extends) 58: klass.send(:include, ComplexType::Includes) 59: klass.type_id = type_id 60: klass 61: end
# File lib/thrift_client/simple.rb, line 55 55: def self.make_type(type_id, name, *args) 56: klass = Struct.new("STT_#{name}", *args) 57: klass.send(:extend, ComplexType::Extends) 58: klass.send(:include, ComplexType::Includes) 59: klass.type_id = type_id 60: klass 61: end
# File lib/thrift_client/simple.rb, line 90 90: def pack_request(method_name, arg_struct, request_id=0) 91: [ VERSION_1, CALL, method_name.to_s.size, method_name.to_s, request_id, arg_struct._pack ].pack("nnNa*Na*") 92: end
# File lib/thrift_client/simple.rb, line 90 90: def pack_request(method_name, arg_struct, request_id=0) 91: [ VERSION_1, CALL, method_name.to_s.size, method_name.to_s, request_id, arg_struct._pack ].pack("nnNa*Na*") 92: end
# File lib/thrift_client/simple.rb, line 69 69: def pack_value(type, value) 70: case type 71: when BOOL 72: [ value ? 1 : 0 ].pack("c") 73: when STRING 74: [ value.size, value ].pack("Na*") 75: when I64 76: [ value >> 32, value & 0xffffffff ].pack("NN") 77: when ListType 78: [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("") 79: when MapType 80: [ 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("") 81: when SetType 82: [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("") 83: when StructType 84: value._pack 85: else 86: [ value ].pack(FORMATS[type]) 87: end 88: end
# File lib/thrift_client/simple.rb, line 69 69: def pack_value(type, value) 70: case type 71: when BOOL 72: [ value ? 1 : 0 ].pack("c") 73: when STRING 74: [ value.size, value ].pack("Na*") 75: when I64 76: [ value >> 32, value & 0xffffffff ].pack("NN") 77: when ListType 78: [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("") 79: when MapType 80: [ 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("") 81: when SetType 82: [ type.element_type.to_i, value.size ].pack("cN") + value.map { |item| pack_value(type.element_type, item) }.join("") 83: when StructType 84: value._pack 85: else 86: [ value ].pack(FORMATS[type]) 87: end 88: end
# File lib/thrift_client/simple.rb, line 130 130: def read_list(s, element_type=nil) 131: etype, len = s.read(5).unpack("cN") 132: expected_type = (element_type and element_type.to_i == etype.to_i) ? element_type : etype 133: rv = [] 134: len.times do 135: rv << read_value(s, expected_type) 136: end 137: rv 138: end
# File lib/thrift_client/simple.rb, line 130 130: def read_list(s, element_type=nil) 131: etype, len = s.read(5).unpack("cN") 132: expected_type = (element_type and element_type.to_i == etype.to_i) ? element_type : etype 133: rv = [] 134: len.times do 135: rv << read_value(s, expected_type) 136: end 137: rv 138: end
# File lib/thrift_client/simple.rb, line 140 140: def read_map(s, key_type=nil, value_type=nil) 141: ktype, vtype, len = s.read(6).unpack("ccN") 142: rv = {} 143: expected_key_type, expected_value_type = if key_type and value_type and key_type.to_i == ktype and value_type.to_i == vtype 144: [ key_type, value_type ] 145: else 146: [ ktype, vtype ] 147: end 148: len.times do 149: key = read_value(s, expected_key_type) 150: value = read_value(s, expected_value_type) 151: rv[key] = value 152: end 153: rv 154: end
# File lib/thrift_client/simple.rb, line 140 140: def read_map(s, key_type=nil, value_type=nil) 141: ktype, vtype, len = s.read(6).unpack("ccN") 142: rv = {} 143: expected_key_type, expected_value_type = if key_type and value_type and key_type.to_i == ktype and value_type.to_i == vtype 144: [ key_type, value_type ] 145: else 146: [ ktype, vtype ] 147: end 148: len.times do 149: key = read_value(s, expected_key_type) 150: value = read_value(s, expected_value_type) 151: rv[key] = value 152: end 153: rv 154: end
# File lib/thrift_client/simple.rb, line 168 168: def read_response(s, rv_class) 169: version, message_type, method_name_len = s.read(8).unpack("nnN") 170: method_name = s.read(method_name_len) 171: seq_id = s.read(4).unpack("N").first 172: [ method_name, seq_id, read_struct(s, rv_class).rv ] 173: end
# File lib/thrift_client/simple.rb, line 168 168: def read_response(s, rv_class) 169: version, message_type, method_name_len = s.read(8).unpack("nnN") 170: method_name = s.read(method_name_len) 171: seq_id = s.read(4).unpack("N").first 172: [ method_name, seq_id, read_struct(s, rv_class).rv ] 173: end
# File lib/thrift_client/simple.rb, line 156 156: def read_struct(s, struct_class=nil) 157: rv = struct_class.new() 158: while true 159: type = s.read(1).unpack("c").first 160: return rv if type == STOP 161: fid = s.read(2).unpack("n").first 162: field = struct_class ? struct_class._fields.find { |f| (f.fid == fid) and (f.type.to_i == type) } : nil 163: value = read_value(s, field ? field.type : type) 164: rv[field.name] = value if field 165: end 166: end
# File lib/thrift_client/simple.rb, line 156 156: def read_struct(s, struct_class=nil) 157: rv = struct_class.new() 158: while true 159: type = s.read(1).unpack("c").first 160: return rv if type == STOP 161: fid = s.read(2).unpack("n").first 162: field = struct_class ? struct_class._fields.find { |f| (f.fid == fid) and (f.type.to_i == type) } : nil 163: value = read_value(s, field ? field.type : type) 164: rv[field.name] = value if field 165: end 166: end
# File lib/thrift_client/simple.rb, line 94 94: def read_value(s, type) 95: case type 96: when BOOL 97: s.read(1).unpack("c").first != 0 98: when STRING 99: len = s.read(4).unpack("N").first 100: s.read(len) 101: when I64 102: hi, lo = s.read(8).unpack("NN") 103: rv = (hi << 32) | lo 104: (rv >= (1 << 63)) ? (rv - (1 << 64)) : rv 105: when LIST 106: read_list(s) 107: when MAP 108: read_map(s) 109: when STRUCT 110: read_struct(s) 111: when ListType 112: read_list(s, type.element_type) 113: when MapType 114: read_map(s, type.key_type, type.value_type) 115: when StructType 116: read_struct(s, type.struct_class) 117: else 118: rv = s.read(SIZES[type]).unpack(FORMATS[type]).first 119: case type 120: when I16 121: (rv >= (1 << 15)) ? (rv - (1 << 16)) : rv 122: when I32 123: (rv >= (1 << 31)) ? (rv - (1 << 32)) : rv 124: else 125: rv 126: end 127: end 128: end
# File lib/thrift_client/simple.rb, line 94 94: def read_value(s, type) 95: case type 96: when BOOL 97: s.read(1).unpack("c").first != 0 98: when STRING 99: len = s.read(4).unpack("N").first 100: s.read(len) 101: when I64 102: hi, lo = s.read(8).unpack("NN") 103: rv = (hi << 32) | lo 104: (rv >= (1 << 63)) ? (rv - (1 << 64)) : rv 105: when LIST 106: read_list(s) 107: when MAP 108: read_map(s) 109: when STRUCT 110: read_struct(s) 111: when ListType 112: read_list(s, type.element_type) 113: when MapType 114: read_map(s, type.key_type, type.value_type) 115: when StructType 116: read_struct(s, type.struct_class) 117: else 118: rv = s.read(SIZES[type]).unpack(FORMATS[type]).first 119: case type 120: when I16 121: (rv >= (1 << 15)) ? (rv - (1 << 16)) : rv 122: when I32 123: (rv >= (1 << 31)) ? (rv - (1 << 32)) : rv 124: else 125: rv 126: end 127: end 128: end