class Cql::Protocol::CqlByteBuffer

Constants

DECIMAL_POINT
FLOAT_STRING_FORMAT
MINUS
NO_CHAR
ZERO

Public Instance Methods

append_bytes(bytes) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 211
def append_bytes(bytes)
  if bytes
    append_int(bytes.bytesize)
    append(bytes)
  else
    append_int(-1)
  end
end
append_consistency(consistency) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 229
def append_consistency(consistency)
  index = CONSISTENCIES.index(consistency)
  raise EncodingError, %(Unknown consistency "#{consistency}") if index.nil? || CONSISTENCIES[index].nil?
  append_short(index)
end
append_decimal(n) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 261
def append_decimal(n)
  str = n.to_s(FLOAT_STRING_FORMAT)
  size = str.index(DECIMAL_POINT)
  number_string = str.gsub(DECIMAL_POINT, NO_CHAR)

  num = number_string.to_i
  raw = self.class.new.append_varint(num)
  append_int(number_string.length - size)
  append(raw)
end
append_double(n) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 272
def append_double(n)
  append([n].pack(Formats::DOUBLE_FORMAT))
end
append_float(n) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 276
def append_float(n)
  append([n].pack(Formats::FLOAT_FORMAT))
end
append_int(n) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 176
def append_int(n)
  append([n].pack(Formats::INT_FORMAT))
end
append_long(n) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 244
def append_long(n)
  top = n >> 32
  bottom = n & 0xffffffff
  append_int(top)
  append_int(bottom)
end
append_long_string(str) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 190
def append_long_string(str)
  append_int(str.bytesize)
  append(str)
end
append_short(n) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 180
def append_short(n)
  append([n].pack(Formats::SHORT_FORMAT))
end
append_short_bytes(bytes) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 220
def append_short_bytes(bytes)
  if bytes
    append_short(bytes.bytesize)
    append(bytes)
  else
    append_short(-1)
  end
end
append_string(str) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 184
def append_string(str)
  str = str.to_s
  append_short(str.bytesize)
  append(str)
end
append_string_list(strs) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 203
def append_string_list(strs)
  append_short(strs.size)
  strs.each do |str|
    append_string(str)
  end
  self
end
append_string_map(map) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 235
def append_string_map(map)
  append_short(map.size)
  map.each do |key, value|
    append_string(key)
    append_string(value)
  end
  self
end
append_uuid(uuid) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 195
def append_uuid(uuid)
  v = uuid.value
  append_int((v >> 96) & 0xffffffff)
  append_int((v >> 64) & 0xffffffff)
  append_int((v >> 32) & 0xffffffff)
  append_int((v >>  0) & 0xffffffff)
end
append_varint(n) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 251
def append_varint(n)
  num = n
  bytes = []
  begin
    bytes << (num & 0xff)
    num >>= 8
  end until (num == 0 || num == -1) && (bytes.last[7] == num[7])
  append(bytes.reverse.pack(Formats::BYTES_FORMAT))
end
read_bytes() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 116
def read_bytes
  size = read_signed_int
  return nil if size & 0x80000000 == 0x80000000
  read(size)
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a bytes: #{e.message}", e.backtrace
end
read_consistency() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 150
def read_consistency
  index = read_unsigned_short
  raise DecodingError, "Unknown consistency index #{index}" if index >= CONSISTENCIES.size || CONSISTENCIES[index].nil?
  CONSISTENCIES[index]
end
read_decimal(len=bytesize) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 29
def read_decimal(len=bytesize)
  size = read_signed_int
  number_string = read_varint(len - 4).to_s
  if number_string.length <= size
    if number_string.start_with?(MINUS)
      number_string = number_string[1, number_string.length - 1]
      fraction_string = MINUS + ZERO << DECIMAL_POINT
    else
      fraction_string = ZERO + DECIMAL_POINT
    end
    (size - number_string.length).times { fraction_string << ZERO }
    fraction_string << number_string
  else
    fraction_string = number_string[0, number_string.length - size]
    fraction_string << DECIMAL_POINT
    fraction_string << number_string[number_string.length - size, number_string.length]
  end
  BigDecimal.new(fraction_string)
rescue DecodingError => e
  raise DecodingError, e.message, e.backtrace
end
read_double() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 61
def read_double
  read(8).unpack(Formats::DOUBLE_FORMAT).first
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a double: #{e.message}", e.backtrace
end
read_float() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 67
def read_float
  read(4).unpack(Formats::FLOAT_FORMAT).first
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a float: #{e.message}", e.backtrace
end
read_inet() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 141
def read_inet
  size = read_byte
  ip_addr = IPAddr.new_ntoh(read(size))
  port = read_int
  [ip_addr, port]
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode an INET: #{e.message}", e.backtrace
end
read_long() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 51
def read_long
  top, bottom = read(8).unpack(Formats::TWO_INTS_FORMAT)
  return (top << 32) | bottom if top <= 0x7fffffff
  top ^= 0xffffffff
  bottom ^= 0xffffffff
  -((top << 32) | bottom) - 1
rescue RangeError => e
  raise DecodingError, e.message, e.backtrace
end
read_long_string() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 96
def read_long_string
  length = read_signed_int
  string = read(length)
  string.force_encoding(::Encoding::UTF_8)
  string
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a long string: #{e.message}", e.backtrace
end
read_option() { |id, self| ... } click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 132
def read_option
  id = read_unsigned_short
  value = nil
  if block_given?
    value = yield id, self
  end
  [id, value]
end
read_short_bytes() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 124
def read_short_bytes
  size = read_unsigned_short
  return nil if size & 0x8000 == 0x8000
  read(size)
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a short bytes: #{e.message}", e.backtrace
end
read_signed_int() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 73
def read_signed_int
  n = read_int
  return n if n <= 0x7fffffff
  n - 0xffffffff - 1
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode an int: #{e.message}", e.backtrace
end
read_string() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 87
def read_string
  length = read_unsigned_short
  string = read(length)
  string.force_encoding(::Encoding::UTF_8)
  string
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a string: #{e.message}", e.backtrace
end
read_string_list() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 111
def read_string_list
  size = read_unsigned_short
  Array.new(size) { read_string }
end
read_string_map() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 156
def read_string_map
  map = {}
  map_size = read_unsigned_short
  map_size.times do
    key = read_string
    map[key] = read_string
  end
  map
end
read_string_multimap() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 166
def read_string_multimap
  map = {}
  map_size = read_unsigned_short
  map_size.times do
    key = read_string
    map[key] = read_string_list
  end
  map
end
read_unsigned_byte() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 9
def read_unsigned_byte
  read_byte
rescue RangeError => e
  raise DecodingError, e.message, e.backtrace
end
read_unsigned_short() click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 81
def read_unsigned_short
  read_short
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a short: #{e.message}", e.backtrace
end
read_uuid(impl=Uuid) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 105
def read_uuid(impl=Uuid)
  impl.new(read_varint(16, false))
rescue DecodingError => e
  raise DecodingError, "Not enough bytes available to decode a UUID: #{e.message}", e.backtrace
end
read_varint(len=bytesize, signed=true) click to toggle source
# File lib/cql/protocol/cql_byte_buffer.rb, line 15
def read_varint(len=bytesize, signed=true)
  bytes = read(len)
  n = 0
  bytes.each_byte do |b|
    n = (n << 8) | b
  end
  if signed && bytes.getbyte(0) & 0x80 == 0x80
    n -= 2**(bytes.length * 8)
  end
  n
rescue RangeError => e
  raise DecodingError, e.message, e.backtrace
end