Skip to content

Commit

Permalink
Serialize integer values in attribute tables (like message headers) a…
Browse files Browse the repository at this point in the history
…s 64 bit unsigned integers

This is what RabbitMQ Java client does to make it possible to specify realistic values for extensions
like x-message-ttl. See http://groups.google.com/group/ruby-amqp/browse_thread/thread/c1e142108b396fb1?hl=en for
the discussion.
  • Loading branch information
michaelklishin committed Oct 12, 2011
1 parent 3239bd5 commit 61da5c9
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 23 deletions.
4 changes: 2 additions & 2 deletions lib/amq/protocol/table_value_decoder.rb
Expand Up @@ -85,8 +85,8 @@ def self.decode_string(data, offset)


def self.decode_integer(data, offset)
v = data.slice(offset, 4).unpack(PACK_UINT32).first
offset += 4
v = AMQ::Hacks.unpack_64_big_endian(data.slice(offset, 8)).first
offset += 8

[v, offset]
end # self.decode_integer(data, offset)
Expand Down
4 changes: 2 additions & 2 deletions lib/amq/protocol/table_value_encoder.rb
Expand Up @@ -34,7 +34,7 @@ def self.encode(value)
accumulator << v
when Integer then
accumulator << TYPE_INTEGER
accumulator << [value].pack(PACK_UINT32)
accumulator << AMQ::Hacks.pack_64_big_endian(value)
when Float then
accumulator << TYPE_64BIT_FLOAT
accumulator << [value].pack(PACK_64BIT_FLOAT)
Expand Down Expand Up @@ -85,7 +85,7 @@ def self.field_value_size(value)
when String then
acc += (value.bytesize + 4)
when Integer then
acc += 4
acc += 8
when Float then
acc += 8
when Time, DateTime then
Expand Down
4 changes: 2 additions & 2 deletions spec/amq/protocol/table_spec.rb
Expand Up @@ -17,7 +17,7 @@ module Protocol
DATA = if one_point_eight?
{
{} => "\000\000\000\000",
{"test" => 1} => "\000\000\000\n\004testI\000\000\000\001",
{"test" => 1} => "\000\000\000\016\004testI\000\000\000\000\000\000\000\001",
{"float" => 1.87} => "\000\000\000\017\005floatd\354Q\270\036\205\353\375?",
{"test" => "string"} => "\000\000\000\020\004testS\000\000\000\006string",
{"test" => {}} => "\000\000\000\n\004testF\000\000\000\000",
Expand All @@ -28,7 +28,7 @@ module Protocol
else
{
{} => "\x00\x00\x00\x00",
{"test" => 1} => "\x00\x00\x00\n\x04testI\x00\x00\x00\x01",
{"test" => 1} => "\x00\x00\x00\x0E\x04testI\x00\x00\x00\x00\x00\x00\x00\x01",
{"float" => 1.92} => "\x00\x00\x00\x0F\x05floatd\xB8\x1E\x85\xEBQ\xB8\xFE?",
{"test" => "string"} => "\x00\x00\x00\x10\x04testS\x00\x00\x00\x06string",
{"test" => {}} => "\x00\x00\x00\n\x04testF\x00\x00\x00\x00",
Expand Down
33 changes: 16 additions & 17 deletions spec/amq/protocol/value_encoder_spec.rb
Expand Up @@ -21,8 +21,8 @@ module Protocol
end

it "calculates size of integer field values" do
described_class.field_value_size(10).should == 5
described_class.encode(10).bytesize.should == 5
described_class.field_value_size(10).should == 9
described_class.encode(10).bytesize.should == 9
end

it "calculates size of float field values (considering them to be 64-bit)" do
Expand Down Expand Up @@ -61,13 +61,13 @@ module Protocol


input2 = { "intval" => 1 }
described_class.field_value_size(input2).should == 17
described_class.encode(input2).bytesize.should == 17
described_class.field_value_size(input2).should == 21
described_class.encode(input2).bytesize.should == 21


input3 = { "intval" => 1, "key" => "value" }
described_class.field_value_size(input3).should == 31
described_class.encode(input3).bytesize.should == 31
described_class.field_value_size(input3).should == 35
described_class.encode(input3).bytesize.should == 35
end


Expand All @@ -90,9 +90,8 @@ module Protocol
}
}

described_class.field_value_size(input1).should == 162
# puts(described_class.encode(input1).inspect)
described_class.encode(input1).bytesize.should == 162
described_class.field_value_size(input1).should == 166
described_class.encode(input1).bytesize.should == 166



Expand All @@ -106,15 +105,15 @@ module Protocol
"hashval" => { "protocol" => "AMQP091", "true" => true, "false" => false, "nil" => nil }
}

described_class.field_value_size(input2).should == 150
described_class.encode(input2).bytesize.should == 150
described_class.field_value_size(input2).should == 158
described_class.encode(input2).bytesize.should == 158
end

it "calculates size of basic array field values" do
input1 = [1, 2, 3]

described_class.field_value_size(input1).should == 20
described_class.encode(input1).bytesize.should == 20
described_class.field_value_size(input1).should == 32
described_class.encode(input1).bytesize.should == 32


input2 = ["one", "two", "three"]
Expand All @@ -123,13 +122,13 @@ module Protocol


input3 = ["one", 2, "three"]
described_class.field_value_size(input3).should == 28
described_class.encode(input3).bytesize.should == 28
described_class.field_value_size(input3).should == 32
described_class.encode(input3).bytesize.should == 32


input4 = ["one", 2, "three", ["four", 5, [6.0]]]
described_class.field_value_size(input4).should == 61
described_class.encode(input4).bytesize.should == 61
described_class.field_value_size(input4).should == 69
described_class.encode(input4).bytesize.should == 69
end


Expand Down

0 comments on commit 61da5c9

Please sign in to comment.