Skip to content

What exactly "write_to_string" expected to do? #10

Open
@r7vme

Description

@r7vme

Hello, I'm trying to understand what write_to_string expected to do. For example, for rosidl_runtime_c__U16String with content "Hello World", I expect that resulted std::string will also have contents "Hello World". But because write_to_string bruteforce fully copies underlay memory, I see that after every char there is a null byte (which is treated as string terminate character).

When I try to print such string I get smth like

H       
e       
l       
l       
o       
        
W       
o       
r       
l       
d 
    

String conversion between std::string and std::wstring is quite complex topic, coversion may not succeed (narrowing conversion from char16 to char8). I'm not generally sure that what you do here is right, because as a result you get ill-formed string.

Should instead smth like std::codecvt_utf8_utf16 be used or wstring considered unsupported by rosidl_typesupport_protobuf?


More details

underlay memory

48 0 65 0 6c 0 6c 0 6f 0 20 0 57 0 6f 0 72 0 6c 0 64 0 <-- initial rosidl_runtime_c__U16String
48 0 65 0 6c 0 6c 0 6f 0 20 0 57 0 6f 0 72 0 6c 0 64 0 <-- converted std::string
48 65 6c 6c 6f 20 57 6f 72 6c 64 <-- expected std::string

following code was used to print above

void print_memory( const void * mem, unsigned int n ) {                                                                                                                                                                               
  const char * p = reinterpret_cast< const char *>( mem );                                                                                                                                                                            
  for ( unsigned int i = 0; i < n; i++ ) {                                                                                                                                                                                            
     std::cout << std::hex << int(p[i]) << " ";                                                                                                                                                                                       
  }                                                                                                                                                                                                                                     std::cout << std::endl;                                                                                                                                                                                                             
}                                                                                                                                                                                                                                     
                                                                                                                                                                                                                                      
TEST(test_wstring_conversion, write_to_string) {                                                                                                                                                                                      
  rosidl_runtime_c__U16String wstr;                           
  ASSERT_TRUE(rosidl_runtime_c__U16String__init(&wstr));                                                                                   
  ASSERT_TRUE(rosidl_runtime_c__U16String__assign(&wstr, reinterpret_cast<const uint16_t*>(u"Hello World")));                                                                                                                         
  std::string converted_str;                                                                                                                                                                                                          
  rosidl_typesupport_protobuf_c::write_to_string(wstr, converted_str);                                                                                                                                                                
  std::string expected_str{"Hello World"};                                                                                                                                                                                            
  print_memory(wstr.data, wstr.size * (sizeof(uint16_t) / sizeof(char)));                                                                                                                                                             
  print_memory(converted_str.data(), converted_str.size());                                                                                                                                                                           
  print_memory(expected_str.data(), expected_str.size());                                                                                                                                                                             
}  

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions