module utile.encoding.iconv; import std.conv, std.string, std.encoding, core.stdc.errno, utile.except; version (linux) : auto iconv(string s, string from, string to) { auto q = to ~ `//IGNORE//TRANSLIT`; auto iv = iconv_open(q.toStringz, from.toStringz); cast(ptrdiff_t)iv != -1 || throwError!`can't convert from %s to %s`(from, to); scope (exit) { iconv_close(iv); } auto p = s.ptr; auto len = s.length; string res; char[2048] tmp = void; while (len) { auto b = tmp.ptr; auto bs = tmp.length; auto c = iconv(iv, cast(char**)&p, &len, &b, &bs); c != size_t.max || errno == E2BIG || throwError(`conversion error`); res ~= tmp[0 .. $ - bs]; } return res; } extern (C): void* iconv_open(in char*, in char*); size_t iconv(void*, char**, size_t*, char**, size_t*); int iconv_close(void*);