module FDB::Tuple
def self.decode(v, pos)
def self.decode(v, pos) code = v.getbyte(pos) if code == @@NULL_CODE [nil, pos+1] elsif code == @@BYTES_CODE epos = find_terminator(v, pos+1) [v.slice(pos+1, epos-pos-1).gsub("\x00\xFF", "\x00"), epos+1] elsif code == @@STRING_CODE epos = find_terminator(v, pos+1) [v.slice(pos+1, epos-pos-1).gsub("\x00\xFF", "\x00").force_encoding("UTF-8"), epos+1] elsif code >= @@INT_ZERO_CODE && code < @@POS_INT_END n = code - @@INT_ZERO_CODE [("\x00" * (8-n) + v.slice(pos+1, n)).unpack("Q>")[0], pos+n+1] elsif code > @@NEG_INT_START and code < @@INT_ZERO_CODE n = @@INT_ZERO_CODE - code [("\x00" * (8-n) + v.slice(pos+1, n)).unpack("Q>")[0]-@@size_limits[n], pos+n+1] elsif code == @@POS_INT_END length = v.getbyte(pos+1) val = 0 length.times do |i| val = val << 8 val += v.getbyte(pos+2+i) end [val, pos+length+2] elsif code == @@NEG_INT_START length = v.getbyte(pos+1) ^ 0xff val = 0 length.times do |i| val = val << 8 val += v.getbyte(pos+2+i) end [val - (1 << (length*8)) + 1, pos+length+2] elsif code == @@FALSE_CODE [false, pos+1] elsif code == @@TRUE_CODE [true, pos+1] elsif code == @@FLOAT_CODE [SingleFloat.new(float_adjust(v, pos+1, 4, false).unpack("g")[0]), pos+5] elsif code == @@DOUBLE_CODE [float_adjust(v, pos+1, 8, false).unpack("G")[0], pos+9] elsif code == @@UUID_CODE [UUID.new(v.slice(pos+1, 16)), pos+17] elsif code == @@NESTED_CODE epos = pos+1 nested = [] while epos < v.length if v.getbyte(epos) == @@NULL_CODE if epos+1 < v.length and v.getbyte(epos+1) == 0xFF nested << nil epos += 2 else break end else r, epos = decode(v, epos) nested << r end end [nested, epos+1] else raise "Unknown data type in DB: " + code.ord.to_s end end