+
+char ucs4_to_eightbit(char_type ucs4, string const & encoding)
+{
+ map<string, IconvProcessor> & processors(ucs4To8bitProcessors());
+ map<string, IconvProcessor>::iterator it = processors.find(encoding);
+ if (it == processors.end()) {
+ IconvProcessor processor(encoding.c_str(), ucs4_codeset);
+ it = processors.insert(make_pair(encoding, processor)).first;
+ }
+
+ char out;
+ int const bytes = it->second.convert((char *)(&ucs4), 4, &out, 1);
+ if (bytes > 0)
+ return out;
+ return 0;
+}
+
+
+void ucs4_to_multibytes(char_type ucs4, vector<char> & out,
+ string const & encoding)
+{
+ static QThreadStorage<map<string, IconvProcessor> *> static_processors;
+ if (!static_processors.hasLocalData())
+ static_processors.setLocalData(new map<string, IconvProcessor>);
+ map<string, IconvProcessor> & processors = *static_processors.localData();
+ map<string, IconvProcessor>::iterator it = processors.find(encoding);
+ if (it == processors.end()) {
+ IconvProcessor processor(encoding.c_str(), ucs4_codeset);
+ it = processors.insert(make_pair(encoding, processor)).first;
+ }
+
+ out.resize(4);
+ int bytes = it->second.convert((char *)(&ucs4), 4, &out[0], 4);
+ if (bytes > 0)
+ out.resize(bytes);
+ else
+ out.clear();
+}
+
+int max_encoded_bytes(std::string const & encoding)
+{
+ // FIXME: this information should be transferred to lib/encodings
+ // UTF8 uses at most 4 bytes to represent one UCS4 code point
+ // (see RFC 3629). RFC 2279 specifies 6 bytes, but that
+ // information is outdated, and RFC 2279 has been superseded by
+ // RFC 3629.
+ // The CJK encodings use (different) multibyte representation as well.
+ // All other encodings encode one UCS4 code point in one byte
+ // (and can therefore only encode a subset of UCS4)
+ // Furthermore, all encodings that use shifting (like SJIS) do not work with
+ // iconv_codecvt_facet.
+ if (encoding == "UTF-8" ||
+ encoding == "GB" ||
+ encoding == "EUC-TW")
+ return 4;
+ else if (encoding == "EUC-JP")
+ return 3;
+ else if (encoding == "ISO-2022-JP")
+ return 8;
+ else if (encoding == "BIG5" ||
+ encoding == "EUC-KR" ||
+ encoding == "EUC-CN" ||
+ encoding == "SJIS" ||
+ encoding == "GBK")
+ return 2;
+ else
+ return 1;
+}
+