summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Bridgen <mikeb@lshift.net>2009-11-10 18:01:05 +0000
committerMichael Bridgen <mikeb@lshift.net>2009-11-10 18:01:05 +0000
commit5a7c82fdd3749dd3f12ee72ce5ebd6b78c6af96b (patch)
tree2e52755e9fbe48324dde4f4463e312508eac2bfa
parent88433c43c79f45b045656aa26e11650776d003d8 (diff)
downloadrabbitmq-server-5a7c82fdd3749dd3f12ee72ce5ebd6b78c6af96b.tar.gz
Refactoring of encoding code, so that it uses the table encoding erm,
code. Test case which mostly exercises the table encoding code.
-rw-r--r--src/rabbit_binary_generator.erl95
-rw-r--r--src/rabbit_tests.erl47
2 files changed, 86 insertions, 56 deletions
diff --git a/src/rabbit_binary_generator.erl b/src/rabbit_binary_generator.erl
index 6cfa9e6d..3e0e99a0 100644
--- a/src/rabbit_binary_generator.erl
+++ b/src/rabbit_binary_generator.erl
@@ -132,52 +132,66 @@ create_frame(TypeInt, ChannelInt, Payload) ->
%% I, D, T and F, as well as the QPid extensions b, d, f, l, s, t, x,
%% and V.
-table_field_to_binary({FName, longstr, Value}) ->
- [short_string_to_binary(FName), "S", long_string_to_binary(Value)];
+table_field_to_binary({FName, Type, Value}) ->
+ [short_string_to_binary(FName) | field_value_to_binary(Type, Value)].
-table_field_to_binary({FName, signedint, Value}) ->
- [short_string_to_binary(FName), "I", <<Value:32/signed>>];
+field_value_to_binary(longstr, Value) ->
+ ["S", long_string_to_binary(Value)];
-table_field_to_binary({FName, decimal, {Before, After}}) ->
- [short_string_to_binary(FName), "D", Before, <<After:32>>];
+field_value_to_binary(signedint, Value) ->
+ ["I", <<Value:32/signed>>];
-table_field_to_binary({FName, timestamp, Value}) ->
- [short_string_to_binary(FName), "T", <<Value:64>>];
+field_value_to_binary(decimal, {Before, After}) ->
+ ["D", Before, <<After:32>>];
-table_field_to_binary({FName, table, Value}) ->
- [short_string_to_binary(FName), "F", table_to_binary(Value)];
+field_value_to_binary(timestamp, Value) ->
+ ["T", <<Value:64>>];
-table_field_to_binary({FName, byte, Value}) ->
- [short_string_to_binary(FName), "b", <<Value:8/unsigned>>];
+field_value_to_binary(table, Value) ->
+ ["F", table_to_binary(Value)];
-table_field_to_binary({FName, double, Value}) ->
- [short_string_to_binary(FName), "d", <<Value:64/float>>];
+field_value_to_binary(array, Value) ->
+ ["A", array_to_binary(Value)];
-table_field_to_binary({FName, float, Value}) ->
- [short_string_to_binary(FName), "f", <<Value:32/float>>];
+field_value_to_binary(byte, Value) ->
+ ["b", <<Value:8/unsigned>>];
-table_field_to_binary({FName, long, Value}) ->
- [short_string_to_binary(FName), "l", <<Value:64/signed>>];
+field_value_to_binary(double, Value) ->
+ ["d", <<Value:64/float>>];
-table_field_to_binary({FName, short, Value}) ->
- [short_string_to_binary(FName), "s", <<Value:16/signed>>];
+field_value_to_binary(float, Value) ->
+ ["f", <<Value:32/float>>];
-table_field_to_binary({FName, bool, Value}) ->
- [short_string_to_binary(FName), "t", if Value -> 1; true -> 0 end];
+field_value_to_binary(long, Value) ->
+ ["l", <<Value:64/signed>>];
-table_field_to_binary({FName, binary, Value}) ->
- [short_string_to_binary(FName), "x", long_string_to_binary(Value)];
+field_value_to_binary(short, Value) ->
+ ["s", <<Value:16/signed>>];
-table_field_to_binary({FName, void, _Value}) ->
- [short_string_to_binary(FName), "V"].
+field_value_to_binary(bool, Value) ->
+ ["t", if Value -> 1; true -> 0 end];
+
+field_value_to_binary(binary, Value) ->
+ ["x", long_string_to_binary(Value)];
+
+field_value_to_binary(void, _Value) ->
+ ["V"].
table_to_binary(Table) when is_list(Table) ->
BinTable = generate_table(Table),
[<<(size(BinTable)):32>>, BinTable].
+array_to_binary(Array) when is_list(Array) ->
+ BinArray = generate_array(Array),
+ [<<(size(Array)):32>>, BinArray].
+
generate_table(Table) when is_list(Table) ->
list_to_binary(lists:map(fun table_field_to_binary/1, Table)).
+generate_array(Array) when is_list(Array) ->
+ list_to_binary(lists:map(
+ fun ({Type, Value}) -> field_value_to_binary(Type, Value) end,
+ Array)).
short_string_to_binary(String) when is_binary(String) and (size(String) < 256) ->
[<<(size(String)):8>>, String];
@@ -186,13 +200,11 @@ short_string_to_binary(String) ->
true = (StringLength < 256), % assertion
[<<StringLength:8>>, String].
-
long_string_to_binary(String) when is_binary(String) ->
[<<(size(String)):32>>, String];
long_string_to_binary(String) ->
[<<(length(String)):32>>, String].
-
encode_properties([], []) ->
<<0, 0>>;
encode_properties(TypeList, ValueList) ->
@@ -238,32 +250,7 @@ encode_property(longlongint, Int) ->
encode_property(timestamp, Int) ->
<<Int:64/unsigned>>;
encode_property(table, Table) ->
- encode_table(Table).
-
-
-encode_table(Table) ->
- TableBin = list_to_binary(lists:map(fun encode_table_entry/1, Table)),
- Len = size(TableBin),
- <<Len:32/unsigned, TableBin:Len/binary>>.
-
-
-encode_table_entry({Name, longstr, Value}) ->
- NLen = size(Name),
- VLen = size(Value),
- <<NLen:8/unsigned, Name:NLen/binary, "S", VLen:32/unsigned, Value:VLen/binary>>;
-encode_table_entry({Name, signedint, Value}) ->
- NLen = size(Name),
- <<NLen:8/unsigned, Name:NLen/binary, "I", Value:32/signed>>;
-encode_table_entry({Name, decimal, {Before, After}}) ->
- NLen = size(Name),
- <<NLen:8/unsigned, Name:NLen/binary, "D", Before:8/unsigned, After:32/unsigned>>;
-encode_table_entry({Name, timestamp, Value}) ->
- NLen = size(Name),
- <<NLen:8/unsigned, Name:NLen/binary, "T", Value:64/unsigned>>;
-encode_table_entry({Name, table, Value}) ->
- NLen = size(Name),
- TableBin = encode_table(Value),
- <<NLen:8/unsigned, Name:NLen/binary, "F", TableBin/binary>>.
+ table_to_binary(Table).
check_empty_content_body_frame_size() ->
%% Intended to ensure that EMPTY_CONTENT_BODY_FRAME_SIZE is
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index c5a7d05e..ef8822a3 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -193,6 +193,7 @@ test_unfold() ->
test_parsing() ->
passed = test_content_properties(),
+ passed = test_field_values(),
passed.
test_content_properties() ->
@@ -218,9 +219,12 @@ test_content_properties() ->
[{<<"one">>, signedint, 1},
{<<"two">>, signedint, 2}]}]}],
<<
- 16#8000:16, % flags
- % properties:
+ % property-flags
+ 16#8000:16,
+ % property-list:
+
+ % table
117:32, % table length in bytes
11,"a signedint", % name
@@ -249,6 +253,45 @@ test_content_properties() ->
V -> exit({got_success_but_expected_failure, V})
end.
+test_field_values() ->
+ %% NB this does not test inexact numbers (double and float) yet,
+ %% because they won't pass the equality assertions
+ test_content_prop_roundtrip(
+ [{table, [{<<"longstr">>, longstr, <<"Here is a long string">>},
+ {<<"signedint">>, signedint, 12345},
+ {<<"decimal">>, decimal, {3, 123456}},
+ {<<"timestamp">>, timestamp, 109876543209876},
+ {<<"table">>, table, [{<<"one">>, signedint, 54321},
+ {<<"two">>, longstr, <<"A long string">>}]},
+ {<<"byte">>, byte, 255},
+ {<<"long">>, long, 1234567890},
+ {<<"short">>, short, 655},
+ {<<"bool">>, bool, true},
+ {<<"binary">>, binary, <<"a binary string">>},
+ {<<"void">>, void, undefined}
+ ]}],
+ <<
+ % property-flags
+ 16#8000:16,
+ % table length in bytes
+ 194:32,
+
+ 7,"longstr", "S", 21:32, "Here is a long string", % = 34
+ 9,"signedint", "I", 12345:32/signed, % + 15 = 49
+ 7,"decimal", "D", 3, 123456:32, % + 14 = 63
+ 9,"timestamp", "T", 109876543209876:64, % + 19 = 82
+ 5,"table", "F", 31:32, % length of table + 11 = 93
+ 3,"one", "I", 54321:32, % + 9 = 102
+ 3,"two", "S", 13:32, "A long string",% + 22 = 124
+ 4,"byte", "b", 255:8, % + 7 = 131
+ 4,"long", "l", 1234567890:64, % + 14 = 145
+ 5,"short", "s", 655:16, % + 9 = 154
+ 4,"bool", "t", 1, % + 7 = 161
+ 6,"binary", "x", 15:32, "a binary string", % + 27 = 188
+ 4,"void", "V" % + 6 = 194
+ >>),
+ passed.
+
test_topic_match(P, R) ->
test_topic_match(P, R, true).