summaryrefslogtreecommitdiff
path: root/codegen.py
diff options
context:
space:
mode:
Diffstat (limited to 'codegen.py')
-rw-r--r--codegen.py158
1 files changed, 104 insertions, 54 deletions
diff --git a/codegen.py b/codegen.py
index 9483e854..5624658b 100644
--- a/codegen.py
+++ b/codegen.py
@@ -24,18 +24,6 @@ from amqp_codegen import *
import string
import re
-erlangTypeMap = {
- 'octet': 'octet',
- 'shortstr': 'shortstr',
- 'longstr': 'longstr',
- 'short': 'shortint',
- 'long': 'longint',
- 'longlong': 'longlongint',
- 'bit': 'bit',
- 'table': 'table',
- 'timestamp': 'timestamp',
-}
-
# Coming up with a proper encoding of AMQP tables in JSON is too much
# hassle at this stage. Given that the only default value we are
# interested in is for the empty table, we only support that.
@@ -123,7 +111,7 @@ def printFileHeader():
def genErl(spec):
def erlType(domain):
- return erlangTypeMap[spec.resolveDomain(domain)]
+ return erlangize(spec.resolveDomain(domain))
def fieldTypeList(fields):
return '[' + ', '.join([erlType(f.domain) for f in fields]) + ']'
@@ -186,11 +174,11 @@ def genErl(spec):
return p+'Len:32/unsigned, '+p+':'+p+'Len/binary'
elif type == 'octet':
return p+':8/unsigned'
- elif type == 'shortint':
+ elif type == 'short':
return p+':16/unsigned'
- elif type == 'longint':
+ elif type == 'long':
return p+':32/unsigned'
- elif type == 'longlongint':
+ elif type == 'longlong':
return p+':64/unsigned'
elif type == 'timestamp':
return p+':64/unsigned'
@@ -233,29 +221,23 @@ def genErl(spec):
def presentBin(fields):
ps = ', '.join(['P' + str(f.index) + ':1' for f in fields])
return '<<' + ps + ', _:%d, R0/binary>>' % (16 - len(fields),)
- def mkMacroName(field):
- return '?' + field.domain.upper() + '_PROP'
- def writePropFieldLine(field, bin_next = None):
+ def writePropFieldLine(field):
i = str(field.index)
- if not bin_next:
- bin_next = 'R' + str(field.index + 1)
- 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))
+ if field.domain == 'bit':
+ print " {F%s, R%s} = {P%s =/= 0, R%s}," % \
+ (i, str(field.index + 1), i, 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))
+ print " {F%s, R%s} = if P%s =:= 0 -> {undefined, R%s}; true -> ?%s_VAL(R%s, L%s, V%s, X%s) end," % \
+ (i, str(field.index + 1), i, i, erlType(field.domain).upper(), i, i, i, i)
if len(c.fields) == 0:
- print "decode_properties(%d, _) ->" % (c.index,)
+ print "decode_properties(%d, <<>>) ->" % (c.index,)
else:
print ("decode_properties(%d, %s) ->" %
(c.index, presentBin(c.fields)))
- for field in c.fields[:-1]:
+ for field in c.fields:
writePropFieldLine(field)
- writePropFieldLine(c.fields[-1], "<<>>")
+ print " <<>> = %s," % ('R' + str(len(c.fields)))
print " #'P_%s'{%s};" % (erlangize(c.name), fieldMapList(c.fields))
def genFieldPreprocessing(packed):
@@ -283,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, L%s) | R%s]} end," % \
+ (i, str(field.index + 1), i, i, erlType(field.domain).upper(), i, 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".
@@ -350,8 +350,8 @@ def genErl(spec):
'table' | 'byte' | 'double' | 'float' | 'long' |
'short' | 'bool' | 'binary' | 'void' | 'array').
-type(amqp_property_type() ::
- 'shortstr' | 'longstr' | 'octet' | 'shortint' | 'longint' |
- 'longlongint' | 'timestamp' | 'bit' | 'table').
+ 'shortstr' | 'longstr' | 'octet' | 'short' | 'long' |
+ 'longlong' | 'timestamp' | 'bit' | 'table').
-type(amqp_table() :: [{binary(), amqp_field_type(), amqp_value()}]).
-type(amqp_array() :: [{amqp_field_type(), amqp_value()}]).
@@ -429,25 +429,78 @@ shortstr_size(S) ->
_ -> 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}
+-define(SHORTSTR_VAL(R, L, V, X),
+ begin
+ <<L:8/unsigned, V:L/binary, X/binary>> = R,
+ {V, X}
+ end).
+
+-define(LONGSTR_VAL(R, L, V, X),
+ begin
+ <<L:32/unsigned, V:L/binary, X/binary>> = R,
+ {V, X}
+ end).
+
+-define(SHORT_VAL(R, L, V, X),
+ begin
+ <<V:8/unsigned, X/binary>> = R,
+ {V, X}
+ end).
+
+-define(LONG_VAL(R, L, V, X),
+ begin
+ <<V:32/unsigned, X/binary>> = R,
+ {V, X}
+ end).
+
+-define(LONGLONG_VAL(R, L, V, X),
+ begin
+ <<V:64/unsigned, X/binary>> = R,
+ {V, X}
+ end).
+
+-define(OCTET_VAL(R, L, V, X),
+ begin
+ <<V:8/unsigned, X/binary>> = R,
+ {V, 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}
+
+-define(TABLE_VAL(R, L, V, X),
+ begin
+ <<L:32/unsigned, V:L/binary, X/binary>> = R,
+ {rabbit_binary_parser:parse_table(V), X}
end).
--define(OCTET_PROP(P, R, I, X),
- if P =:= 0 -> {undefined, R};
- true -> <<I:8/unsigned, X/binary>> = R,
- {I, X}
+
+-define(TIMESTAMP_VAL(R, L, V, X),
+ begin
+ <<V:64/unsigned, X/binary>> = R,
+ {V, X}
end).
--define(TIMESTAMP_PROP(P, R, I, X),
- if P =:= 0 -> {undefined, R};
- true -> <<I:64/unsigned, X/binary>> = R,
- {I, X}
+
+-define(SHORTSTR_PROP(X, L),
+ begin
+ L = size(X),
+ if L < 256 -> <<L:8, X:L/binary>>;
+ true -> exit(content_properties_shortstr_overflow)
+ end
+ end).
+
+-define(LONGSTR_PROP(X, L),
+ begin
+ L = size(X),
+ <<L:32, X:L/binary>>
+ end).
+
+-define(OCTET_PROP(X, L), <<X:8/unsigned>>).
+-define(SHORT_PROP(X, L), <<X:16/unsigned>>).
+-define(LONG_PROP(X, L), <<X:32/unsigned>>).
+-define(LONGLONG_PROP(X, L), <<X:64/unsigned>>).
+-define(TIMESTAMP_PROP(X, L), <<X:64/unsigned>>).
+
+-define(TABLE_PROP(X, T),
+ begin
+ T = rabbit_binary_generator:generate_table(X),
+ <<(size(T)):32, T/binary>>
end).
"""
version = "{%d, %d, %d}" % (spec.major, spec.minor, spec.revision)
@@ -497,9 +550,6 @@ shortstr_size(S) ->
print "amqp_exception(_Code) -> undefined."
def genHrl(spec):
- def erlType(domain):
- return erlangTypeMap[spec.resolveDomain(domain)]
-
def fieldNameList(fields):
return ', '.join([erlangize(f.name) for f in fields])