+/* C Strings {{{ */
+template <typename Type_>
+_finline size_t iconv_(size_t (*iconv)(iconv_t, Type_, size_t *, char **, size_t *), iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) {
+ return iconv(cd, const_cast<Type_>(inbuf), inbytesleft, outbuf, outbytesleft);
+}
+
+#ifdef __GLIBC__
+#define UCS_2_INTERNAL "UCS-2"
+#else
+#define UCS_2_INTERNAL "UCS-2-INTERNAL"
+#endif
+
+CYUTF8String CYPoolUTF8String(apr_pool_t *pool, CYUTF16String utf16) {
+ _assert(pool != NULL);
+
+ const char *in(reinterpret_cast<const char *>(utf16.data));
+
+ iconv_t conversion(_syscall(iconv_open("UTF-8", UCS_2_INTERNAL)));
+
+ // XXX: this is wrong
+ size_t size(utf16.size * 5);
+ char *out(new(pool) char[size]);
+ CYUTF8String utf8(out, size);
+
+ size = utf16.size * 2;
+ _syscall(iconv_(&iconv, conversion, const_cast<char **>(&in), &size, &out, &utf8.size));
+
+ *out = '\0';
+ utf8.size = out - utf8.data;
+
+ _syscall(iconv_close(conversion));
+
+ return utf8;
+}
+
+CYUTF16String CYPoolUTF16String(apr_pool_t *pool, CYUTF8String utf8) {
+ _assert(pool != NULL);
+
+ const char *in(utf8.data);
+
+ iconv_t conversion(_syscall(iconv_open(UCS_2_INTERNAL, "UTF-8")));
+
+ // XXX: this is wrong
+ size_t size(utf8.size * 5);
+ uint16_t *temp(new (pool) uint16_t[size]);
+ CYUTF16String utf16(temp, size * 2);
+ char *out(reinterpret_cast<char *>(temp));
+
+ size = utf8.size;
+ _syscall(iconv_(&iconv, conversion, const_cast<char **>(&in), &size, &out, &utf16.size));
+
+ utf16.size = reinterpret_cast<uint16_t *>(out) - utf16.data;
+ temp[utf16.size] = 0;
+
+ _syscall(iconv_close(conversion));
+
+ return utf16;
+}
+/* }}} */