diff liboctave/util/oct-string.cc @ 26702:2dc190401eeb

Add C++ functions to convert encoding of strings (bug #55452). * oct-string.[h,cc] (u8_to_encoding, u8_from_encoding): New functions.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 02 Feb 2019 20:07:45 +0100
parents 00f796120a6d
children d503426130bf
line wrap: on
line diff
--- a/liboctave/util/oct-string.cc	Fri Feb 08 17:33:14 2019 -0800
+++ b/liboctave/util/oct-string.cc	Sat Feb 02 20:07:45 2019 +0100
@@ -34,6 +34,8 @@
 #include "Array.h"
 #include "lo-ieee.h"
 #include "lo-mappers.h"
+#include "uniconv-wrappers.h"
+#include "unwind-prot.h"
 
 template <typename T>
 static bool
@@ -484,6 +486,70 @@
   return val;
 }
 
+std::string
+octave::string::u8_to_encoding (const std::string& who,
+                                const std::string& u8_string,
+                                const std::string& encoding)
+{
+  const uint8_t *src = reinterpret_cast<const uint8_t *>
+                       (u8_string.c_str ());
+  size_t srclen = u8_string.length ();
+
+  size_t length;
+  char *native_str = octave_u8_conv_to_encoding (encoding.c_str (), src,
+                                                 srclen, &length);
+
+  if (! native_str)
+    {
+      if (errno == ENOSYS)
+        (*current_liboctave_error_handler)
+          ("%s: iconv() is not supported. Installing GNU libiconv and then "
+           "re-compiling Octave could fix this.", who.c_str ());
+      else
+        (*current_liboctave_error_handler)
+          ("%s: converting from UTF-8 to codepage '%s' failed: %s",
+           who.c_str (), encoding.c_str (), std::strerror (errno));
+    }
+
+  octave::unwind_protect frame;
+  frame.add_fcn (::free, static_cast<void *> (native_str));
+
+  std::string retval = std::string (native_str, length);
+
+  return retval;
+}
+
+std::string
+octave::string::u8_from_encoding (const std::string& who,
+                                  const std::string& native_string,
+                                  const std::string& encoding)
+{
+  const char *src = native_string.c_str ();
+  size_t srclen = native_string.length ();
+
+  size_t length;
+  uint8_t *utf8_str = octave_u8_conv_from_encoding (encoding.c_str (), src,
+                                                    srclen, &length);
+  if (! utf8_str)
+    {
+      if (errno == ENOSYS)
+        (*current_liboctave_error_handler)
+          ("%s: iconv() is not supported. Installing GNU libiconv and then "
+           "re-compiling Octave could fix this.", who.c_str ());
+      else
+        (*current_liboctave_error_handler)
+          ("%s: converting from codepage '%s' to UTF-8 failed: %s",
+           who.c_str (), encoding.c_str (), std::strerror (errno));
+    }
+
+  octave::unwind_protect frame;
+  frame.add_fcn (::free, static_cast<void *> (utf8_str));
+
+  std::string retval = std::string (reinterpret_cast<char *> (utf8_str), length);
+
+  return retval;
+}
+
 template <typename T>
 std::string
 rational_approx (T val, int len)