Skip to content
This repository has been archived by the owner on Jan 2, 2023. It is now read-only.

Commit

Permalink
Fixed Decoding#read_long! and Decoding#read_int! for negative values
Browse files Browse the repository at this point in the history
- Added specs for bigint, counter and int decoding.
- Added unit test to Decoding#read_int! for negative values
  • Loading branch information
leobessa authored and iconara committed Aug 4, 2013
1 parent 57c1e76 commit dbed04b
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 5 deletions.
16 changes: 13 additions & 3 deletions lib/cql/protocol/decoding.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,14 @@ def read_decimal!(buffer, length=buffer.length)
end

def read_long!(buffer)
top, bottom = buffer.read(8).unpack(Formats::TWO_INTS_FORMAT)
(top << 32) | bottom
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
Expand All @@ -57,7 +63,11 @@ def read_float!(buffer)
end

def read_int!(buffer)
buffer.read_int
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
Expand Down
14 changes: 12 additions & 2 deletions spec/cql/protocol/decoding_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,16 @@ module Protocol
end

describe '#read_long!' do
it 'decodes a long' do
it 'decodes a positive long' do
buffer = ByteBuffer.new("\x00\x00\xca\xfe\xba\xbe\x00\x00")
Decoding.read_long!(buffer).should == 0x0000cafebabe0000
end

it 'decodes a negative long' do
buffer = ByteBuffer.new("\xff\xff\xff\xff\xff\xff\xff\xff")
Decoding.read_long!(buffer).should == -1
end

it 'consumes the bytes' do
buffer = ByteBuffer.new("\xca\xfe\xba\xbe\xca\xfe\xba\xbe\xca\xfe\xba\xbe")
Decoding.read_long!(buffer)
Expand Down Expand Up @@ -137,10 +142,15 @@ module Protocol
ByteBuffer.new("\x00\xff\x00\xff")
end

it 'decodes an int' do
it 'decodes a positive int' do
Decoding.read_int!(buffer).should == 0x00ff00ff
end

it 'decodes a negative int' do
buffer = ByteBuffer.new("\xff\xff\xff\xff")
Decoding.read_int!(buffer).should == -1
end

it 'consumes the bytes' do
buffer << "\xab\xcd"
Decoding.read_int!(buffer)
Expand Down
70 changes: 70 additions & 0 deletions spec/integration/protocol_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,76 @@ def in_keyspace_with_counters_table
end
end

it 'decodes positive counters' do
in_keyspace_with_counters_table do
max_long = (1 << 63) -1
response = query(%<UPDATE counters SET c1 = c1 + 1, c2 = c2 +#{max_long} WHERE id = 'positive'>)
response = query(%<SELECT * FROM counters>, :quorum)
response.rows.should == [
{'id' => 'positive', 'c1' => 1, 'c2' => max_long},
]
end
end

it 'decodes negative counters' do
in_keyspace_with_counters_table do
min_long = 0 - (1 << 63)
response = query(%<UPDATE counters SET c1 = c1 - 1 , c2 = c2 -#{min_long.abs} WHERE id = 'negative'>)
response = query(%<SELECT * FROM counters>, :quorum)
response.rows.should == [
{'id' => 'negative', 'c1' => -1 , 'c2' => min_long}
]
end
end

it 'decodes positive bigints' do
in_keyspace do
max_long = (1 << 63) -1
response = query('CREATE TABLE stuff (id VARCHAR, c1 bigint, c2 bigint, PRIMARY KEY (id))')
response = query(%<UPDATE stuff SET c1 = 1, c2 = #{max_long} WHERE id = 'stuff'>)
response = query(%<SELECT * FROM stuff>, :quorum)
response.rows.should == [
{'id' => 'stuff', 'c1' => 1, 'c2' => max_long}
]
end
end

it 'decodes negative bigints' do
in_keyspace do
min_long = 0 - (1 << 63)
response = query('CREATE TABLE stuff (id VARCHAR, c1 bigint, c2 bigint, PRIMARY KEY (id))')
response = query(%<UPDATE stuff SET c1 = -1, c2 = #{min_long} WHERE id = 'stuff'>)
response = query(%<SELECT * FROM stuff>, :quorum)
response.rows.should == [
{'id' => 'stuff', 'c1' => -1, 'c2' => min_long}
]
end
end

it 'decodes positive ints' do
in_keyspace do
max_int = (1 << 31) -1
response = query('CREATE TABLE stuff (id VARCHAR, c1 int, c2 int, PRIMARY KEY (id))')
response = query(%<UPDATE stuff SET c1 = 1, c2 = #{max_int} WHERE id = 'stuff'>)
response = query(%<SELECT * FROM stuff>, :quorum)
response.rows.should == [
{'id' => 'stuff', 'c1' => 1, 'c2' => max_int}
]
end
end

it 'decodes negative ints' do
in_keyspace do
min_int = 0 - (1 << 31)
response = query('CREATE TABLE stuff (id VARCHAR, c1 int, c2 int, PRIMARY KEY (id))')
response = query(%<UPDATE stuff SET c1 = -1, c2 = #{min_int} WHERE id = 'stuff'>)
response = query(%<SELECT * FROM stuff>, :quorum)
response.rows.should == [
{'id' => 'stuff', 'c1' => -1, 'c2' => min_int}
]
end
end

it 'sends a DELETE command' do
in_keyspace_with_table do
response = query(%<DELETE email FROM users WHERE user_name = 'sue'>)
Expand Down

0 comments on commit dbed04b

Please sign in to comment.