Skip to content

Instantly share code, notes, and snippets.

@iratqq
Created December 7, 2008 16:00
Show Gist options
  • Save iratqq/33172 to your computer and use it in GitHub Desktop.
Save iratqq/33172 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iconv.h>
int
iconv_convert(char **outstr, char *instr, const char *tocode, const char *fromcode)
{
iconv_t cd;
size_t ins;
char *in;
size_t outbufsiz, outs;
char *outbuf, *out;
size_t ret = 0, irr = 0;
size_t idx = 0;
size_t nconv = 0;
char *str = NULL;
cd = iconv_open(tocode, fromcode);
if (cd == (iconv_t)-1)
return -1;
ins = strlen(instr);
in = instr;
outbufsiz = BUFSIZ;
if ((out = outbuf = malloc(outbufsiz)) == NULL)
return -1;
while (ins > 0) {
out = outbuf;
outs = outbufsiz;
ret = iconv(cd, &in, &ins, &out, &outs);
nconv = outbufsiz - outs;
if (ret == (size_t)-1) {
switch (errno) {
case EINVAL:
goto err;
case E2BIG:
outbufsiz *= 2;
out = realloc(outbuf, outbufsiz);
if (!out)
goto err;
outbuf = out;
break;
default:
goto err;
}
} else {
irr += ret;
}
if (nconv > 0) {
char *newstr;
if (str == NULL)
newstr = malloc(nconv + 1);
else
newstr = realloc(str, idx + nconv + 1);
if (!newstr)
goto err;
str = newstr;
memcpy(&str[idx], outbuf, nconv);
idx += nconv;
}
}
do {
out = outbuf;
outs = outbufsiz;
ret = iconv(cd, NULL, NULL, &out, &outs);
nconv = outbufsiz - outs;
if (ret == (size_t)-1) {
outbufsiz *= 2;
out = realloc(outbuf, outbufsiz);
if (!out)
goto err;
outbuf = out;
} else {
irr += ret;
}
if (nconv > 0) {
char *newstr;
if (str == NULL)
newstr = malloc(nconv + 1);
else
newstr = realloc(str, idx + nconv + 1);
if (!newstr)
goto err;
str = newstr;
memcpy(&str[idx], outbuf, nconv);
idx += nconv;
}
} while (ret == (size_t)-1);
if (str == NULL)
str = strdup("");
else
str[idx] = '\0';
if (!str)
goto err;
*outstr = str;
iconv_close(cd);
return irr;
err:
free(str);
free(outbuf);
iconv_close(cd);
return -1;
}
int
main()
{
char *buf;
int ret;
ret = iconv_convert(&buf, "こんにちはこんにちは!", "EUC-JP", "UTF-8");
if (0 <= ret) {
printf("%d: %s\n", ret, buf);
free(buf);
}
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment