Module: Cql::Protocol::Decoding

Extended by:
Decoding
Included in:
Decoding, Response, TypeConverter
Defined in:
lib/cql/protocol/decoding.rb

Instance Method Summary collapse

Instance Method Details

#read_byte!(buffer) ⇒ Object



11
12
13
14
15
# File 'lib/cql/protocol/decoding.rb', line 11

def read_byte!(buffer)
  buffer.read_byte
rescue RangeError => e
  raise DecodingError, e.message, e.backtrace
end

#read_bytes!(buffer) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/cql/protocol/decoding.rb', line 112

def read_bytes!(buffer)
  size = read_int!(buffer)
  return nil if size & 0x80000000 == 0x80000000
  buffer.read(size)
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a bytes: #{e.message}", e.backtrace
end

#read_consistency!(buffer) ⇒ Object

Raises:



146
147
148
149
150
# File 'lib/cql/protocol/decoding.rb', line 146

def read_consistency!(buffer)
  index = read_short!(buffer)
  raise DecodingError, "Unknown consistency index #{index}" unless index < CONSISTENCIES.size
  CONSISTENCIES[index]
end

#read_decimal!(buffer, length = buffer.length) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/cql/protocol/decoding.rb', line 31

def read_decimal!(buffer, length=buffer.length)
  size = read_int!(buffer)
  number_string = read_varint!(buffer, length - 4).to_s
  fraction_string = number_string[0, number_string.length - size] << DECIMAL_POINT << number_string[number_string.length - size, number_string.length]
  BigDecimal.new(fraction_string)
rescue RangeError => e
  raise DecodingError, e.message, e.backtrace
end

#read_double!(buffer) ⇒ Object



53
54
55
56
57
# File 'lib/cql/protocol/decoding.rb', line 53

def read_double!(buffer)
  buffer.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!(buffer) ⇒ Object



59
60
61
62
63
# File 'lib/cql/protocol/decoding.rb', line 59

def read_float!(buffer)
  buffer.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!(buffer) ⇒ Object



137
138
139
140
141
142
143
144
# File 'lib/cql/protocol/decoding.rb', line 137

def read_inet!(buffer)
  size = read_byte!(buffer)
  ip_addr = IPAddr.new_ntoh(buffer.read(size))
  port = read_int!(buffer)
  [ip_addr, port]
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode an INET: #{e.message}", e.backtrace
end

#read_int!(buffer) ⇒ Object



65
66
67
68
69
70
71
72
73
# File 'lib/cql/protocol/decoding.rb', line 65

def read_int!(buffer)
  val = buffer.read_int
  if (val > 0x7fffffff)
    val = 0 - ((val - 1) ^ 0xffffffff)
  end
  val
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode an int: #{e.message}", e.backtrace
end

#read_long!(buffer) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/cql/protocol/decoding.rb', line 40

def read_long!(buffer)
  hi, lo = buffer.read(8).unpack(Formats::TWO_INTS_FORMAT)
  if (hi > 0x7fffffff)
    hi ^= 0xffffffff
    lo ^= 0xffffffff
    0 - (hi << 32) - lo - 1
  else
    (hi << 32) + lo
  end
rescue RangeError => e
  raise DecodingError, e.message, e.backtrace
end

#read_long_string!(buffer) ⇒ Object



90
91
92
93
94
95
96
97
# File 'lib/cql/protocol/decoding.rb', line 90

def read_long_string!(buffer)
  length = read_int!(buffer)
  string = buffer.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!(buffer) ⇒ Object



128
129
130
131
132
133
134
135
# File 'lib/cql/protocol/decoding.rb', line 128

def read_option!(buffer)
  id = read_short!(buffer)
  value = nil
  if block_given?
    value = yield id, buffer
  end
  [id, value]
end

#read_short!(buffer) ⇒ Object



75
76
77
78
79
# File 'lib/cql/protocol/decoding.rb', line 75

def read_short!(buffer)
  buffer.read_short
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a short: #{e.message}", e.backtrace
end

#read_short_bytes!(buffer) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/cql/protocol/decoding.rb', line 120

def read_short_bytes!(buffer)
  size = read_short!(buffer)
  return nil if size & 0x8000 == 0x8000
  buffer.read(size)
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a short bytes: #{e.message}", e.backtrace
end

#read_string!(buffer) ⇒ Object



81
82
83
84
85
86
87
88
# File 'lib/cql/protocol/decoding.rb', line 81

def read_string!(buffer)
  length = read_short!(buffer)
  string = buffer.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!(buffer) ⇒ Object



105
106
107
108
109
110
# File 'lib/cql/protocol/decoding.rb', line 105

def read_string_list!(buffer)
  size = read_short!(buffer)
  size.times.map do
    read_string!(buffer)
  end
end

#read_string_map!(buffer) ⇒ Object



152
153
154
155
156
157
158
159
160
# File 'lib/cql/protocol/decoding.rb', line 152

def read_string_map!(buffer)
  map = {}
  map_size = read_short!(buffer)
  map_size.times do
    key = read_string!(buffer)
    map[key] = read_string!(buffer)
  end
  map
end

#read_string_multimap!(buffer) ⇒ Object



162
163
164
165
166
167
168
169
170
# File 'lib/cql/protocol/decoding.rb', line 162

def read_string_multimap!(buffer)
  map = {}
  map_size = read_short!(buffer)
  map_size.times do
    key = read_string!(buffer)
    map[key] = read_string_list!(buffer)
  end
  map
end

#read_uuid!(buffer) ⇒ Object



99
100
101
102
103
# File 'lib/cql/protocol/decoding.rb', line 99

def read_uuid!(buffer)
  Uuid.new(read_varint!(buffer, 16, false))
rescue RangeError => e
  raise DecodingError, "Not enough bytes available to decode a UUID: #{e.message}", e.backtrace
end

#read_varint!(buffer, length = buffer.length, signed = true) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/cql/protocol/decoding.rb', line 17

def read_varint!(buffer, length=buffer.length, signed=true)
  bytes = buffer.read(length)
  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