diff options
author | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-10-17 16:51:23 +0100 |
---|---|---|
committer | Alexandru Scvortov <alexandru@rabbitmq.com> | 2011-10-17 16:51:23 +0100 |
commit | 68a318884b74919f98402bcf7378d394001fc719 (patch) | |
tree | 9cdfd020f764c2d3d7bb70a1f3912aa4c12b1914 | |
parent | a37dcf5877929df1ec3135884dfe65731672e43b (diff) | |
download | rabbitmq-server-68a318884b74919f98402bcf7378d394001fc719.tar.gz |
unroll property parser
The codegen code is quite ugly now; I'll see what I can do about that.
-rw-r--r-- | codegen.py | 50 | ||||
-rw-r--r-- | src/rabbit_binary_parser.erl | 55 |
2 files changed, 46 insertions, 59 deletions
@@ -42,7 +42,8 @@ erlangTypeMap = { def convertTable(d): if len(d) == 0: return "[]" - else: raise 'Non-empty table defaults not supported', d + else: + raise Exception('Non-empty table defaults not supported ' + d) erlangDefaultValueTypeConvMap = { bool : lambda x: str(x).lower(), @@ -229,9 +230,27 @@ def genErl(spec): print " %s;" % (recordConstructorExpr,) def genDecodeProperties(c): - print "decode_properties(%d, PropBin) ->" % (c.index) - print " %s = rabbit_binary_parser:parse_properties(%s, PropBin)," % \ - (fieldTempList(c.fields), fieldTypeList(c.fields)) + def presentBin(fields): + return '<<' + ', '.join(['P' + str(f.index) + ':1' for f in fields]) + ', _:2, R0/binary>>' + def mkMacroName(field): + return '?' + field.domain.upper() + '_PROP' + def writePropFieldLine(field, bin_next = None): + i = str(field.index) + if not bin_next: + i1 = str(field.index + 1) + bin_next = 'R' + i1 + if field.domain in ['octet', 'timestamp']: + print " {%s, %s} = %s(%s, %s, %s, %s)," % ('F' + i, bin_next, mkMacroName(field), 'P' + i, 'R' + i, 'I' + i, 'X' + i) + else: + print " {%s, %s} = %s(%s, %s, %s, %s, %s)," % ('F' + i, bin_next, mkMacroName(field), 'P' + i, 'R' + i, 'L' + i, 'S' + i, 'X' + i) + + if len(c.fields) == 0: + print "decode_properties(%d, _) ->" % (c.index) + else: + print "decode_properties(%d, %s) ->" % (c.index, presentBin(c.fields)) + for field in c.fields[:-1]: + writePropFieldLine(field) + writePropFieldLine(c.fields[-1], "<<>>") print " #'P_%s'{%s};" % (erlangize(c.name), fieldMapList(c.fields)) def genFieldPreprocessing(packed): @@ -272,7 +291,7 @@ def genErl(spec): if mCls == 'SOFT_ERROR': genLookupException1(c,'false') elif mCls == 'HARD_ERROR': genLookupException1(c, 'true') elif mCls == '': pass - else: raise 'Unknown constant class', cls + else: raise Exception('Unknown constant class' + cls) def genLookupException1(c,hardErrorBoolStr): n = erlangConstantName(c) @@ -404,6 +423,27 @@ shortstr_size(S) -> Len when Len =< 255 -> Len; _ -> exit(method_field_shortstr_overflow) end. + +-define(SHORTSTR_PROP(P, R, L, S, X), + if P =:= 0 -> {undefined, R}; + true -> <<L:8/unsigned, S:L/binary, X/binary>> = R, + {S, X} + end). +-define(TABLE_PROP(P, R, L, T, X), + if P =:= 0 -> {undefined, R}; + true -> <<L:32/unsigned, T:L/binary, X/binary>> = R, + {rabbit_binary_parser:parse_table(T), X} + end). +-define(OCTET_PROP(P, R, I, X), + if P =:= 0 -> {undefined, R}; + true -> <<I:8/unsigned, X/binary>> = R, + {I, X} + end). +-define(TIMESTAMP_PROP(P, R, I, X), + if P =:= 0 -> {undefined, R}; + true -> <<I:64/unsigned, X/binary>> = R, + {I, X} + end). """ version = "{%d, %d, %d}" % (spec.major, spec.minor, spec.revision) if version == '{8, 0, 0}': version = '{0, 8, 0}' diff --git a/src/rabbit_binary_parser.erl b/src/rabbit_binary_parser.erl index 88026bab..f3ca4e98 100644 --- a/src/rabbit_binary_parser.erl +++ b/src/rabbit_binary_parser.erl @@ -18,7 +18,7 @@ -include("rabbit.hrl"). --export([parse_table/1, parse_properties/2]). +-export([parse_table/1]). -export([ensure_content_decoded/1, clear_decoded_content/1]). %%---------------------------------------------------------------------------- @@ -26,8 +26,6 @@ -ifdef(use_specs). -spec(parse_table/1 :: (binary()) -> rabbit_framing:amqp_table()). --spec(parse_properties/2 :: - ([rabbit_framing:amqp_property_type()], binary()) -> [any()]). -spec(ensure_content_decoded/1 :: (rabbit_types:content()) -> rabbit_types:decoded_content()). -spec(clear_decoded_content/1 :: @@ -94,57 +92,6 @@ parse_field_value(<<"x", VLen:32/unsigned, ValueString:VLen/binary, Rest/binary> parse_field_value(<<"V", Rest/binary>>) -> {void, undefined, Rest}. - -parse_properties([], _PropBin) -> - []; -parse_properties(TypeList, PropBin) -> - FlagCount = length(TypeList), - %% round up to the nearest multiple of 15 bits, since the 16th bit - %% in each short is a "continuation" bit. - FlagsLengthBytes = trunc((FlagCount + 14) / 15) * 2, - <<Flags:FlagsLengthBytes/binary, Properties/binary>> = PropBin, - <<FirstShort:16, Remainder/binary>> = Flags, - parse_properties(0, TypeList, [], FirstShort, Remainder, Properties). - -parse_properties(_Bit, [], Acc, _FirstShort, - _Remainder, <<>>) -> - lists:reverse(Acc); -parse_properties(_Bit, [], _Acc, _FirstShort, - _Remainder, _LeftoverBin) -> - exit(content_properties_binary_overflow); -parse_properties(15, TypeList, Acc, _OldFirstShort, - <<NewFirstShort:16,Remainder/binary>>, Properties) -> - parse_properties(0, TypeList, Acc, NewFirstShort, Remainder, Properties); -parse_properties(Bit, [Type | TypeListRest], Acc, FirstShort, - Remainder, Properties) -> - {Value, Rest} = - if (FirstShort band (1 bsl (15 - Bit))) /= 0 -> - parse_property(Type, Properties); - Type == bit -> {false , Properties}; - true -> {undefined, Properties} - end, - parse_properties(Bit + 1, TypeListRest, [Value | Acc], FirstShort, - Remainder, Rest). - -parse_property(shortstr, <<Len:8/unsigned, String:Len/binary, Rest/binary>>) -> - {String, Rest}; -parse_property(longstr, <<Len:32/unsigned, String:Len/binary, Rest/binary>>) -> - {String, Rest}; -parse_property(octet, <<Int:8/unsigned, Rest/binary>>) -> - {Int, Rest}; -parse_property(shortint, <<Int:16/unsigned, Rest/binary>>) -> - {Int, Rest}; -parse_property(longint, <<Int:32/unsigned, Rest/binary>>) -> - {Int, Rest}; -parse_property(longlongint, <<Int:64/unsigned, Rest/binary>>) -> - {Int, Rest}; -parse_property(timestamp, <<Int:64/unsigned, Rest/binary>>) -> - {Int, Rest}; -parse_property(bit, Rest) -> - {true, 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; |