/* This file is part of Idest.
Copyright (C) 2016 Sergey Poznyakoff
Idest is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
Idest is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Idest. If not, see . */
#include "idest.h"
#include
#include
#ifdef HAVE_ICONV_H
# include
#endif
#ifndef ICONV_CONST
# define ICONV_CONST
#endif
#ifndef HAVE_ICONV
# undef iconv_open
# define iconv_open(tocode, fromcode) ((iconv_t) -1)
# undef iconv
# define iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft) ((size_t) 0)
# undef iconv_close
# define iconv_close(cd) 0
#endif
char const *charset;
char const *broken_8bit_charset;
static iconv_t conv_desc[] = { (iconv_t) -1, (iconv_t) -1, (iconv_t) -1 };
static iconv_t
utf8_init(int mode)
{
if (!charset)
charset = locale_charset();
if (conv_desc[mode] == (iconv_t) -1) {
switch (mode) {
case idest_conv_decode:
conv_desc[mode] = iconv_open(charset, "UTF-8");
break;
case idest_conv_encode:
conv_desc[mode] = iconv_open("UTF-8", charset);
break;
case idest_conv_recode:
conv_desc[mode] = iconv_open("UTF-8", broken_8bit_charset);
}
}
return conv_desc[mode];
}
int
utf8_convert(int mode, char const *input, char **output)
{
char ICONV_CONST *ib;
char *bufptr, *ob;
size_t inlen;
size_t outlen;
size_t rc;
iconv_t cd = utf8_init(mode);
if (cd == 0) {
*output = xstrdup(input);
return 0;
} else if (cd == (iconv_t)-1)
return -1;
inlen = strlen(input) + 1;
outlen = inlen * MB_LEN_MAX + 1;
ob = bufptr = xmalloc(outlen);
ib = (char ICONV_CONST *) input;
rc = iconv(cd, &ib, &inlen, &ob, &outlen);
if (rc == (size_t)-1) {
free(bufptr);
return -1;
}
*ob = 0;
*output = bufptr;
return 0;
}