/*----------------------------------------------------------------------
* Module name: my_iconv
* Author name: Arkadiusz Firus
* Create date: 07 Sep 08
* Purpose: iconv handles
*----------------------------------------------------------------------
Changes:
* 04 Jan 10, daved@physiol.usyd.edu.au: use path specfied with -P to
* load charmap file(s)
*--------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include "malloc.h"
#include "my_iconv.h"
#include "util.h"
#if 1 /* daved 0.21.1 */
#include "unicode.h"
#include "path.h"
#include <unistd.h>
#include <stdlib.h>
#endif
extern int verbose_mode;
my_iconv_t
my_iconv_open(const char *tocode, const char *fromcode)
{
char *path;
FILE *f;
my_iconv_t cd = MY_ICONV_T_CLEAR;
int c, i;
if ((cd.desc = iconv_open(tocode, fromcode)) == (iconv_t) -1)
{
#if 1 /* daved 0.21.1 */
struct path_dir *path_dir_p;
char u_success=0;
for(path_dir_p = &topdir; path_dir_p->dir_name; path_dir_p = path_dir_p->next)
{
char *p;
p = path_dir_p->dir_name;
if(*(p+strlen(p)-1) != '/')
p = concatenate(p, "/");
p = concatenate(p, fromcode);
path=concatenate(p, ".charmap");
if(access(path, F_OK|R_OK))
continue;
u_success++;
break;
}
if(!u_success)
{
#else
path = concatenate(CHARMAP_DIR, fromcode);
#endif
#if 1 /* daved 0.21.1 */
}
if((f = fopen(path, "r")) == NULL && verbose_mode)
fprintf(stderr, "failed to open charmap file %s\n", path);
#else
f = fopen(path, "r");
#endif
if (f != NULL)
{
cd.char_table = (char **)my_malloc(char_table_size * sizeof(char *));
c = fgetc(f);
for (i = 0; i < char_table_size && c != EOF; i++)
{
if (c == '<')
cd.char_table[i] = get_unicode_char(f);
leave_line(f);
c = fgetc(f);
}
fclose(f);
}
my_free(path);
}
return cd;
}
size_t
my_iconv(my_iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
{
int c, i;
size_t result = 0;
if (cd.desc == (iconv_t) -1) {
if (cd.char_table != NULL)
{
while (*inbytesleft > 0 && *outbytesleft > 0)
{
c = (int) **inbuf;
if (c < 0)
c = 256 + c;
if (cd.char_table[c] != NULL)
{
for (i = 0; cd.char_table[c][i] != '\0' && *outbytesleft > 0; i++)
{
**outbuf = cd.char_table[c][i];
(*outbytesleft)--;
(*outbuf)++;
}
}
(*inbuf)++;
(*inbytesleft)--;
result++;
}
}
}
else
result = iconv(cd.desc, inbuf, inbytesleft, outbuf, outbytesleft);
return result;
}
my_iconv_t
my_iconv_close(my_iconv_t cd)
{
int i;
if (cd.char_table != NULL)
{
for (i = 0; i < char_table_size; i++)
{
my_free(cd.char_table[i]);
}
my_free((void *)cd.char_table);
cd.char_table = NULL;
}
if (cd.desc != (iconv_t) -1)
{
iconv_close(cd.desc);
cd.desc = (iconv_t) -1;
}
return cd;
}
int
my_iconv_is_valid (my_iconv_t cd)
{
if (cd.desc != (iconv_t) -1 || cd.char_table != NULL)
return 1;
return 0;
}
void
my_iconv_t_make_invalid(my_iconv_t *cd)
{
cd->desc = (iconv_t) -1;
cd->char_table = NULL;
}