@@ -191,9 +191,14 @@ for member in message.structure.members:
191191 elif isinstance (member .type , AbstractSequence) and ' array.array' not in lazy_import_methods :
192192 lazy_import_methods .add (' array.array' )
193193 TEMPLATE (' _import_type.c.em' , full_type_name = ' array.array' , func_name = ' lazy_import_array' )
194- }@
195- @ {
194+
196195module_name = ' _' + convert_camel_case_to_lower_case_underscore (interface_path .stem )
196+ full_type_name = ' .' .join (message .structure .namespaced_type .namespaces + [module_name, message .structure .namespaced_type .name ])
197+ import_func_name = ' lazy_import_' + convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )
198+ no_fields = len (message .structure .members ) == 1 and message .structure .members [0 ].name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME
199+ TEMPLATE (
200+ ' _import_type.c.em' ,
201+ full_type_name = full_type_name, func_name = import_func_name, ensure_is_type = True)
197202}@
198203ROSIDL_GENERATOR_C_EXPORT
199204bool @ (' __' .join (message .structure .namespaced_type .namespaces + [convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )]))__convert_from_py (PyObject * _pymsg, void * _ros_message)
@@ -203,36 +208,17 @@ full_classname = '%s.%s.%s' % ('.'.join(message.structure.namespaced_type.namesp
203208}@
204209 // check that the passed message is of the expected Python class
205210 {
206- char full_classname_dest[@ (len (full_classname) + 1 )];
207- {
208- char * class_name = NULL;
209- char * module_name = NULL;
210- {
211- PyObject * class_attr = PyObject_GetAttrString (_pymsg, " __class__" );
212- if (class_attr) {
213- PyObject * name_attr = PyObject_GetAttrString (class_attr, " __name__" );
214- if (name_attr) {
215- class_name = (char * )PyUnicode_1BYTE_DATA (name_attr);
216- Py_DECREF (name_attr);
217- }
218- PyObject * module_attr = PyObject_GetAttrString (class_attr, " __module__" );
219- if (module_attr) {
220- module_name = (char * )PyUnicode_1BYTE_DATA (module_attr);
221- Py_DECREF (module_attr);
222- }
223- Py_DECREF (class_attr);
224- }
225- }
226- if (! class_name || ! module_name) {
227- return false ;
228- }
229- snprintf (full_classname_dest, sizeof (full_classname_dest), " %s.%s" , module_name, class_name);
230- }
231- assert (strncmp (" @(full_classname)" , full_classname_dest, @ (len (full_classname))) == 0 );
211+ PyTypeObject * py_type = (PyTypeObject * )@ (import_func_name)();
212+ assert (Py_TYPE (_pymsg) == py_type);
232213 }
233214 @ (msg_typename) * ros_message = _ros_message;
215+ @ [if no_fields]@
216+ ros_message-> @ (member .name ) = 0 ;
217+ @ [else ]
218+ @ (message .structure .namespaced_type .name )Base * base_msg = (@ (message .structure .namespaced_type .name )Base * )_pymsg;
219+ @ [end if ]@
234220@ [for member in message .structure .members ]@
235- @ [ if len ( message . structure . members ) == 1 and member . name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME ]@
221+ @ [ if no_fields ]@
236222 ros_message-> @ (member .name ) = 0 ;
237223@ [ continue ]@
238224@ [ end if ]@
@@ -242,31 +228,30 @@ if isinstance(type_, AbstractNestedType):
242228 type_ = type_ .value_type
243229}@
244230 { // @ (member .name )
245- PyObject * field = PyObject_GetAttrString (_pymsg, " @(member.name)" );
231+ @ [ if not isinstance (member .type , BasicType)]@
232+ PyObject * field = base_msg-> _@ (member .name );
246233 if (! field) {
247234 return false ;
248235 }
236+ @ [ end if ]@
249237@ [ if isinstance (type_, NamespacedType)]@
250238@ {
251239nested_type = ' __' .join (type_ .namespaced_name ())
252240}@
253241@ [ if isinstance (member .type , AbstractNestedType)]@
254242 PyObject * seq_field = PySequence_Fast (field, " expected a sequence in '@(member.name)'" );
255243 if (! seq_field) {
256- Py_DECREF (field);
257244 return false ;
258245 }
259246@ [ if isinstance (member .type , AbstractSequence)]@
260247 Py_ssize_t size = PySequence_Size (field);
261248 if (- 1 == size) {
262249 Py_DECREF (seq_field);
263- Py_DECREF (field);
264250 return false ;
265251 }
266252 if (! @ (nested_type)__Sequence__init (& (ros_message-> @ (member .name )), size)) {
267253 PyErr_SetString (PyExc_RuntimeError, " unable to create @(nested_type)__Sequence ros_message" );
268254 Py_DECREF (seq_field);
269- Py_DECREF (field);
270255 return false ;
271256 }
272257 @ (nested_type) * dest = ros_message-> @ (member .name ).data ;
@@ -277,14 +262,12 @@ nested_type = '__'.join(type_.namespaced_name())
277262 for (Py_ssize_t i = 0 ; i < size; ++ i) {
278263 if (! @ (' __' .join (type_ .namespaces + [convert_camel_case_to_lower_case_underscore (type_ .name )]))__convert_from_py (PySequence_Fast_GET_ITEM (seq_field, i), & dest[i])) {
279264 Py_DECREF (seq_field);
280- Py_DECREF (field);
281265 return false ;
282266 }
283267 }
284268 Py_DECREF (seq_field);
285269@ [ else ]@
286270 if (! @ (' __' .join (type_ .namespaces + [convert_camel_case_to_lower_case_underscore (type_ .name )]))__convert_from_py (field, & ros_message-> @ (member .name ))) {
287- Py_DECREF (field);
288271 return false ;
289272 }
290273@ [ end if ]@
@@ -295,21 +278,18 @@ nested_type = '__'.join(type_.namespaced_name())
295278 Py_buffer view;
296279 int rc = PyObject_GetBuffer (field, & view, PyBUF_SIMPLE);
297280 if (rc < 0 ) {
298- Py_DECREF (field);
299281 return false ;
300282 }
301283 Py_ssize_t size = view .len / sizeof (@ primitive_msg_type_to_c (member .type .value_type ));
302284 if (! rosidl_runtime_c__@ (member .type .value_type .typename )__Sequence__init (& (ros_message-> @ (member .name )), size)) {
303285 PyErr_SetString (PyExc_RuntimeError, " unable to create @(member.type.value_type.typename)__Sequence ros_message" );
304286 PyBuffer_Release (& view);
305- Py_DECREF (field);
306287 return false ;
307288 }
308289 @ primitive_msg_type_to_c (member .type .value_type ) * dest = ros_message-> @ (member .name ).data ;
309290 rc = PyBuffer_ToContiguous (dest, & view, view .len , ' C' );
310291 if (rc < 0 ) {
311292 PyBuffer_Release (& view);
312- Py_DECREF (field);
313293 return false ;
314294 }
315295 PyBuffer_Release (& view);
@@ -329,36 +309,31 @@ nested_type = '__'.join(type_.namespaced_name())
329309@ [ else ]@
330310 PyObject * seq_field = PySequence_Fast (field, " expected a sequence in '@(member.name)'" );
331311 if (! seq_field) {
332- Py_DECREF (field);
333312 return false ;
334313 }
335314@ [ end if ]@
336315@ [ if isinstance (member .type , AbstractSequence)]@
337316 Py_ssize_t size = PySequence_Size (field);
338317 if (- 1 == size) {
339318 Py_DECREF (seq_field);
340- Py_DECREF (field);
341319 return false ;
342320 }
343321@ [ if isinstance (member .type .value_type , AbstractString)]@
344322 if (! rosidl_runtime_c__String__Sequence__init (& (ros_message-> @ (member .name )), size)) {
345323 PyErr_SetString (PyExc_RuntimeError, " unable to create String__Sequence ros_message" );
346324 Py_DECREF (seq_field);
347- Py_DECREF (field);
348325 return false ;
349326 }
350327@ [ elif isinstance (member .type .value_type , AbstractWString)]@
351328 if (! rosidl_runtime_c__U16String__Sequence__init (& (ros_message-> @ (member .name )), size)) {
352329 PyErr_SetString (PyExc_RuntimeError, " unable to create U16String__Sequence ros_message" );
353330 Py_DECREF (seq_field);
354- Py_DECREF (field);
355331 return false ;
356332 }
357333@ [ else ]@
358334 if (! rosidl_runtime_c__@ (member .type .value_type .typename )__Sequence__init (& (ros_message-> @ (member .name )), size)) {
359335 PyErr_SetString (PyExc_RuntimeError, " unable to create @(member.type.value_type.typename)__Sequence ros_message" );
360336 Py_DECREF (seq_field);
361- Py_DECREF (field);
362337 return false ;
363338 }
364339@ [ end if ]@
@@ -372,7 +347,6 @@ nested_type = '__'.join(type_.namespaced_name())
372347 PyObject * item = PySequence_Fast_GET_ITEM (seq_field, i);
373348 if (! item) {
374349 Py_DECREF (seq_field);
375- Py_DECREF (field);
376350 return false ;
377351 }
378352@ [ end if ]@
@@ -396,7 +370,6 @@ nested_type = '__'.join(type_.namespaced_name())
396370 PyObject * encoded_item = PyUnicode_AsUTF8String (item);
397371 if (! encoded_item) {
398372 Py_DECREF (seq_field);
399- Py_DECREF (field);
400373 return false ;
401374 }
402375 rosidl_runtime_c__String__assign (& dest[i], PyBytes_AS_STRING (encoded_item));
@@ -407,7 +380,6 @@ nested_type = '__'.join(type_.namespaced_name())
407380 PyObject * encoded_item = PyUnicode_AsUTF16String (item);
408381 if (! encoded_item) {
409382 Py_DECREF (seq_field);
410- Py_DECREF (field);
411383 return false ;
412384 }
413385 char * buffer;
@@ -416,15 +388,13 @@ nested_type = '__'.join(type_.namespaced_name())
416388 if (rc) {
417389 Py_DECREF (encoded_item);
418390 Py_DECREF (seq_field);
419- Py_DECREF (field);
420391 return false ;
421392 }
422393 // use offset of 2 to skip BOM mark
423394 bool succeeded = rosidl_runtime_c__U16String__assignn_from_char (& dest[i], buffer + 2 , length - 2 );
424395 Py_DECREF (encoded_item);
425396 if (! succeeded) {
426397 Py_DECREF (seq_field);
427- Py_DECREF (field);
428398 return false ;
429399 }
430400@ [ elif isinstance (member .type .value_type , BasicType) and member .type .value_type .typename == ' boolean' ]@
@@ -468,18 +438,6 @@ nested_type = '__'.join(type_.namespaced_name())
468438 }
469439 Py_DECREF (seq_field);
470440 }
471- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' char' ]@
472- assert (PyUnicode_Check (field));
473- PyObject * encoded_field = PyUnicode_AsUTF8String (field);
474- if (! encoded_field) {
475- Py_DECREF (field);
476- return false ;
477- }
478- ros_message-> @ (member .name ) = PyBytes_AS_STRING (encoded_field)[0 ];
479- Py_DECREF (encoded_field);
480- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' octet' ]@
481- assert (PyBytes_Check (field));
482- ros_message-> @ (member .name ) = PyBytes_AS_STRING (field)[0 ];
483441@ [ elif isinstance (member .type , AbstractString)]@
484442 assert (PyUnicode_Check (field));
485443 PyObject * encoded_field = PyUnicode_AsUTF8String (field);
@@ -494,78 +452,38 @@ nested_type = '__'.join(type_.namespaced_name())
494452 // the returned string starts with a BOM mark and uses native byte order
495453 PyObject * encoded_field = PyUnicode_AsUTF16String (field);
496454 if (! encoded_field) {
497- Py_DECREF (field);
498455 return false ;
499456 }
500457 char * buffer;
501458 Py_ssize_t length;
502459 int rc = PyBytes_AsStringAndSize (encoded_field, & buffer, & length);
503460 if (rc) {
504461 Py_DECREF (encoded_field);
505- Py_DECREF (field);
506462 return false ;
507463 }
508464 // use offset of 2 to skip BOM mark
509465 {
510466 bool succeeded = rosidl_runtime_c__U16String__assignn_from_char (& ros_message-> @ (member .name ), buffer + 2 , length - 2 );
511467 Py_DECREF (encoded_field);
512468 if (! succeeded) {
513- Py_DECREF (field);
514469 return false ;
515470 }
516471 }
517- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' boolean' ]@
518- assert (PyBool_Check (field));
519- ros_message-> @ (member .name ) = (Py_True == field);
520- @ [ elif isinstance (member .type , BasicType) and member .type .typename in (' float' , ' double' )]@
521- assert (PyFloat_Check (field));
472+ @ [ elif isinstance (member .type , BasicType)]@
522473@ [ if member .type .typename == ' float' ]@
523- ros_message-> @ (member .name ) = (float)PyFloat_AS_DOUBLE (field );
474+ ros_message-> @ (member .name ) = (float)base_msg -> _ @ ( member . name );
524475@ [ else ]@
525- ros_message-> @ (member .name ) = PyFloat_AS_DOUBLE (field );
476+ ros_message-> @ (member .name ) = base_msg -> _ @ ( member . name );
526477@ [ end if ]@
527- @ [ elif isinstance (member .type , BasicType) and member .type .typename in (
528- ' int8' ,
529- ' int16' ,
530- ' int32' ,
531- )]@
532- assert (PyLong_Check (field));
533- ros_message-> @ (member .name ) = (@ (primitive_msg_type_to_c (member .type )))PyLong_AsLong (field);
534- @ [ elif isinstance (member .type , BasicType) and member .type .typename in (
535- ' uint8' ,
536- ' uint16' ,
537- ' uint32' ,
538- )]@
539- assert (PyLong_Check (field));
540- @ [ if member .type .typename == ' uint32' ]@
541- ros_message-> @ (member .name ) = PyLong_AsUnsignedLong (field);
542- @ [ else ]@
543- ros_message-> @ (member .name ) = (@ (primitive_msg_type_to_c (member .type )))PyLong_AsUnsignedLong (field);
544- @ [ end if ]@
545- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' int64' ]@
546- assert (PyLong_Check (field));
547- ros_message-> @ (member .name ) = PyLong_AsLongLong (field);
548- @ [ elif isinstance (member .type , BasicType) and member .type .typename == ' uint64' ]@
549- assert (PyLong_Check (field));
550- ros_message-> @ (member .name ) = PyLong_AsUnsignedLongLong (field);
551478@ [ else ]@
552479 assert (false );
553480@ [ end if ]@
554- Py_DECREF (field);
555481 }
556482@ [end for ]@
557483
558484 return true ;
559485}
560486
561- @ {
562- full_type_name = ' .' .join (message .structure .namespaced_type .namespaces + [module_name, message .structure .namespaced_type .name ])
563- import_func_name = ' lazy_import_' + convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )
564- TEMPLATE (
565- ' _import_type.c.em' ,
566- full_type_name = full_type_name, func_name = import_func_name, ensure_is_type = True)
567- }@
568-
569487ROSIDL_GENERATOR_C_EXPORT
570488PyObject * @ (' __' .join (message .structure .namespaced_type .namespaces + [convert_camel_case_to_lower_case_underscore (message .structure .namespaced_type .name )]))__convert_to_py (void * raw_ros_message)
571489{
@@ -591,13 +509,13 @@ PyObject * @('__'.join(message.structure.namespaced_type.namespaces + [convert_c
591509 return NULL;
592510 }
593511 }
594- @ [if len ( message . structure . members ) == 1 and member . name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME ]@
512+ @ [if no_fields ]@
595513 (void )raw_ros_message;
596514@ [else ]@
597515 @ (msg_typename) * ros_message = (@ (msg_typename) * )raw_ros_message;
598516@ [end if ]@
599517@ [for member in message .structure .members ]@
600- @ [ if len ( message . structure . members ) == 1 and member . name == EMPTY_STRUCTURE_REQUIRED_MEMBER_NAME ]@
518+ @ [ if no_fields ]@
601519@ [ continue ]@
602520@ [ end if ]@
603521@ {
0 commit comments