1 |
// Iconv ISO-8859-1 To UTF-8 |
2 |
// |
3 |
// Douglas Thrift |
4 |
// |
5 |
// $Id$ |
6 |
|
7 |
#include <cxx/standard.hh> |
8 |
|
9 |
#include <hop/function.hpp> |
10 |
|
11 |
#include <iconv.h> |
12 |
|
13 |
#include "Iso88591ToUtf8.hpp" |
14 |
|
15 |
#define iconv_(conversion, inBytes, inBytesLeft, outBytes, outBytesLeft) iconv(conversion, const_cast<hop::FunctionTraits<__typeof__ (::iconv)>::Args::Tail::Head>(inBytes), inBytesLeft, outBytes, outBytesLeft) |
16 |
|
17 |
namespace Iconv |
18 |
{ |
19 |
|
20 |
cse::String Iso88591ToUtf8(const ext::Buffer &iso88591) |
21 |
{ |
22 |
::iconv_t conversion(::iconv_open("UTF-8", "ISO-8859-1")); |
23 |
|
24 |
if (conversion == ::iconv_t(-1)) |
25 |
throw api::Posix::Error(); |
26 |
|
27 |
ext::Buffer utf8(iso88591.GetSize()); |
28 |
const char *iso88591Bytes(iso88591.Begin()); |
29 |
char *utf8Bytes(utf8.Begin()); |
30 |
size_t code, iso88591BytesLeft(iso88591.GetSize()), utf8BytesLeft(utf8.GetSize()); |
31 |
|
32 |
while ((code = ::iconv_(conversion, &iso88591Bytes, &iso88591BytesLeft, &utf8Bytes, &utf8BytesLeft)) == size_t(-1)) |
33 |
if (errno == E2BIG) |
34 |
{ |
35 |
utf8.SetSize(utf8.GetSize() + (utf8BytesLeft += iso88591BytesLeft)); |
36 |
|
37 |
utf8Bytes = utf8.End() - utf8BytesLeft; |
38 |
} |
39 |
else |
40 |
api::Posix::CheckError(code); |
41 |
|
42 |
api::Posix::CheckError(::iconv_close(conversion)); |
43 |
|
44 |
return utf8; |
45 |
} |
46 |
|
47 |
} |