@@ -22,15 +22,6 @@ from rosidl_parser.definition import NamespacedType
2222msg_normalized_type = ' __' .join (message .structure .namespaced_type .namespaced_name ())
2323msg_jni_type = ' /' .join (message .structure .namespaced_type .namespaced_name ())
2424
25- list_java_type = " java.util.List"
26- array_list_java_type = " java.util.ArrayList"
27-
28- list_normalized_type = " java__util__List"
29- list_jni_type = " java/util/List"
30-
31- array_list_normalized_type = " java__util__ArrayList"
32- array_list_jni_type = " java/util/ArrayList"
33-
3425# Collect JNI types and includes
3526cache = defaultdict (lambda : False)
3627cache[msg_normalized_type] = msg_jni_type
@@ -39,8 +30,6 @@ member_includes = set()
3930for member in message .structure .members :
4031 type_ = member .type
4132 if isinstance (type_, AbstractNestedType):
42- cache[list_normalized_type] = list_jni_type
43- cache[array_list_normalized_type] = array_list_jni_type
4433 type_ = type_ .value_type
4534 if isinstance (type_, BasicType):
4635 member_includes .add (' rosidl_generator_c/primitives_sequence.h' )
@@ -220,72 +209,92 @@ JNIEXPORT jlong JNICALL Java_@(underscore_separated_jni_type_name)_getDestructor
220209 }
221210@ [for member in message .structure .members ]@
222211@ {
223- normalized_type = get_normalized_type (member .type )
212+ if isinstance (member .type , AbstractNestedType):
213+ normalized_type = get_normalized_type (member .type .value_type )
214+ get_java_name = get_java_type (member .type .value_type , use_primitives = True)
215+ get_method_name = get_java_type (member .type .value_type , use_primitives = True).capitalize ()
216+ jni_signature = get_jni_signature (member .type .value_type )
217+ else :
218+ normalized_type = get_normalized_type (member .type )
219+ get_java_name = get_java_type (member .type , use_primitives = True)
220+ get_method_name = get_java_type (member .type , use_primitives = True).capitalize ()
221+ jni_signature = get_jni_signature (member .type )
224222}@
225223@ [ if isinstance (member .type , AbstractNestedType)]
226- auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " L@(list_jni_type);" );
227- jobject _jlist_@ (member .name )_object = env-> GetObjectField (_jmessage_obj, _jfield_@ (member .name )_fid);
224+ @ [ if isinstance (member .type .value_type , BasicType)]@
225+ auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " [@(jni_signature)" );
226+ j@ (get_java_name)Array _jarray_@ (member .name )_obj = (j@ (get_java_name)Array )env-> GetObjectField (_jmessage_obj, _jfield_@ (member .name )_fid);
227+ @ [ elif isinstance (member .type .value_type , AbstractGenericString)]@
228+ auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " [Ljava/lang/String;" );
229+ jobjectArray _jarray_@ (member .name )_obj = (jobjectArray)env-> GetObjectField (_jmessage_obj, _jfield_@ (member .name )_fid);
230+ @ [ else ]@
231+ auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " [L@('/'.join(member.type.value_type.namespaced_name()));" );
232+ jobjectArray _jarray_@ (member .name )_obj = (jobjectArray)env-> GetObjectField (_jmessage_obj, _jfield_@ (member .name )_fid);
233+ @ [ end if ]@
228234
229- if (_jlist_@ (member .name )_object != nullptr) {
230- jmethodID _jlist_@ (member .name )_get_mid = env-> GetMethodID (_j@ (list_normalized_type)_class_global, " get" , " (I)Ljava/lang/Object;" );
235+ if (_jarray_@ (member .name )_obj != nullptr) {
231236@ [ if isinstance (member .type , AbstractSequence)]@
232- jmethodID _jlist_@ (member .name )_size_mid = env-> GetMethodID (_j@ (list_normalized_type)_class_global, " size" , " ()I" );
233- jint _jlist_@ (member .name )_size = env-> CallIntMethod (_jlist_@ (member .name )_object, _jlist_@ (member .name )_size_mid);
237+ @ [ if isinstance (member .type , Array )]@
238+ jint _jarray_@ (member .name )_size = @ (member .type .size );
239+ @ [ else ]@
240+ jint _jarray_@ (member .name )_size = env-> GetArrayLength (_jarray_@ (member .name )_obj);
241+ @ [ end if ]@
234242@ [ if isinstance (member .type .value_type , AbstractString)]@
235- if (! rosidl_generator_c__String__Sequence__init (& (ros_message-> @ (member .name )), _jlist_ @ (member .name )_size)) {
243+ if (! rosidl_generator_c__String__Sequence__init (& (ros_message-> @ (member .name )), _jarray_ @ (member .name )_size)) {
236244 rcljava_throw_exception (env, " java/lang/IllegalStateException" , " unable to create String__Array ros_message" );
237245 }
238246@ [ elif isinstance (member .type .value_type , AbstractWString)]@
239- if (! rosidl_generator_c__U16String__Sequence__init (& (ros_message-> @ (member .name )), _jlist_ @ (member .name )_size)) {
247+ if (! rosidl_generator_c__U16String__Sequence__init (& (ros_message-> @ (member .name )), _jarray_ @ (member .name )_size)) {
240248 rcljava_throw_exception (env, " java/lang/IllegalStateException" , " unable to create U16String__Array ros_message" );
241249 }
242250@ [ else ]@
243251@ [ if isinstance (member .type .value_type , BasicType)]@
244- if (! rosidl_generator_c__@ (member .type .value_type .typename )__Sequence__init (& (ros_message-> @ (member .name )), _jlist_ @ (member .name )_size)) {
252+ if (! rosidl_generator_c__@ (member .type .value_type .typename )__Sequence__init (& (ros_message-> @ (member .name )), _jarray_ @ (member .name )_size)) {
245253 rcljava_throw_exception (env, " java/lang/IllegalStateException" , " unable to create @(member.type.value_type)__Array ros_message" );
246254 }
247255@ [ else ]@
248- if (! @ (' __' .join (member .type .value_type .namespaced_name ()))__Sequence__init (& (ros_message-> @ (member .name )), _jlist_ @ (member .name )_size)) {
256+ if (! @ (' __' .join (member .type .value_type .namespaced_name ()))__Sequence__init (& (ros_message-> @ (member .name )), _jarray_ @ (member .name )_size)) {
249257 rcljava_throw_exception (env, " java/lang/IllegalStateException" , " unable to create @(member.type.value_type)__Array ros_message" );
250258 }
251259
252260@ [ end if ]@
253261@ [ end if ]@
254262 auto _dest_@ (member .name ) = ros_message-> @ (member .name ).data ;
255263@ [ else ]@
256- jint _jlist_ @ (member .name )_size = @ (member .type .size );
264+ jint _jarray_ @ (member .name )_size = @ (member .type .size );
257265
258266 auto _dest_@ (member .name ) = ros_message-> @ (member .name );
259267@ [ end if ]@
260-
261- for (jint i = 0 ; i < _jlist_@ (member .name )_size; ++ i) {
262- auto element = env-> CallObjectMethod (_jlist_@ (member .name )_object, _jlist_@ (member .name )_get_mid, i);
263- @ [ if isinstance (member .type .value_type , AbstractString)]@
268+ @ [ if isinstance (member .type .value_type , BasicType)]@
269+ j@ (get_java_name) * _jarray_@ (member .name )_ptr = env-> Get@ (get_method_name)ArrayElements (_jarray_@ (member .name )_obj, nullptr);
270+ std :: copy (_jarray_@ (member .name )_ptr, _jarray_@ (member .name )_ptr + _jarray_@ (member .name )_size, _dest_@ (member .name ));
271+ env-> Release@ (get_method_name)ArrayElements (_jarray_@ (member .name )_obj, _jarray_@ (member .name )_ptr, 0 );
272+ @ [ else ]@
273+ for (jint i = 0 ; i < _jarray_@ (member .name )_size; ++ i) {
274+ auto element = env-> GetObjectArrayElement (_jarray_@ (member .name )_obj, i);
275+ @ [ if isinstance (member .type .value_type , AbstractString)]@
264276 jstring _jfield_@ (member .name )_value = static_cast<jstring >(element);
265277 if (_jfield_@ (member .name )_value != nullptr) {
266- const char * _str @ (member .name ) = env-> GetStringUTFChars (_jfield_@ (member .name )_value, 0 );
278+ const char * _str_ @ (member .name ) = env-> GetStringUTFChars (_jfield_@ (member .name )_value, 0 );
267279 rosidl_generator_c__String__assign (
268- & _dest_@ (member .name )[i], _str @ (member .name ));
269- env-> ReleaseStringUTFChars (_jfield_@ (member .name )_value, _str @ (member .name ));
280+ & _dest_@ (member .name )[i], _str_ @ (member .name ));
281+ env-> ReleaseStringUTFChars (_jfield_@ (member .name )_value, _str_ @ (member .name ));
270282 }
271- @ [ elif isinstance (member .type .value_type , AbstractWString)]@
283+ @ [ elif isinstance (member .type .value_type , AbstractWString)]@
272284 jstring _jfield_@ (member .name )_value = static_cast<jstring >(element);
273285 if (_jfield_@ (member .name )_value != nullptr) {
274- const jchar * _str @ (member .name ) = env-> GetStringChars (_jfield_@ (member .name )_value, 0 );
286+ const jchar * _str_ @ (member .name ) = env-> GetStringChars (_jfield_@ (member .name )_value, 0 );
275287 rosidl_generator_c__U16String__assign (
276- & _dest_@ (member .name )[i], _str @ (member .name ));
277- env-> ReleaseStringChars (_jfield_@ (member .name )_value, _str @ (member .name ));
288+ & _dest_@ (member .name )[i], _str_ @ (member .name ));
289+ env-> ReleaseStringChars (_jfield_@ (member .name )_value, _str_ @ (member .name ));
278290 }
279- @ [ elif isinstance (member .type .value_type , BasicType)]@
280- @ {
281- call_method_name = ' Call%sMethod' % get_java_type (member .type .value_type , use_primitives = True).capitalize ()
282- }@
283- _dest_@ (member .name )[i] = env-> @ (call_method_name)(element, _j@ (normalized_type)_value_global);
284- @ [ else ]@
291+ @ [ else ]@
285292 _dest_@ (member .name )[i] = * _j@ (normalized_type)_from_java_function (element, nullptr);
286- @ [ end if ]@
293+ @ [ end if ]@
287294 env-> DeleteLocalRef (element);
288295 }
296+ @ [ end if ]@
297+ env-> DeleteLocalRef (_jarray_@ (member .name )_obj);
289298 }
290299@ [ else ]@
291300@ [ if isinstance (member .type , AbstractGenericString)]@
@@ -349,61 +358,74 @@ jobject @(underscore_separated_type_name)__convert_to_java(@(msg_normalized_type
349358 }
350359@ [for member in message .structure .members ]@
351360@ {
352- normalized_type = get_normalized_type (member .type )
361+ if isinstance (member .type , AbstractNestedType):
362+ normalized_type = get_normalized_type (member .type .value_type )
363+ get_java_name = get_java_type (member .type .value_type , use_primitives = True)
364+ get_method_name = get_java_type (member .type .value_type , use_primitives = True).capitalize ()
365+ jni_signature = get_jni_signature (member .type .value_type )
366+ else :
367+ normalized_type = get_normalized_type (member .type )
368+ get_java_name = get_java_type (member .type , use_primitives = True)
369+ get_method_name = get_java_type (member .type , use_primitives = True).capitalize ()
370+ jni_signature = get_jni_signature (member .type )
353371}@
354372@ [ if isinstance (member .type , AbstractNestedType)]@
355373@ [ if isinstance (member .type .value_type , (BasicType, AbstractGenericString))]@
356- auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " L@(list_jni_type);" );
357- jobject _jarray_list_@ (member .name )_obj = env-> NewObject (_j@ (array_list_normalized_type)_class_global, _j@ (array_list_normalized_type)_constructor_global);
358- // TODO (esteve): replace ArrayList with a jobjectArray to initialize the array beforehand
359- jmethodID _jlist_@ (member .name )_add_mid = env-> GetMethodID (_j@ (array_list_normalized_type)_class_global, " add" , " (Ljava/lang/Object;)Z" );
374+ auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " [@(jni_signature)" );
375+ @ [ else ]@
376+ auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " [L@('/'.join(member.type.value_type.namespaced_name()));" );
377+ @ [ end if ]@
378+
379+ @ [ if isinstance (member .type .value_type , BasicType)]@
360380@ [ if isinstance (member .type , Array )]@
361- for (size_t i = 0 ; i < @ (member .type .size ); ++ i) {
381+ j@ (get_java_name)Array _jarray_@ (member .name )_obj = env-> New@ (get_method_name)Array (@ (member .type .size ));
382+ j@ (get_java_name) * _j@ (get_java_name)_@ (member .name )_buf = (j@ (get_java_name) * )malloc (sizeof (j@ (get_java_name)) * @ (member .type .size ));
383+ std :: copy (_ros_message-> @ (member .name ), _ros_message-> @ (member .name ) + @ (member .type .size ), _j@ (get_java_name)_@ (member .name )_buf);
384+ env-> Set @ (get_method_name)ArrayRegion (_jarray_@ (member .name )_obj, 0 , @ (member .type .size ), (const j@ (get_java_name) * )_j@ (get_java_name)_@ (member .name )_buf);
385+ @ [ else ]@
386+ j@ (get_java_name)Array _jarray_@ (member .name )_obj = env-> New@ (get_method_name)Array (_ros_message-> @ (member .name ).size );
387+ j@ (get_java_name) * _j@ (get_java_name)_@ (member .name )_buf = (j@ (get_java_name) * )malloc (sizeof (j@ (get_java_name)) * _ros_message-> @ (member .name ).size );
388+ std :: copy (_ros_message-> @ (member .name ).data , _ros_message-> @ (member .name ).data + _ros_message-> @ (member .name ).size , _j@ (get_java_name)_@ (member .name )_buf);
389+ env-> Set @ (get_method_name)ArrayRegion (_jarray_@ (member .name )_obj, 0 , _ros_message-> @ (member .name ).size , (const j@ (get_java_name) * )_j@ (get_java_name)_@ (member .name )_buf);
390+ @ [ end if ]@
391+ free (_j@ (get_java_name)_@ (member .name )_buf);
392+ @ [ elif isinstance (member .type .value_type , AbstractGenericString)]@
393+ @ [ if isinstance (member .type , Array )]@
394+ jobjectArray _jarray_@ (member .name )_obj = (jobjectArray)env-> NewObjectArray (@ (member .type .size ), env-> FindClass (" java/lang/String" ), NULL);
395+ for (size_t i = 0 ; i < @ (member .type .size ); i++ ) {
362396 auto _ros_@ (member .name )_element = _ros_message-> @ (member .name )[i];
363397@ [ else ]@
364- for (size_t i = 0 ; i < _ros_message-> @ (member .name ).size ; ++ i) {
398+ jobjectArray _jarray_@ (member .name )_obj = (jobjectArray)env-> NewObjectArray (_ros_message-> @ (member .name ).size , env-> FindClass (" java/lang/String" ), NULL);
399+ for (size_t i = 0 ; i < _ros_message-> @ (member .name ).size ; i++ ) {
365400 auto _ros_@ (member .name )_element = _ros_message-> @ (member .name ).data [i];
366401@ [ end if ]@
367- @ [ if isinstance (member .type .value_type , AbstractGenericString)]@
368- jobject _jlist_@ (member .name )_element = nullptr;
402+ jstring _jarray_@ (member .name )_element = nullptr;
369403 if (_ros_@ (member .name )_element .data != nullptr) {
370- @ [ if isinstance (member .type .value_type , AbstractString)]@
371- _jlist_@ (member .name )_element = env-> NewStringUTF (_ros_@ (member .name )_element .data );
372- @ [ else ]@
373- _jlist_@ (member .name )_element = env-> NewString (_ros_@ (member .name )_element .data , _ros_@ (member .name )_element .size );
374- @ [ end if ]@
375- }
404+ @ [ if isinstance (member .type .value_type , AbstractString)]@
405+ _jarray_@ (member .name )_element = env-> NewStringUTF (_ros_@ (member .name )_element .data );
376406@ [ else ]@
377- jobject _jlist_@ (member .name )_element = env-> NewObject (
378- _j@ (normalized_type)_class_global, _j@ (normalized_type)_constructor_global, _ros_@ (member .name )_element);
379- @ [ end if ]@
380- if (_jlist_@ (member .name )_element != nullptr) {
381- jboolean _jlist_@ (member .name )_add_result = env-> CallBooleanMethod (_jarray_list_@ (member .name )_obj, _jlist_@ (member .name )_add_mid, _jlist_@ (member .name )_element);
382- assert (_jlist_@ (member .name )_add_result);
407+ _jarray_@ (member .name )_element = env-> NewString (_ros_@ (member .name )_element .data , _ros_@ (member .name )_element .size );
408+ @ [ end if ]@
383409 }
410+ env-> SetObjectArrayElement (_jarray_@ (member .name )_obj, i, _jarray_@ (member .name )_element);
411+ env-> DeleteLocalRef (_jarray_@ (member .name )_element);
384412 }
385413@ [ else ]@
386-
387- auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " L@(list_jni_type);" );
388- jobject _jarray_list_@ (member .name )_obj = env-> NewObject (_j@ (array_list_normalized_type)_class_global, _j@ (array_list_normalized_type)_constructor_global);
389- // TODO (esteve): replace ArrayList with a jobjectArray to initialize the array beforehand
390- jmethodID _jlist_@ (member .name )_add_mid = env-> GetMethodID (_j@ (array_list_normalized_type)_class_global, " add" , " (Ljava/lang/Object;)Z" );
391-
392414@ [ if isinstance (member .type , Array )]@
393- for (size_t i = 0 ; i < @ (member .type .size ); ++ i) {
394- jobject _jlist_@ (member .name )_element = _j@ (normalized_type)_to_java_function (& (_ros_message-> @ (member .name )[i]), nullptr);
415+ jobjectArray _jarray_@ (member .name )_obj = (jobjectArray)env-> NewObjectArray (@ (member .type .size ), _j@ (normalized_type)_class_global, NULL);
416+ for (size_t i = 0 ; i < @ (member .type .size ); i++ ) {
417+ jobject _jarray_@ (member .name )_element = _j@ (normalized_type)_to_java_function (& (_ros_message-> @ (member .name )[i]), nullptr);
395418@ [ else ]@
396- for (size_t i = 0 ; i < _ros_message-> @ (member .name ).size ; ++ i) {
397- jobject _jlist_@ (member .name )_element = _j@ (normalized_type)_to_java_function (& (_ros_message-> @ (member .name ).data [i]), nullptr);
419+ jobjectArray _jarray_@ (member .name )_obj = (jobjectArray)env-> NewObjectArray (_ros_message-> @ (member .name ).size , _j@ (normalized_type)_class_global, NULL);
420+ for (size_t i = 0 ; i < _ros_message-> @ (member .name ).size ; i++ ) {
421+ jobject _jarray_@ (member .name )_element = _j@ (normalized_type)_to_java_function (& (_ros_message-> @ (member .name ).data [i]), nullptr);
398422@ [ end if ]@
399- if (_jlist_@ (member .name )_element != nullptr) {
400- jboolean _jlist_@ (member .name )_add_result = env-> CallBooleanMethod (_jarray_list_@ (member .name )_obj, _jlist_@ (member .name )_add_mid, _jlist_@ (member .name )_element);
401- assert (_jlist_@ (member .name )_add_result);
402- }
423+ env-> SetObjectArrayElement (_jarray_@ (member .name )_obj, i, _jarray_@ (member .name )_element);
424+ env-> DeleteLocalRef (_jarray_@ (member .name )_element);
403425 }
404426@ [ end if ]@
405- env-> SetObjectField (_jmessage_obj, _jfield_@ (member .name )_fid, _jarray_list_ @ (member .name )_obj);
406- env-> DeleteLocalRef (_jarray_list_ @ (member .name )_obj);
427+ env-> SetObjectField (_jmessage_obj, _jfield_@ (member .name )_fid, _jarray_ @ (member .name )_obj);
428+ env-> DeleteLocalRef (_jarray_ @ (member .name )_obj);
407429@ [ else ]@
408430@ [ if isinstance (member .type , AbstractGenericString)]@
409431 auto _jfield_@ (member .name )_fid = env-> GetFieldID (_j@ (msg_normalized_type)_class_global, " @(member.name)" , " Ljava/lang/String;" );
0 commit comments