# TODO(VPP-1187): do not inline JNI object creation inside message handlers to reduce number of special cases
-def generate_j2c_swap(element, struct_ref_name):
+def generate_j2c_swap(element, struct_ref_name, is_alias):
initialization = []
for field in element.fields:
- initialization.append(generate_j2c_field_swap(field, struct_ref_name))
+ initialization.append(generate_j2c_field_swap(field, struct_ref_name, is_alias))
return "\n".join(initialization)
-def generate_j2c_field_swap(field, struct_ref_name):
+def generate_j2c_field_swap(field, struct_ref_name, is_alias):
if is_array(field):
- return _generate_j2c_array_swap(field, struct_ref_name)
+ return _generate_j2c_array_swap(field, struct_ref_name, is_alias)
else:
- return _generate_j2c_scalar_swap(field, struct_ref_name)
+ return _generate_j2c_scalar_swap(field, struct_ref_name, is_alias)
-def _generate_j2c_array_swap(field, struct_ref_name):
+def _generate_j2c_array_swap(field, struct_ref_name, is_alias):
# TODO(VPP-1186): move the logic to JNI generators
base_type = field.type.base_type
if isinstance(base_type, (Class, Enum, Union)):
elif base_type.is_swap_needed:
return _generate_j2c_primitive_type_array_swap(field, struct_ref_name)
else:
- return _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name)
+ return _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias)
def _generate_j2c_object_array_swap(field, struct_ref_name):
""")
-def _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name):
+def _generate_j2c_primitive_type_array_no_swap(field, struct_ref_name, is_alias):
field_type = field.type
- return _J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE.substitute(
+ if not is_alias:
+ template = _J2C_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
+ else:
+ template = _J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
+
+ return template.substitute(
field_reference_name=field.java_name,
field_length_check=_generate_field_length_check(field),
base_type=field_type.base_type.jni_accessor,
""")
+_J2C_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
+ if (${field_reference_name}) {
+ jsize cnt = (*env)->GetArrayLength (env, ${field_reference_name});
+ ${field_length_check}
+ (*env)->Get${base_type}ArrayRegion(env, ${field_reference_name}, 0, cnt, (${jni_base_type} *)${struct_reference_name});
+ }
+""")
+
+
def _generate_field_length_check(field):
# Enforce max length if array has fixed length or uses variable length syntax
field_length = str(field.array_len)
if (cnt > max_size) cnt = max_size;""")
-def _generate_j2c_scalar_swap(field, struct_ref_name):
+def _generate_j2c_scalar_swap(field, struct_ref_name, is_alias):
field_type = field.type
if field_type.is_swap_needed:
host = field.java_name
- net = "%s->%s" % (struct_ref_name, field.name)
- return " %s;" % field_type.get_host_to_net_function(host, net)
+ if not is_alias:
+ net = "%s->%s" % (struct_ref_name, field.name)
+ return " %s;" % field_type.get_host_to_net_function(host, net)
+ else:
+ net = "%s" % (struct_ref_name)
+ return " *%s;" % field_type.get_host_to_net_function(host, net)
else:
return " %s->%s = %s;" % (struct_ref_name, field.name, field.java_name)
-def generate_c2j_swap(element, object_ref_name, struct_ref_name):
+def generate_c2j_swap(element, object_ref_name, struct_ref_name, is_alias):
msg_java_name = element.java_name_lower
initialization = []
for field in element.fields:
# For retval don't generate setters and generate retval check
continue
elif is_array(field):
- initialization.append(_generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name))
+ initialization.append(_generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias))
else:
- initialization.append(_generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name))
+ initialization.append(_generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias))
return "".join(initialization)
-def _generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+def _generate_c2j_array_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
# TODO(VPP-1186): move the logic to JNI generators
base_type = field.type.base_type
if isinstance(base_type, (Class, Union)):
elif base_type.is_swap_needed:
return _generate_c2j_primitive_type_array_swap(msg_java_name, field, object_ref_name, struct_ref_name)
else:
- return _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name)
+ return _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)
def _generate_c2j_object_array_swap(msg_java_name, field, object_ref_name, struct_ref_name):
""")
-def _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+def _generate_c2j_primitive_type_array_no_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
field_type = field.type
- return _C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE.substitute(
+ if not is_alias:
+ template = _C2J_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
+ else:
+ template = _C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE
+ return template.substitute(
field_reference_name=field.java_name,
class_ref_name=msg_java_name,
jni_signature=field_type.jni_signature,
""")
+_C2J_ALIAS_PRIMITIVE_TYPE_ARRAY_NO_SWAP_TEMPLATE = Template("""
+ jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${field_reference_name}", "${jni_signature}");
+ ${jni_type} ${field_reference_name} = (*env)->New${base_type}Array(env, ${field_length});
+ (*env)->Set${base_type}ArrayRegion(env, ${field_reference_name}, 0, ${field_length}, (const ${jni_base_type}*)${struct_ref_name});
+ (*env)->SetObjectField(env, ${object_ref_name}, ${field_reference_name}FieldId, ${field_reference_name});
+ (*env)->DeleteLocalRef(env, ${field_reference_name});
+""")
+
+
def _generate_array_length(field, struct_ref_name):
if field.array_len_field:
len_field = field.array_len_field
return field.array_len
-def _generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+def _generate_c2j_scalar_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
field_type = field.type
if field_type.is_swap_needed:
# TODO(VPP-1186): move the logic to JNI generators
elif isinstance(field_type, Enum):
return _generate_c2j_enum_swap(msg_java_name, field, object_ref_name, struct_ref_name)
else:
- return _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name)
+ return _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias)
else:
return _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name)
""")
-def _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name):
+def _generate_c2j_primitive_type_swap(msg_java_name, field, object_ref_name, struct_ref_name, is_alias):
field_type = field.type
- return _C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE.substitute(
+ if not is_alias:
+ template = _C2J_PRIMITIVE_TYPE_SWAP_TEMPLATE
+ else:
+ template = _C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE
+ return template.substitute(
java_name=field.java_name,
class_ref_name=msg_java_name,
jni_signature=field_type.jni_signature,
""")
+_C2J_ALIAS_PRIMITIVE_TYPE_SWAP_TEMPLATE = Template("""
+ jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");
+ (*env)->Set${jni_accessor}Field(env, ${object_ref_name}, ${java_name}FieldId, ${net_to_host_function}(*${struct_ref_name}));
+""")
+
+
def _generate_c2j_primitive_type_no_swap(msg_java_name, field, object_ref_name, struct_ref_name):
field_type = field.type
return _C2J_PRIMITIVE_TYPE_NO_SWAP_TEMPLATE.substitute(
def _generate_class(model, t, type_handlers):
ref_name = t.java_name_lower
+ if t.name in model._aliases:
+ is_alias = True
+ else:
+ is_alias = False
+
type_handlers.append(_TYPE_HOST_TO_NET_TEMPLATE.substitute(
c_name=t.name,
json_filename=model.json_api_files,
type_reference_name=ref_name,
class_FQN=t.jni_name,
jni_identifiers=generate_j2c_identifiers(t, class_ref_name="%sClass" % ref_name, object_ref_name="_host"),
- type_swap=generate_j2c_swap(t, struct_ref_name="_net")
+ type_swap=generate_j2c_swap(t, struct_ref_name="_net", is_alias=is_alias)
))
type_handlers.append(_TYPE_NET_TO_HOST_TEMPLATE.substitute(
c_name=t.name,
json_definition=t.doc,
type_reference_name=ref_name,
class_FQN=t.jni_name,
- type_swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net")
+ type_swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net", is_alias=is_alias)
))
_TYPE_HOST_TO_NET_TEMPLATE = Template("""
swap = []
for i, field in enumerate(t.fields):
field_type = field.type
+ if t.name in model._aliases:
+ is_alias = True
+ else:
+ is_alias = False
swap.append(_UNION_FIELD_HOST_TO_NET_TEMPLATE.substitute(
field_index=i,
java_name=field.java_name,
jni_signature=field_type.jni_signature,
jni_type=field_type.jni_type,
jni_accessor=field_type.jni_accessor,
- swap=generate_j2c_field_swap(field, struct_ref_name="_net")
+ swap=generate_j2c_field_swap(field, struct_ref_name="_net", is_alias=is_alias)
))
return _UNION_HOST_TO_NET_TEMPLATE.substitute(
def _generate_union_net_to_host(model, t):
+ if t.name in model._aliases:
+ is_alias = True
+ else:
+ is_alias = False
return _UNION_NET_TO_HOST_TEMPLATE.substitute(
c_name=t.name,
json_filename=model.json_api_files,
json_definition=t.doc,
type_reference_name=t.java_name_lower,
class_FQN=t.jni_name,
- swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net")
+ swap=generate_c2j_swap(t, object_ref_name="_host", struct_ref_name="_net", is_alias=is_alias)
)
_UNION_NET_TO_HOST_TEMPLATE = Template("""