/** * @file charconv_iconv.c * * * @brief 文字コード変換 (iconvライブラリ使用) * * * * * @brief Character set conversion using iconv library * * * * @author Akinobu LEE * @date Thu Feb 17 16:02:41 2005 * * $Revision: 1.5 $ * */ /* * Copyright (c) 1991-2012 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2012 Julius project team, Nagoya Institute of Technology * All rights reserved */ #include "app.h" #ifdef CHARACTER_CONVERSION #ifdef HAVE_ICONV #include static iconv_t cd = (iconv_t)-1; ///< Converstion descriptor /** * Setup charset conversion for iconv. * * @param fromcode [in] input charset code name (NULL invalid) * @param tocode [in] output charset code name, or NULL when disable conversion * @param enable_conv [out] return whether conversion should be enabled or not * * @return TRUE on success, FALSE on failure (unknown code name). */ boolean charconv_iconv_setup(char *fromcode, char *tocode, boolean *enable_conv) { /* clear already allocated descriptor */ if (cd != (iconv_t)-1) { if (iconv_close(cd) < 0) { perror("j_prinf_set_iconv"); return FALSE; } cd = (iconv_t)-1; } if (tocode == NULL) { /* disable conversion */ *enable_conv = FALSE; } else { /* check for codes */ if (fromcode == NULL) { jlog("Error: charconv_iconv: charset names of both input and output should be given.\n"); jlog("Error: charconv_iconf: use \"-charconv from to\" instead of \"-kanji\".\n"); *enable_conv = FALSE; return FALSE; } /* allocate conversion descriptor */ cd = iconv_open(tocode, fromcode); if (cd == (iconv_t)-1) { /* allocation failed */ jlog("Error: charconv_iconv: unknown charset name in \"%s\" or \"%s\"\n", fromcode, tocode); jlog("Error: charconv_iconv: do \"iconv --list\" to get the list of available charset names.\n"); *enable_conv = FALSE; return FALSE; } *enable_conv = TRUE; } return TRUE; } /** * Apply charset conversion to a string using iconv. * * @param instr [in] source string * @param outstr [out] destination buffer * @param maxoutlen [in] allocated length of outstr in byte. * * @return either of instr or outstr, that holds the result string. * */ char * charconv_iconv(char *instr, char *outstr, int maxoutlen) { char *src, *dst; size_t srclen, dstlen; size_t ret; if (cd == (iconv_t)-1) { fprintf(stderr, "InternalError: codeconv: conversion descriptor not allocated\n"); exit(-1); } srclen = strlen(instr)+1; dstlen = maxoutlen; src = instr; dst = outstr; ret = iconv(cd, (ICONV_CONST char **)&src, &srclen, &dst, &dstlen); if (ret == -1) { switch(errno) { case EILSEQ: fprintf(stderr, "InternalError: codeconv: invalid multibyte sequence in the input\n"); exit(-1); break; case EINVAL: fprintf(stderr, "InternalError: codeconv: incomplete multibyte sequence in the input\n"); exit(-1); break; case E2BIG: fprintf(stderr, "InternalError: codeconv: converted string size exceeded buffer (>%d)\n", maxoutlen); exit(-1); break; } } /* outstr always holds the result */ return(outstr); } #endif /* HAVE_ICONV */ #endif /* CHARACTER_CONVERSION */