Cross-platform Unicode route processing

I use boost::filesystemcross-platform path manipulation, but this is interrupted when calls need to be reduced to interfaces that I do not control that will not accept UTF-8. For example, when using the Windows API, I need to convert to UTF-16, and then call the widescreen version of any function that I was going to call, and then convert any output back to UTF-8.

While the forms wpathand w*many of the many boost :: filesystem functions help keep sanity, are there any suggestions on how to best handle this conversion in large format when necessary, while maintaining consistency in my own code?

+3
source share
3 answers

Well, the easiest way is to make some kind of general routine that will return a string encoded the way you want for the provided path or wrapper class around the path.

boost::filesystem::wpath boostPath( L"c:\\some_path" );
MyPathWrapper p( boostPath );
std::wstring sUtf8 = p.file_string_utf8();
std::wstring sUtf16 = p.file_string_utf16();
// or
std::wstring sUtf8 = p.file_string( CP_UTF8 );
// ...

Something like that.

+2
source

What I've done:

struct vpath_traits;

typedef boost::filesystem::basic_path<std::string, vpath_traits> vpath;

// utf8 
struct vpath_traits
{
  typedef std::string internal_string_type;
  typedef std::wstring external_string_type;
  static external_string_type to_external(
      const vpath &, const internal_string_type &src);
  static internal_string_type to_internal(const external_string_type &src);
};


namespace boost {
  namespace filesystem {
    template<> struct is_basic_path<vpath>
    { BOOST_STATIC_CONSTANT( bool, value = true ); };
  }
}

// convenient functions for converting vpath to and from
// whatever API you may be using.

std::string    vpathToWin32Byte(const vpath &src);
vpath          vpathFromWin32Byte(const std::string &str);
vpath          vpathFromWin32Byte(const char *str);

std::wstring   vpathToWin32Wide(const vpath &src);
vpath          vpathFromWin32Wide(const std::wstring &str);
vpath          vpathFromWin32Wide(const wchar_t *str);

QDir           vpathToQDir(const vpath &src);
vpath          vpathFromQDir(const QDir &qdir);

Note:

You must somehow implement the vpath_traits::to_externaland methods vpath_traits::to_internal. There is probably some utf8 converter to increase. However, I applied utf8 to ucs-16 and came back myself, but it's neither pretty nor complete, so you better use some standard implementations.

It works in our code. E g:

namespace fs = boost::filesystem;
...

vpath dstFile = dstDir / filePath;
bool success = true;

try { fs::remove(dstFile); }
catch (fs::basic_filesystem_error<vpath> & /* e */) { success = false;}

if (success) {
  try { fs::copy_file(srcFile, dstFile); }
  catch (fs::basic_filesystem_error<vpath> & /* e */) { success = false;}
}

...
+1
source

:

0
source

Source: https://habr.com/ru/post/1723443/


All Articles