diff options
author | Marek Gradzki <mgradzki@cisco.com> | 2016-09-29 13:22:35 +0200 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2016-10-31 21:42:40 +0000 |
commit | 81c7dfc1bb48f1121fca4bf6f1e6e24efb0024de (patch) | |
tree | b0f831227ab2a7fd412d733c09f83649d8472692 /vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py | |
parent | c967a8239d98830e0b889bf9a621581a38a71dd8 (diff) |
VPP-120: add custom types support to jvpp
Generates java classes based on typeonly definitions
(hashcode, equals and toString methods are also included).
Adds JNI handling for request and reply messages
(also arrays of custom types).
Change-Id: I16f1cea17899704426aa083fad1cb800a8d115df
Signed-off-by: Marek Gradzki <mgradzki@cisco.com>
Diffstat (limited to 'vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py')
-rw-r--r-- | vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py | 286 |
1 files changed, 35 insertions, 251 deletions
diff --git a/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py b/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py index d63acd6965f..1a35a6c09c0 100644 --- a/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py +++ b/vpp-api/java/jvpp/gen/jvppgen/jvpp_c_gen.py @@ -17,6 +17,9 @@ import os, util from string import Template +import jni_gen + + def is_manually_generated(f_name, plugin_name): return f_name in {'control_ping_reply'} @@ -54,6 +57,7 @@ static void delete_class_references(JNIEnv* env) { $delete_class_invocations }""") + def generate_class_cache(func_list, plugin_name): class_references = [] find_class_invocations = [] @@ -105,94 +109,10 @@ request_class_template = Template(""" jclass requestClass = (*env)->FindClass(env, "io/fd/vpp/jvpp/${plugin_name}/dto/${java_name_upper}");""") request_field_identifier_template = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, requestClass, "${java_name}", "${jni_signature}"); - ${jni_type} ${java_name} = (*env)->Get${jni_getter}(env, request, ${java_name}FieldId); + jfieldID ${field_reference_name}FieldId = (*env)->GetFieldID(env, ${object_name}Class, "${field_name}", "${jni_signature}"); + ${jni_type} ${field_reference_name} = (*env)->Get${jni_getter}(env, ${object_name}, ${field_reference_name}FieldId); """) -u8_struct_setter_template = Template(""" - mp->${c_name} = ${java_name};""") - -u16_struct_setter_template = Template(""" - mp->${c_name} = clib_host_to_net_u16(${java_name});""") - -u32_struct_setter_template = Template(""" - mp->${c_name} = clib_host_to_net_u32(${java_name});""") - -i32_struct_setter_template = Template(""" - mp->${c_name} = clib_host_to_net_i32(${java_name});!""") - -u64_struct_setter_template = Template(""" - mp->${c_name} = clib_host_to_net_u64(${java_name});""") - -fixed_array_length_enforcement_template = Template(""" - size_t max_size = ${field_length}; - if (cnt > max_size) cnt = max_size;""") - -u8_array_struct_setter_template = Template(""" - if (${java_name}) { - jsize cnt = (*env)->GetArrayLength (env, ${java_name}); - ${field_length_check} - (*env)->GetByteArrayRegion(env, ${java_name}, 0, cnt, (jbyte *)mp->${c_name}); - } -""") - -u16_array_struct_setter_template = Template(""" - jshort * ${java_name}ArrayElements = (*env)->GetShortArrayElements(env, ${java_name}, NULL); - if (${java_name}) { - size_t _i; - jsize cnt = (*env)->GetArrayLength (env, ${java_name}); - ${field_length_check} - for (_i = 0; _i < cnt; _i++) { - mp->${c_name}[_i] = clib_host_to_net_u16(${java_name}ArrayElements[_i]); - } - } - (*env)->ReleaseShortArrayElements (env, ${java_name}, ${java_name}ArrayElements, 0); - """) - -u32_array_struct_setter_template = Template(""" - jint * ${java_name}ArrayElements = (*env)->GetIntArrayElements(env, ${java_name}, NULL); - if (${java_name}) { - size_t _i; - jsize cnt = (*env)->GetArrayLength (env, ${java_name}); - ${field_length_check} - for (_i = 0; _i < cnt; _i++) { - mp->${c_name}[_i] = clib_host_to_net_u32(${java_name}ArrayElements[_i]); - } - } - (*env)->ReleaseIntArrayElements (env, ${java_name}, ${java_name}ArrayElements, 0); - """) - -u64_array_struct_setter_template = Template(""" - jlong * ${java_name}ArrayElements = (*env)->GetLongArrayElements(env, ${java_name}, NULL); - if (${java_name}) { - size_t _i; - jsize cnt = (*env)->GetArrayLength (env, ${java_name}); - ${field_length_check} - for (_i = 0; _i < cnt; _i++) { - mp->${c_name}[_i] = clib_host_to_net_u64(${java_name}ArrayElements[_i]); - } - } - (*env)->ReleaseLongArrayElements (env, ${java_name}, ${java_name}ArrayElements, 0); - """) - -vl_api_ip4_fib_counter_t_array_struct_setter_template = Template(""" - // vl_api_ip4_fib_counter_t_array_field_setter_template FIXME""") - -vl_api_ip6_fib_counter_t_array_struct_setter_template = Template(""" - // vl_api_ip6_fib_counter_t_array_field_setter_template FIXME""") - -struct_setter_templates = {'u8': u8_struct_setter_template, - 'u16': u16_struct_setter_template, - 'u32': u32_struct_setter_template, - 'i32': u32_struct_setter_template, - 'u64': u64_struct_setter_template, - 'u8[]': u8_array_struct_setter_template, - 'u16[]': u16_array_struct_setter_template, - 'u32[]': u32_array_struct_setter_template, - 'u64[]': u64_array_struct_setter_template, - 'vl_api_ip4_fib_counter_t[]': vl_api_ip4_fib_counter_t_array_struct_setter_template, - 'vl_api_ip6_fib_counter_t[]': vl_api_ip6_fib_counter_t_array_struct_setter_template - } jni_impl_template = Template(""" /** @@ -200,13 +120,12 @@ jni_impl_template = Template(""" * Generated based on $inputfile preparsed data: $api_data */ -JNIEXPORT jint JNICALL Java_io_fd_vpp_jvpp_${plugin_name}_JVpp${java_plugin_name}Impl_${java_name}0 +JNIEXPORT jint JNICALL Java_io_fd_vpp_jvpp_${plugin_name}_JVpp${java_plugin_name}Impl_${field_name}0 (JNIEnv * env, jclass clazz$args) { ${plugin_name}_main_t *plugin_main = &${plugin_name}_main; vl_api_${c_name}_t * mp; u32 my_context_id = vppjni_get_context_id (&jvpp_main); $request_class - $field_identifiers // create message: mp = vl_msg_api_alloc(sizeof(*mp)); @@ -215,7 +134,8 @@ JNIEXPORT jint JNICALL Java_io_fd_vpp_jvpp_${plugin_name}_JVpp${java_plugin_name mp->client_index = plugin_main->my_client_index; mp->context = clib_host_to_net_u32 (my_context_id); - $struct_setters + $msg_initialization + // send message: vl_msg_api_send_shmem (plugin_main->vl_input_queue, (u8 *)&mp); if ((*env)->ExceptionCheck(env)) { @@ -235,8 +155,7 @@ def generate_jni_impl(func_list, plugin_name, inputfile): arguments = '' request_class = '' - field_identifiers = '' - struct_setters = '' + msg_initialization = '' f_name_uppercase = f_name.upper() if f['args']: @@ -247,142 +166,29 @@ def generate_jni_impl(func_list, plugin_name, inputfile): java_name_upper=camel_case_function_name_upper, plugin_name=plugin_name) - # field identifiers - for t in zip(f['types'], f['args']): - jni_type = t[0] - java_field_name = util.underscore_to_camelcase(t[1]) - jni_signature = util.jni_2_signature_mapping[jni_type] - jni_getter = util.jni_field_accessors[jni_type] - field_identifiers += request_field_identifier_template.substitute( - jni_type=jni_type, - java_name=java_field_name, - jni_signature=jni_signature, - jni_getter=jni_getter) - - # field setters - for t in zip(f['c_types'], f['args'], f['lengths']): - c_type = t[0] - c_name = t[1] - field_length = t[2][0] - field_length_check = "" - - # check if we are processing variable length array: - if t[2][1]: - field_length = util.underscore_to_camelcase(t[2][0]) - - # enforce max length if array has fixed length or uses variable length syntax - if str(t[2][0]) != "0": - field_length_check = fixed_array_length_enforcement_template.substitute(field_length=field_length) - - java_field_name = util.underscore_to_camelcase(c_name) - - struct_setter_template = struct_setter_templates[c_type] - - struct_setters += struct_setter_template.substitute( - c_name=c_name, - java_name=java_field_name, - field_length_check=field_length_check) + for t in zip(f['types'], f['args'], f['lengths']): + field_name = util.underscore_to_camelcase(t[1]) + msg_initialization += jni_gen.jni_request_binding_for_type(field_type=t[0], c_name=t[1], + field_reference_name=field_name, + field_name=field_name, + field_length=t[2][0], + is_variable_len_array=t[2][1]) jni_impl.append(jni_impl_template.substitute( inputfile=inputfile, api_data=util.api_message_to_javadoc(f), - java_name=camel_case_function_name, + field_reference_name=camel_case_function_name, + field_name=camel_case_function_name, c_name_uppercase=f_name_uppercase, c_name=f_name, plugin_name=plugin_name, java_plugin_name=plugin_name.title(), request_class=request_class, - field_identifiers=field_identifiers, - struct_setters=struct_setters, + msg_initialization=msg_initialization, args=arguments)) return "\n".join(jni_impl) - -dto_field_id_template = Template(""" - jfieldID ${java_name}FieldId = (*env)->GetFieldID(env, ${class_ref_name}Class, "${java_name}", "${jni_signature}");""") - -default_dto_field_setter_template = Template(""" - (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, mp->${c_name}); -""") - -variable_length_array_value_template = Template("""mp->${length_var_name}""") -variable_length_array_template = Template("""clib_net_to_host_${length_field_type}(${value})""") - -u16_dto_field_setter_template = Template(""" - (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, clib_net_to_host_u16(mp->${c_name})); -""") - -u32_dto_field_setter_template = Template(""" - (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, clib_net_to_host_u32(mp->${c_name})); -""") - -u64_dto_field_setter_template = Template(""" - (*env)->Set${jni_setter}(env, dto, ${java_name}FieldId, clib_net_to_host_u64(mp->${c_name})); -""") - -u8_array_dto_field_setter_template = Template(""" - jbyteArray ${java_name} = (*env)->NewByteArray(env, ${field_length}); - (*env)->SetByteArrayRegion(env, ${java_name}, 0, ${field_length}, (const jbyte*)mp->${c_name}); - (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name}); -""") - -u16_array_dto_field_setter_template = Template(""" - { - jshortArray ${java_name} = (*env)->NewShortArray(env, ${field_length}); - jshort * ${java_name}ArrayElements = (*env)->GetShortArrayElements(env, ${java_name}, NULL); - unsigned int _i; - for (_i = 0; _i < ${field_length}; _i++) { - ${java_name}ArrayElements[_i] = clib_net_to_host_u16(mp->${c_name}[_i]); - } - - (*env)->ReleaseShortArrayElements(env, ${java_name}, ${java_name}ArrayElements, 0); - (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name}); - } -""") - -u32_array_dto_field_setter_template = Template(""" - { - jintArray ${java_name} = (*env)->NewIntArray(env, ${field_length}); - jint * ${java_name}ArrayElements = (*env)->GetIntArrayElements(env, ${java_name}, NULL); - unsigned int _i; - for (_i = 0; _i < ${field_length}; _i++) { - ${java_name}ArrayElements[_i] = clib_net_to_host_u32(mp->${c_name}[_i]); - } - - (*env)->ReleaseIntArrayElements(env, ${java_name}, ${java_name}ArrayElements, 0); - (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name}); - } -""") - -# For each u64 array we get its elements. Then we convert values to host byte order. -# All changes to jlong* buffer are written to jlongArray (isCopy is set to NULL) -u64_array_dto_field_setter_template = Template(""" - { - jlongArray ${java_name} = (*env)->NewLongArray(env, ${field_length}); - jlong * ${java_name}ArrayElements = (*env)->GetLongArrayElements(env, ${java_name}, NULL); - unsigned int _i; - for (_i = 0; _i < ${field_length}; _i++) { - ${java_name}ArrayElements[_i] = clib_net_to_host_u64(mp->${c_name}[_i]); - } - - (*env)->ReleaseLongArrayElements(env, ${java_name}, ${java_name}ArrayElements, 0); - (*env)->SetObjectField(env, dto, ${java_name}FieldId, ${java_name}); - } -""") - -dto_field_setter_templates = {'u8': default_dto_field_setter_template, - 'u16': u16_dto_field_setter_template, - 'u32': u32_dto_field_setter_template, - 'i32': u32_dto_field_setter_template, - 'u64': u64_dto_field_setter_template, - 'f64': default_dto_field_setter_template, #fixme - 'u8[]': u8_array_dto_field_setter_template, - 'u16[]': u16_array_dto_field_setter_template, - 'u32[]': u32_array_dto_field_setter_template, - 'u64[]': u64_array_dto_field_setter_template - } - # code fragment for checking result of the operation before sending request reply callback_err_handler_template = Template(""" // for negative result don't send callback message but send error callback @@ -418,6 +224,7 @@ static void vl_api_${handler_name}_t_handler (vl_api_${handler_name}_t * mp) (*env)->CallVoidMethod(env, plugin_main->callbackObject, callbackMethod, dto); }""") + def generate_msg_handlers(func_list, plugin_name, inputfile): handlers = [] for f in func_list: @@ -438,25 +245,20 @@ def generate_msg_handlers(func_list, plugin_name, inputfile): dto_setters = '' err_handler = '' # dto setters - for t in zip(f['c_types'], f['types'], f['args'], f['lengths']): - c_type = t[0] - jni_type = t[1] - c_name = t[2] - field_length = t[3][0] - - if jni_type.endswith('Array') and field_length == '0': - raise Exception('Variable array \'%s\' defined in message \'%s\' ' - 'should have defined length (e.g. \'%s[%s_length]\'' - % (c_name, handler_name, c_name, c_name)) - - # check if we are processing variable length array - if t[3][1]: - length_var_name = t[3][0] - length_field_type = f['c_types'][f['args'].index(length_var_name)] - field_length = variable_length_array_value_template.substitute(length_var_name=length_var_name) - if length_field_type != 'u8': # we need net to host conversion: - field_length = variable_length_array_template.substitute( - length_field_type=length_field_type, value=field_length) + for t in zip(f['types'], f['args'], f['lengths']): + c_name = t[1] + java_name = util.underscore_to_camelcase(c_name) + field_length = t[2][0] + is_variable_len_array = t[2][1] + length_field_type = None + if is_variable_len_array: + length_field_type = f['types'][f['args'].index(field_length)] + dto_setters += jni_gen.jni_reply_handler_for_type(handler_name=handler_name, ref_name=ref_name, + field_type=t[0], c_name=t[1], + field_reference_name=java_name, + field_name=java_name, field_length=field_length, + is_variable_len_array=is_variable_len_array, + length_field_type=length_field_type) # for retval don't generate setters and generate retval check if util.is_retval_field(c_name): @@ -465,24 +267,6 @@ def generate_msg_handlers(func_list, plugin_name, inputfile): ) continue - java_field_name = util.underscore_to_camelcase(c_name) - jni_signature = util.jni_2_signature_mapping[jni_type] - jni_setter = util.jni_field_accessors[jni_type] - - dto_setters += dto_field_id_template.substitute( - java_name=java_field_name, - class_ref_name=ref_name, - jni_signature=jni_signature) - - dto_setter_template = dto_field_setter_templates[c_type] - - dto_setters += dto_setter_template.substitute( - java_name=java_field_name, - jni_signature=jni_signature, - c_name=c_name, - jni_setter=jni_setter, - field_length=field_length) - handlers.append(msg_handler_template.substitute( inputfile=inputfile, api_data=util.api_message_to_javadoc(f), |