]> git.lyx.org Git - lyx.git/blobdiff - src/support/unicode.C
* support/qstring_helpers.h: erase ucs4_to_qstring() method.
[lyx.git] / src / support / unicode.C
index f5518b4f0beb6a1bf159f3e58e6d6c58158ee1d1..a9d5a6a634a21a811201dce53b1c8d0fdb7abf80 100644 (file)
 
 using std::endl;
 
+namespace {
+
+#ifdef WORDS_BIGENDIAN
+       char const * utf16_codeset = "UTF16-BE";
+#else
+       char const * utf16_codeset = "UTF16-LE";
+#endif
+
+}
+
+
 namespace lyx {
 
 #ifdef WORDS_BIGENDIAN
        char const * ucs4_codeset = "UCS-4BE";
-       char const * ucs2_codeset = "UCS-2BE";
 #else
        char const * ucs4_codeset = "UCS-4LE";
-       char const * ucs2_codeset = "UCS-2LE";
 #endif
 
 static const iconv_t invalid_cd = (iconv_t)(-1);
@@ -39,6 +48,15 @@ static const iconv_t invalid_cd = (iconv_t)(-1);
 
 struct IconvProcessor::Private {
        Private(): cd(invalid_cd) {}
+       ~Private()
+       {
+               if (cd != invalid_cd) {
+                       if (iconv_close(cd) == -1) {
+                               lyxerr << "Error returned from iconv_close("
+                                      << errno << ")" << endl;
+                       }
+               }
+       }
        iconv_t cd;
 };
 
@@ -50,16 +68,27 @@ IconvProcessor::IconvProcessor(char const * tocode,
 }
 
 
-IconvProcessor::~IconvProcessor()
+IconvProcessor::IconvProcessor(IconvProcessor const & other)
+       : tocode_(other.tocode_), fromcode_(other.fromcode_),
+         pimpl_(new IconvProcessor::Private)
 {
-       if (iconv_close(pimpl_->cd) == -1) {
-               lyxerr << "Error returned from iconv_close("
-                       << errno << ")" << endl;
-       }
-       delete pimpl_;
 }
 
 
+IconvProcessor & IconvProcessor::operator=(IconvProcessor const & other)
+{
+       if (&other == this)
+               return *this;
+       tocode_ = other.tocode_;
+       fromcode_ = other.fromcode_;
+       pimpl_.reset(new Private);
+       return *this;
+}
+
+
+IconvProcessor::~IconvProcessor() {}
+
+
 bool IconvProcessor::init()
 {
        if (pimpl_->cd != invalid_cd)
@@ -121,10 +150,13 @@ int IconvProcessor::convert(char const * buf, size_t buflen,
                                << " has been encountered in the input.\n"
                                << "When converting from " << fromcode_
                                << " to " << tocode_ << ".\n";
-                       lyxerr << "Input: " << std::hex;
+                       lyxerr << "Input:" << std::hex;
                        for (size_t i = 0; i < buflen; ++i) {
-                               boost::uint32_t const b = buf[i];
-                               lyxerr << "0x" << b << " ";
+                               // char may be signed, avoid output of
+                               // something like 0xffffffc2
+                               boost::uint32_t const b =
+                                       *reinterpret_cast<unsigned char const *>(buf + i);
+                               lyxerr << " 0x" << b;
                        }
                        lyxerr << endl;
                        break;
@@ -133,10 +165,13 @@ int IconvProcessor::convert(char const * buf, size_t buflen,
                                << " has been encountered in the input.\n"
                                << "When converting from " << fromcode_
                                << " to " << tocode_ << ".\n";
-                       lyxerr << "Input: " << std::hex;
+                       lyxerr << "Input:" << std::hex;
                        for (size_t i = 0; i < buflen; ++i) {
-                               boost::uint32_t const b = buf[i];
-                               lyxerr << "0x" << b << " ";
+                               // char may be signed, avoid output of
+                               // something like 0xffffffc2
+                               boost::uint32_t const b =
+                                       *reinterpret_cast<unsigned char const *>(buf + i);
+                               lyxerr << " 0x" << b;
                        }
                        lyxerr << endl;
                        break;
@@ -174,6 +209,10 @@ iconv_convert(IconvProcessor & processor,
        char * outbuf = out;
 
        int bytes = processor.convert(inbuf, inbytesleft, outbuf, outsize);
+       if (bytes <= 0)
+               // Conversion failed
+               // FIXME Maybe throw an exception and handle that in the caller?
+               return std::vector<RetType>();
 
        RetType const * tmp = reinterpret_cast<RetType const *>(out);
        return std::vector<RetType>(tmp, tmp + bytes / sizeof(RetType));
@@ -199,52 +238,18 @@ utf8_to_ucs4(char const * utf8str, size_t ls)
 }
 
 
-lyx::char_type
-ucs2_to_ucs4(unsigned short c)
+std::vector<char_type>
+utf16_to_ucs4(unsigned short const * s, size_t ls)
 {
-       return ucs2_to_ucs4(&c, 1)[0];
-}
-
-
-std::vector<lyx::char_type>
-ucs2_to_ucs4(std::vector<unsigned short> const & ucs2str)
-{
-       if (ucs2str.empty())
-               return std::vector<lyx::char_type>();
-
-       return ucs2_to_ucs4(&ucs2str[0], ucs2str.size());
-}
-
-
-std::vector<lyx::char_type>
-ucs2_to_ucs4(unsigned short const * ucs2str, size_t ls)
-{
-       static IconvProcessor processor(ucs4_codeset, ucs2_codeset);
-       return iconv_convert<lyx::char_type>(processor, ucs2str, ls);
-}
-
-
-unsigned short
-ucs4_to_ucs2(lyx::char_type c)
-{
-       return ucs4_to_ucs2(&c, 1)[0];
-}
-
-
-std::vector<unsigned short>
-ucs4_to_ucs2(std::vector<lyx::char_type> const & ucs4str)
-{
-       if (ucs4str.empty())
-               return std::vector<unsigned short>();
-
-       return ucs4_to_ucs2(&ucs4str[0], ucs4str.size());
+       static IconvProcessor processor(ucs4_codeset, utf16_codeset);
+       return iconv_convert<char_type>(processor, s, ls);
 }
 
 
 std::vector<unsigned short>
-ucs4_to_ucs2(lyx::char_type const * s, size_t ls)
+ucs4_to_utf16(char_type const * s, size_t ls)
 {
-       static IconvProcessor processor(ucs2_codeset, ucs4_codeset);
+       static IconvProcessor processor(utf16_codeset, ucs4_codeset);
        return iconv_convert<unsigned short>(processor, s, ls);
 }