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);
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;
};
}
-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)
<< " 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;
<< " 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;
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));
}
-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);
}