diff options
| author | Matthias Radestock <matthias@rabbitmq.com> | 2012-11-05 12:22:21 +0000 |
|---|---|---|
| committer | Matthias Radestock <matthias@rabbitmq.com> | 2012-11-05 12:22:21 +0000 |
| commit | ec58eb9caf0b399afbd2c7e37c3f79d47d1fbdc0 (patch) | |
| tree | 9c952446407487e2e48008fd988dc632c2e0d823 | |
| parent | 91a212abeb9d6dff75d075593c6835336bd9fc5e (diff) | |
| download | rabbitmq-server-git-ec58eb9caf0b399afbd2c7e37c3f79d47d1fbdc0.tar.gz | |
code gen property encoder
pretty much symmetric to decoder
Involves renaming of the decoder helper funs, since those names are
more meaningful for the encoder
| -rw-r--r-- | codegen.py | 70 | ||||
| -rw-r--r-- | src/rabbit_binary_generator.erl | 57 |
2 files changed, 57 insertions, 70 deletions
diff --git a/codegen.py b/codegen.py index 2ff7842031..6c36753c9c 100644 --- a/codegen.py +++ b/codegen.py @@ -227,7 +227,7 @@ def genErl(spec): print " {F%s, R%s} = {P%s =/= 0, R%s}," % \ (i, str(field.index + 1), i, i) else: - print " {F%s, R%s} = if P%s =:= 0 -> {undefined, R%s}; true -> %s_prop(R%s) end," % \ + print " {F%s, R%s} = if P%s =:= 0 -> {undefined, R%s}; true -> %s_val(R%s) end," % \ (i, str(field.index + 1), i, i, erlType(field.domain), i) if len(c.fields) == 0: @@ -265,9 +265,27 @@ def genErl(spec): print " <<%s>>;" % (', '.join([methodFieldFragment(f) for f in packedFields])) def genEncodeProperties(c): + def presentBin(fields): + ps = ', '.join(['P' + str(f.index) + ':1' for f in fields]) + return '<<' + ps + ', 0:%d>>' % (16 - len(fields),) + def writePropFieldLine(field): + i = str(field.index) + if field.domain == 'bit': + print " {P%s, R%s} = {F%s =:= 1, R%s}," % \ + (i, str(field.index + 1), i, i) + else: + print " {P%s, R%s} = if F%s =:= undefined -> {0, R%s}; true -> {1, [?%s_PROP(F%s) | R%s]} end," % \ + (i, str(field.index + 1), i, i, erlType(field.domain).upper(), i, i) + print "encode_properties(#'P_%s'{%s}) ->" % (erlangize(c.name), fieldMapList(c.fields)) - print " rabbit_binary_generator:encode_properties(%s, %s);" % \ - (fieldTypeList(c.fields), fieldTempList(c.fields)) + if len(c.fields) == 0: + print " <<>>;" + else: + print " R0 = <<>>," + for field in c.fields: + writePropFieldLine(field) + print " list_to_binary([%s | lists:reverse(R%s)]);" % \ + (presentBin(c.fields), str(len(c.fields))) def messageConstantClass(cls): # We do this because 0.8 uses "soft error" and 8.1 uses "soft-error". @@ -413,26 +431,50 @@ shortstr_size(S) -> %% use of these functions by the codec depends on the protocol spec -compile({nowarn_unused_function, - [{shortstr_prop, 1}, {longstr_prop, 1}, - {short_prop, 1}, {long_prop, 1}, {longlong_prop, 1}, - {octet_prop, 1}, {table_prop, 1}, {timestamp_prop, 1}]}). + [{shortstr_val, 1}, {longstr_val, 1}, + {short_val, 1}, {long_val, 1}, {longlong_val, 1}, + {octet_val, 1}, {table_val, 1}, {timestamp_val, 1}, + {shortstr_prop, 1}, {longstr_prop, 1}, {table_prop, 1}]}). -shortstr_prop(<<L:8/unsigned, S:L/binary, X/binary>>) -> {S, X}. +shortstr_val(<<L:8/unsigned, S:L/binary, X/binary>>) -> {S, X}. -longstr_prop(<<L:32/unsigned, S:L/binary, X/binary>>) -> {S, X}. +longstr_val(<<L:32/unsigned, S:L/binary, X/binary>>) -> {S, X}. -short_prop(<<I:8/unsigned, X/binary>>) -> {I, X}. +short_val(<<I:8/unsigned, X/binary>>) -> {I, X}. -long_prop(<<I:32/unsigned, X/binary>>) -> {I, X}. +long_val(<<I:32/unsigned, X/binary>>) -> {I, X}. -longlong_prop(<<I:64/unsigned, X/binary>>) -> {I, X}. +longlong_val(<<I:64/unsigned, X/binary>>) -> {I, X}. -octet_prop(<<I:8/unsigned, X/binary>>) -> {I, X}. +octet_val(<<I:8/unsigned, X/binary>>) -> {I, X}. -table_prop(<<L:32/unsigned, T:L/binary, X/binary>>) -> +table_val(<<L:32/unsigned, T:L/binary, X/binary>>) -> {rabbit_binary_parser:parse_table(T), X}. -timestamp_prop(<<I:64/unsigned, X/binary>>) -> {I, X}. +timestamp_val(<<I:64/unsigned, X/binary>>) -> {I, X}. + +shortstr_prop(S) -> + L = size(S), + if L < 256 -> <<L:8, S:L/binary>>; + true -> exit(content_properties_shortstr_overflow) + end. + +longstr_prop(S) -> + L = size(S), + <<L:32, S:L/binary>>. + +table_prop(T) -> + BinT = rabbit_binary_generator:generate_table(T), + <<(size(BinT)):32, BinT/binary>>. + +-define(SHORTSTR_PROP(X), shortstr_prop(X)). +-define(LONGSTR_PROP(X), longstr_prop(X)). +-define(OCTET_PROP(X), <<X:8/unsigned>>). +-define(SHORT_PROP(X), <<X:16/unsigned>>). +-define(LONG_PROP(X), <<X:32/unsigned>>). +-define(LONGLONG_PROP(X), <<X:64/unsigned>>). +-define(TIMESTAMP_PROP(X), <<X:64/unsigned>>). +-define(TABLE_PROP(X), table_prop(X)). """ 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_generator.erl b/src/rabbit_binary_generator.erl index 2ece86963f..a333c1ce05 100644 --- a/src/rabbit_binary_generator.erl +++ b/src/rabbit_binary_generator.erl @@ -21,7 +21,7 @@ -export([build_simple_method_frame/3, build_simple_content_frames/4, build_heartbeat_frame/0]). --export([generate_table/1, encode_properties/2]). +-export([generate_table/1]). -export([check_empty_frame_size/0]). -export([ensure_content_encoded/2, clear_encoded_content/1]). -export([map_exception/3]). @@ -42,8 +42,6 @@ -> [frame()]). -spec(build_heartbeat_frame/0 :: () -> frame()). -spec(generate_table/1 :: (rabbit_framing:amqp_table()) -> binary()). --spec(encode_properties/2 :: - ([rabbit_framing:amqp_property_type()], [any()]) -> binary()). -spec(check_empty_frame_size/0 :: () -> 'ok'). -spec(ensure_content_encoded/2 :: (rabbit_types:content(), rabbit_types:protocol()) -> @@ -168,59 +166,6 @@ long_string_to_binary(String) when is_binary(String) -> long_string_to_binary(String) -> [<<(length(String)):32>>, String]. -encode_properties([], []) -> - <<0, 0>>; -encode_properties(TypeList, ValueList) -> - encode_properties(0, TypeList, ValueList, 0, [], []). - -encode_properties(_Bit, [], [], - FirstShortAcc, FlagsAcc, PropsAcc) -> - list_to_binary([lists:reverse(FlagsAcc), - <<FirstShortAcc:16>>, - lists:reverse(PropsAcc)]); -encode_properties(_Bit, [], _ValueList, - _FirstShortAcc, _FlagsAcc, _PropsAcc) -> - exit(content_properties_values_overflow); -encode_properties(15, TypeList, ValueList, - FirstShortAcc, FlagsAcc, PropsAcc) -> - NewFlagsShort = FirstShortAcc bor 1, % set the continuation low bit - encode_properties(0, TypeList, ValueList, - 0, [<<NewFlagsShort:16>> | FlagsAcc], PropsAcc); -encode_properties(Bit, [bit | TypeList], [true | ValueList], - FirstShortAcc, FlagsAcc, PropsAcc) -> - encode_properties(Bit + 1, TypeList, ValueList, - FirstShortAcc bor (1 bsl (15 - Bit)), FlagsAcc, PropsAcc); -encode_properties(Bit, [bit | TypeList], [false | ValueList], - FirstShortAcc, FlagsAcc, PropsAcc) -> - encode_properties(Bit + 1, TypeList, ValueList, - FirstShortAcc, FlagsAcc, PropsAcc); -encode_properties(_Bit, [bit | _TypeList], [Other | _ValueList], - _FirstShortAcc, _FlagsAcc, _PropsAcc) -> - exit({content_properties_illegal_bit_value, Other}); -encode_properties(Bit, [_Type | TypeList], [undefined | ValueList], - FirstShortAcc, FlagsAcc, PropsAcc) -> - encode_properties(Bit + 1, TypeList, ValueList, - FirstShortAcc, FlagsAcc, PropsAcc); -encode_properties(Bit, [Type | TypeList], [Value | ValueList], - FirstShortAcc, FlagsAcc, PropsAcc) -> - encode_properties(Bit + 1, TypeList, ValueList, - FirstShortAcc bor (1 bsl (15 - Bit)), FlagsAcc, - [encode_property(Type, Value) | PropsAcc]). - -encode_property(shortstr, String) -> - Len = size(String), - if Len < 256 -> <<Len:8, String:Len/binary>>; - true -> exit(content_properties_shortstr_overflow) - end; -encode_property(longstr, String) -> Len = size(String), - <<Len:32, String:Len/binary>>; -encode_property(octet, Int) -> <<Int:8/unsigned>>; -encode_property(short, Int) -> <<Int:16/unsigned>>; -encode_property(long, Int) -> <<Int:32/unsigned>>; -encode_property(longlong, Int) -> <<Int:64/unsigned>>; -encode_property(timestamp, Int) -> <<Int:64/unsigned>>; -encode_property(table, Table) -> table_to_binary(Table). - check_empty_frame_size() -> %% Intended to ensure that EMPTY_FRAME_SIZE is defined correctly. case iolist_size(create_frame(?FRAME_BODY, 0, <<>>)) of |
