X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fsupport%2Funicode.h;h=6559cf60b60e0c569943d8e5b4ad99cf64f345a8;hb=b96ce9a9c101a711ef8a1cdd5d6fe812a18966da;hp=d81b454502b254505a4c3abc3239d82f4691a1cb;hpb=9160d824d87d27088db65afa0bcf0951c2db08cc;p=lyx.git diff --git a/src/support/unicode.h b/src/support/unicode.h index d81b454502..6559cf60b6 100644 --- a/src/support/unicode.h +++ b/src/support/unicode.h @@ -1,9 +1,10 @@ +// -*- C++ -*- /** * \file unicode.h * This file is part of LyX, the document processor. * Licence details can be found in the file COPYING. * - * \author Lars Gullik Bjønnes + * \author Lars Gullik Bjønnes * * Full author contact details are available in file CREDITS. * @@ -14,37 +15,59 @@ #define LYX_SUPPORT_UNICODE_H #include "support/strfwd.h" +#include "support/unique_ptr.h" +#include +#include #include namespace lyx { +/** + * Wrapper for iconv(3). + * + * According to the POSIX standard, all specified functions are thread-safe, + * with some exceptions. The iconv() function is not listed as an exception: + * http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xsh_chap02.html#tag_22_02_09_09 + * http://man7.org/linux/man-pages/man7/pthreads.7.html + * + * Therefore, you can use as many instances of this class in parallel as you + * like. However, you need to ensure that each instance is only used by one + * thread at any given time. If this condition is not met you get nasty + * mixtures of different thread data as in bug 7240. + * + * From a performance point of view it is best to use one static instance + * per thread for each in/out encoding pair. This can e.g. be achieved by + * using helpers for thread-local storage such as QThreadStorage or + * boost::thread_specific_ptr. A single static instance protected by a mutex + * would work as well, and might be preferrable for exotic encoding pairs. + * Creating local IconvProcessor instances should be avoided because of the + * overhead in iconv_open(). + */ class IconvProcessor { + /// open iconv. + /// \return true if the processor is ready to use. + bool init(); + std::string const tocode_; + std::string const fromcode_; + struct Handler; + unique_ptr h_; public: - IconvProcessor(char const * tocode = "", char const * fromcode = ""); - /// copy constructor needed because of pimpl_ - IconvProcessor(IconvProcessor const &); - /// assignment operator needed because of pimpl_ - void operator=(IconvProcessor const &); - /// destructor - ~IconvProcessor(); - + IconvProcessor(std::string tocode, std::string fromcode); /// convert any data from \c fromcode to \c tocode unicode format. /// \return the number of bytes of the converted output buffer. int convert(char const * in_buffer, size_t in_size, char * out_buffer, size_t max_out_size); - -private: - /// open iconv. - /// \return true if the processor is ready to use. - bool init(); - /// hide internals - struct Impl; - Impl * pimpl_; + /// target encoding + std::string to() const { return tocode_; } }; +/// Get the global IconvProcessor instance of the current thread for +/// utf8->ucs4 conversions +IconvProcessor & utf8ToUcs4(); + // A single codepoint conversion for utf8_to_ucs4 does not make // sense, so that function is left out. @@ -60,6 +83,10 @@ std::vector utf16_to_ucs4(unsigned short const * s, size_t ls); std::vector ucs4_to_utf16(char_type const * s, size_t ls); +/// Get the global IconvProcessor instance of the current thread for +/// ucs4->utf8 conversions +IconvProcessor & ucs4ToUtf8(); + // ucs4_to_utf8 std::vector ucs4_to_utf8(char_type c); @@ -88,6 +115,8 @@ void ucs4_to_multibytes(char_type ucs4, std::vector & out, extern char const * ucs4_codeset; +/// How many bytes does one UCS4 code point use at most in encoding \p encoding? +int max_encoded_bytes(std::string const & encoding); } // namespace lyx