summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Bridgen <mikeb@lshift.net>2009-11-11 16:06:42 +0000
committerMichael Bridgen <mikeb@lshift.net>2009-11-11 16:06:42 +0000
commit3281811ad1d2a066241ed670fbfe6ea76738058d (patch)
treedffc990f456c863a896643efc04dcb7374250a51
parent8392aa492f3ff4d503c7b635568a9defeefe51be (diff)
downloadrabbitmq-server-bug21929.tar.gz
Support field-arrays in the parser. This involves a similar factoringbug21929
of field-value to the generator (since field-value is used both for field-table and field-array). Also fixed a dumb mistake in the array bit of rabbit_binary_generator.
-rw-r--r--src/rabbit_binary_generator.erl2
-rw-r--r--src/rabbit_binary_parser.erl65
-rw-r--r--src/rabbit_tests.erl14
3 files changed, 49 insertions, 32 deletions
diff --git a/src/rabbit_binary_generator.erl b/src/rabbit_binary_generator.erl
index 3e0e99a0..01ac4f02 100644
--- a/src/rabbit_binary_generator.erl
+++ b/src/rabbit_binary_generator.erl
@@ -183,7 +183,7 @@ table_to_binary(Table) when is_list(Table) ->
array_to_binary(Array) when is_list(Array) ->
BinArray = generate_array(Array),
- [<<(size(Array)):32>>, BinArray].
+ [<<(size(BinArray)):32>>, BinArray].
generate_table(Table) when is_list(Table) ->
list_to_binary(lists:map(fun table_field_to_binary/1, Table)).
diff --git a/src/rabbit_binary_parser.erl b/src/rabbit_binary_parser.erl
index 4ef382aa..506e87ec 100644
--- a/src/rabbit_binary_parser.erl
+++ b/src/rabbit_binary_parser.erl
@@ -56,45 +56,57 @@
parse_table(<<>>) ->
[];
+parse_table(<<NLen:8/unsigned, NameString:NLen/binary, ValueAndRest/binary>>) ->
+ {Type, Value, Rest} = parse_field_value(ValueAndRest),
+ [{NameString, Type, Value} | parse_table(Rest)].
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "S", VLen:32/unsigned, ValueString:VLen/binary, Rest/binary>>) ->
- [{NameString, longstr, ValueString} | parse_table(Rest)];
+parse_array(<<>>) ->
+ [];
+parse_array(<<ValueAndRest/binary>>) ->
+ {Type, Value, Rest} = parse_field_value(ValueAndRest),
+ [{Type, Value} | parse_array(Rest)].
+
+parse_field_value(<<"S", VLen:32/unsigned, ValueString:VLen/binary, Rest/binary>>) ->
+ {longstr, ValueString, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "I", Value:32/signed, Rest/binary>>) ->
- [{NameString, signedint, Value} | parse_table(Rest)];
+parse_field_value(<<"I", Value:32/signed, Rest/binary>>) ->
+ {signedint, Value, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "D", Before:8/unsigned, After:32/unsigned, Rest/binary>>) ->
- [{NameString, decimal, {Before, After}} | parse_table(Rest)];
+parse_field_value(<<"D", Before:8/unsigned, After:32/unsigned, Rest/binary>>) ->
+ {decimal, {Before, After}, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "T", Value:64/unsigned, Rest/binary>>) ->
- [{NameString, timestamp, Value} | parse_table(Rest)];
+parse_field_value(<<"T", Value:64/unsigned, Rest/binary>>) ->
+ {timestamp, Value, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "F", VLen:32/unsigned, Table:VLen/binary, Rest/binary>>) ->
- [{NameString, table, parse_table(Table)} | parse_table(Rest)];
+parse_field_value(<<"F", VLen:32/unsigned, Table:VLen/binary, Rest/binary>>) ->
+ {table, parse_table(Table), Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "b", Value:8/unsigned, Rest/binary>>) ->
- [{NameString, byte, Value} | parse_table(Rest)];
+parse_field_value(<<"A", VLen:32/unsigned, Array:VLen/binary, Rest/binary>>) ->
+ {array, parse_array(Array), Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "d", Value:64/float, Rest/binary>>) ->
- [{NameString, double, Value} | parse_table(Rest)];
+parse_field_value(<<"b", Value:8/unsigned, Rest/binary>>) ->
+ {byte, Value, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "f", Value:32/float, Rest/binary>>) ->
- [{NameString, float, Value} | parse_table(Rest)];
+parse_field_value(<<"d", Value:64/float, Rest/binary>>) ->
+ {double, Value, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "l", Value:64/signed, Rest/binary>>) ->
- [{NameString, long, Value} | parse_table(Rest)];
+parse_field_value(<<"f", Value:32/float, Rest/binary>>) ->
+ {float, Value, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "s", Value:16/signed, Rest/binary>>) ->
- [{NameString, short, Value} | parse_table(Rest)];
+parse_field_value(<<"l", Value:64/signed, Rest/binary>>) ->
+ {long, Value, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "t", Value:8/unsigned, Rest/binary>>) ->
- [{NameString, bool, (Value /= 0)} | parse_table(Rest)];
+parse_field_value(<<"s", Value:16/signed, Rest/binary>>) ->
+ {short, Value, Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "x", VLen:32/unsigned, ValueString:VLen/binary, Rest/binary>>) ->
- [{NameString, binary, ValueString} | parse_table(Rest)];
+parse_field_value(<<"t", Value:8/unsigned, Rest/binary>>) ->
+ {bool, (Value /= 0), Rest};
-parse_table(<<NLen:8/unsigned, NameString:NLen/binary, "V", Rest/binary>>) ->
- [{NameString, void, undefined} | parse_table(Rest)].
+parse_field_value(<<"x", VLen:32/unsigned, ValueString:VLen/binary, Rest/binary>>) ->
+ {binary, ValueString, Rest};
+
+parse_field_value(<<"V", Rest/binary>>) ->
+ {void, undefined, Rest}.
parse_properties([], _PropBin) ->
@@ -147,7 +159,6 @@ parse_property(bit, Rest) ->
parse_property(table, <<Len:32/unsigned, Table:Len/binary, Rest/binary>>) ->
{parse_table(Table), Rest}.
-
ensure_content_decoded(Content = #content{properties = Props})
when Props =/= 'none' ->
Content;
diff --git a/src/rabbit_tests.erl b/src/rabbit_tests.erl
index baa59a19..ba048184 100644
--- a/src/rabbit_tests.erl
+++ b/src/rabbit_tests.erl
@@ -254,7 +254,7 @@ test_content_properties() ->
end.
test_field_values() ->
- %% NB this does not test inexact numbers (double and float) yet,
+ %% FIXME 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">>},
@@ -268,13 +268,16 @@ test_field_values() ->
{<<"short">>, short, 655},
{<<"bool">>, bool, true},
{<<"binary">>, binary, <<"a binary string">>},
- {<<"void">>, void, undefined}
+ {<<"void">>, void, undefined},
+ {<<"array">>, array, [{signedint, 54321},
+ {longstr, <<"A long string">>}]}
+
]}],
<<
% property-flags
16#8000:16,
% table length in bytes
- 194:32,
+ 228:32,
7,"longstr", "S", 21:32, "Here is a long string", % = 34
9,"signedint", "I", 12345:32/signed, % + 15 = 49
@@ -288,7 +291,10 @@ test_field_values() ->
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
+ 4,"void", "V", % + 6 = 194
+ 5,"array", "A", 23:32, % + 11 = 205
+ "I", 54321:32, % + 5 = 210
+ "S", 13:32, "A long string" % + 18 = 228
>>),
passed.