00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libnuclient.h"
00023 #include <stdlib.h>
00024 #include <errno.h>
00025 #include <string.h>
00026 #include <iconv.h>
00027 #include <langinfo.h>
00028 #include <stdio.h>
00029 #include <locale.h>
00030
00044 char *nu_client_to_utf8(const char *inbuf, char *from_charset)
00045 {
00046 iconv_t ctx;
00047 size_t inlen = strlen(inbuf);
00048 size_t maxlen = inlen * 4;
00049 char *outbuf;
00050 char *targetbuf;
00051 size_t real_outlen;
00052 size_t orig_inlen = inlen;
00053 size_t outbuflen = 3;
00054 size_t outbufleft;
00055 int ret;
00056
00057
00058 if (inbuf == NULL) {
00059 return NULL;
00060 }
00061
00062
00063 ctx = iconv_open("UTF-8", from_charset);
00064
00065
00066 outbuf = calloc(outbuflen, sizeof(char));
00067 nu_assert(outbuf != NULL, "iconv fail to allocate output buffer!");
00068
00069
00070 outbufleft = outbuflen - 1;
00071 targetbuf = outbuf;
00072 ret = iconv(ctx, (char **) &inbuf, &inlen, &targetbuf, &outbufleft);
00073 real_outlen = targetbuf - outbuf;
00074
00075
00076 if (ret == -1) {
00077 if (errno != E2BIG) {
00078 free(outbuf);
00079 iconv_close(ctx);
00080 panic("iconv error code %i!", ret);
00081 }
00082
00083 while ((ret == -1) && (errno == E2BIG)
00084 && (outbuflen < maxlen)) {
00085
00086 outbuflen += orig_inlen;
00087 outbuf = realloc(outbuf, outbuflen);
00088 if (outbuf == NULL) {
00089 free(outbuf);
00090 iconv_close(ctx);
00091 panic
00092 ("iconv error: can't rellocate buffer!");
00093 }
00094
00095
00096 outbufleft = outbuflen - real_outlen - 1;
00097 targetbuf = outbuf + real_outlen;
00098 ret = iconv(ctx, (char **) &inbuf, &inlen,
00099 &targetbuf, &outbufleft);
00100 real_outlen = targetbuf - outbuf;
00101 }
00102 }
00103
00104
00105 iconv_close(ctx);
00106
00107
00108 outbuflen = real_outlen + 1;
00109 outbuf = realloc(outbuf, outbuflen);
00110 outbuf[outbuflen - 1] = 0;
00111 return outbuf;
00112 }
00113