module FDB::Tuple

def self.encode(v, nested=false)

def self.encode(v, nested=false)
  if v.nil?
    if nested
      "\x00\xFF"
    else
      @@NULL_CODE.chr
    end
  elsif v.kind_of? String
    if v.encoding == Encoding::BINARY || v.encoding == Encoding::ASCII
      @@BYTES_CODE.chr + v.gsub("\x00", "\x00\xFF") + 0.chr
    elsif v.encoding == Encoding::UTF_8
      @@STRING_CODE.chr + v.dup.force_encoding("BINARY").gsub("\x00", "\x00\xFF") + 0.chr
    else
      raise ArgumentError, "unsupported encoding #{v.encoding.name}"
    end
  elsif v.kind_of? Integer
    raise RangeError, "Integer magnitude is too large (more than 255 bytes)" if v < -2**2040+1 || v > 2**2040-1
    if v == 0
      @@INT_ZERO_CODE.chr
    elsif v > 0
      if v > @@size_limits[-1]
        length = (v.bit_length + 7) / 8
        result = @@POS_INT_END.chr + length.chr
        length.times do |i|
          result << ((v >> (8 * (length-i-1))) & 0xff)
        end
        result
      else
        n = bisect_left( @@size_limits, v )
        (@@INT_ZERO_CODE+n).chr + [v].pack("Q>").slice(8-n, n)
      end
    else
      if -v > @@size_limits[-1]
        length = ((-v).bit_length + 7) / 8
        v += (1 << (length * 8)) - 1
        result = @@NEG_INT_START.chr + (length ^ 0xff).chr
        length.times do |i|
          result << ((v >> (8 * (length-i-1))) & 0xff)
        end
        result
      else
        n = bisect_left( @@size_limits, -v )
        (@@INT_ZERO_CODE-n).chr + [@@size_limits[n]+v].pack("Q>").slice(8-n, n)
      end
    end
  elsif v.kind_of? TrueClass
    @@TRUE_CODE.chr
  elsif v.kind_of? FalseClass
    @@FALSE_CODE.chr
  elsif v.kind_of? SingleFloat
    @@FLOAT_CODE.chr + float_adjust([v.value].pack("g"), 0, 4, true)
  elsif v.kind_of? Float
    @@DOUBLE_CODE.chr + float_adjust([v].pack("G"), 0, 8, true)
  elsif v.kind_of? UUID
    @@UUID_CODE.chr + v.data
  elsif v.kind_of? Array
    @@NESTED_CODE.chr + (v.map { |el| encode(el, true).force_encoding("BINARY") }).join + 0.chr
  else
    raise ArgumentError, "unsupported type #{v.class}"
  end
end