[protocol] Implement object arrays
This commit is contained in:
parent
8a6fdb67ef
commit
1e2e6da787
|
@ -33,9 +33,32 @@ def extract_array_type(type):
|
||||||
return type[:type.rfind('[')]
|
return type[:type.rfind('[')]
|
||||||
return type
|
return type
|
||||||
|
|
||||||
def extract_array_count(type):
|
def extract_array_count(value, name=''):
|
||||||
if '[' in type and ']' in type:
|
if isinstance(value, dict):
|
||||||
count = type[type.find('[')+1:type.rfind(']')]
|
if name == '' or name == None:
|
||||||
|
raise Exception('extract_array_count called with dict value but name not provided')
|
||||||
|
|
||||||
|
idx = name.find('(')
|
||||||
|
if idx > 0:
|
||||||
|
idxend = name.find(')')
|
||||||
|
if idxend > idx:
|
||||||
|
attribute = name[idx+1:idxend]
|
||||||
|
name = name[:idx]
|
||||||
|
# array of objects key(#count): {...}
|
||||||
|
if attribute.startswith('#'):
|
||||||
|
count = attribute[1:]
|
||||||
|
if count.isdigit():
|
||||||
|
return int(count)
|
||||||
|
else:
|
||||||
|
return count
|
||||||
|
else:
|
||||||
|
warn('WARNING: Var name "{}" has unterminated () brackets', name)
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if '[' in value and ']' in value:
|
||||||
|
count = value[value.find('[')+1:value.rfind(']')]
|
||||||
if count.isdigit():
|
if count.isdigit():
|
||||||
return int(count)
|
return int(count)
|
||||||
else:
|
else:
|
||||||
|
@ -69,13 +92,8 @@ def get_type_info(types, typename):
|
||||||
return tp
|
return tp
|
||||||
|
|
||||||
def resolve_name(types, name, value, decl=False):
|
def resolve_name(types, name, value, decl=False):
|
||||||
|
|
||||||
if isinstance(value, dict):
|
|
||||||
return name
|
|
||||||
|
|
||||||
typename = value
|
fullname = name
|
||||||
|
|
||||||
tp = get_type_info(types, typename)
|
|
||||||
|
|
||||||
idx = name.find('(')
|
idx = name.find('(')
|
||||||
if idx > 0:
|
if idx > 0:
|
||||||
|
@ -84,9 +102,10 @@ def resolve_name(types, name, value, decl=False):
|
||||||
warn('ERROR: Invalid variable name "{}"'.format(name))
|
warn('ERROR: Invalid variable name "{}"'.format(name))
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
||||||
|
# standard array syntax key: type[count]
|
||||||
if decl:
|
if decl:
|
||||||
if is_type_array(types, typename):
|
if is_type_array(types, fullname, value):
|
||||||
count = extract_array_count(typename)
|
count = extract_array_count(value, fullname)
|
||||||
if type(count) is int:
|
if type(count) is int:
|
||||||
# array of fixed size
|
# array of fixed size
|
||||||
name += '[' + str(count) + ']'
|
name += '[' + str(count) + ']'
|
||||||
|
@ -109,20 +128,33 @@ def resolve_type(types, value):
|
||||||
else:
|
else:
|
||||||
return typename
|
return typename
|
||||||
|
|
||||||
def is_type_array(types, typename):
|
def is_type_array(types, name, value):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
return extract_array_count(value, name) != None
|
||||||
|
typename = value
|
||||||
tp = get_type_info(types, typename)
|
tp = get_type_info(types, typename)
|
||||||
if 'size' in tp and tp['size'] == 'count':
|
if 'size' in tp and tp['size'] == 'count':
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return extract_array_count(typename) != None
|
return extract_array_count(typename) != None
|
||||||
|
|
||||||
def get_type_size(types, value):
|
def get_type_size(types, value, name=''):
|
||||||
global varint_max_size
|
global varint_max_size
|
||||||
|
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
|
if name == '' or name == None:
|
||||||
|
raise Exception('get_type_size called on dict value with no name')
|
||||||
|
|
||||||
size = 0
|
size = 0
|
||||||
for k, v in value.items():
|
for k, v in value.items():
|
||||||
size += get_type_size(types, v)
|
size += get_type_size(types, v)
|
||||||
|
if is_type_array(types, name, value):
|
||||||
|
count = extract_array_count(value, name)
|
||||||
|
if type(count) is int:
|
||||||
|
return size * count
|
||||||
|
else:
|
||||||
|
# TODO: handling size for variable arrays...
|
||||||
|
return size
|
||||||
return size
|
return size
|
||||||
|
|
||||||
typename = value
|
typename = value
|
||||||
|
@ -178,10 +210,17 @@ def print_rw_logic(types, value, name, read):
|
||||||
resolved_name = resolve_name(types, name, value)
|
resolved_name = resolve_name(types, name, value)
|
||||||
|
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
|
is_array = is_type_array(types, name, value)
|
||||||
|
if is_array:
|
||||||
|
count = extract_array_count(value, name)
|
||||||
|
add_text(f'for (int i = 0; i < {count}; i++)')
|
||||||
add_text('{{')
|
add_text('{{')
|
||||||
indent()
|
indent()
|
||||||
for k, v in value.items():
|
for k, v in value.items():
|
||||||
scoped_name = f'{resolved_name}.{resolve_name(types, k, v)}'
|
scoped_name = resolved_name
|
||||||
|
if is_array:
|
||||||
|
scoped_name += '[i]'
|
||||||
|
scoped_name += f'.{resolve_name(types, k, v)}'
|
||||||
print_rw_logic(types, v, scoped_name, read)
|
print_rw_logic(types, v, scoped_name, read)
|
||||||
unindent()
|
unindent()
|
||||||
add_text('}}')
|
add_text('}}')
|
||||||
|
@ -204,7 +243,7 @@ def print_rw_logic(types, value, name, read):
|
||||||
|
|
||||||
rw_func = get_rw_func(types, typename, read)
|
rw_func = get_rw_func(types, typename, read)
|
||||||
|
|
||||||
if is_type_array(types, typename):
|
if is_type_array(types, name, typename):
|
||||||
# arrays
|
# arrays
|
||||||
count = extract_array_count(typename)
|
count = extract_array_count(typename)
|
||||||
arrtype = extract_array_type(typename)
|
arrtype = extract_array_type(typename)
|
||||||
|
@ -310,7 +349,7 @@ def print_messages(list, globalTypes):
|
||||||
size = varint_max_size # Packet Length
|
size = varint_max_size # Packet Length
|
||||||
size += varint_max_size # Packet Id
|
size += varint_max_size # Packet Id
|
||||||
for name, typename in message['vars'].items():
|
for name, typename in message['vars'].items():
|
||||||
size += get_type_size(types, typename)
|
size += get_type_size(types, typename, name)
|
||||||
|
|
||||||
struct_name = '{}{}'.format(direction.capitalize(), message_name)
|
struct_name = '{}{}'.format(direction.capitalize(), message_name)
|
||||||
add_text('struct {}', struct_name)
|
add_text('struct {}', struct_name)
|
||||||
|
|
Loading…
Reference in New Issue