X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=util%2Fsiconv.c;h=73d7148c06942fe3629c78419fd5f1875cfb5128;hb=c39a893dfdae5f792139177132e7e7a70e010aa7;hp=8bbc4edb69f4346ecb7f8e8f742b688cf68d74b9;hpb=165b231b0f6eaa0b2b5fbf438f5ddede630b10e3;p=yaz-moved-to-github.git diff --git a/util/siconv.c b/util/siconv.c index 8bbc4ed..73d7148 100644 --- a/util/siconv.c +++ b/util/siconv.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1997-2002, Index Data + * Copyright (c) 1997-2003, Index Data * See the file LICENSE for details. * - * $Id: siconv.c,v 1.5 2002-09-24 08:05:41 adam Exp $ + * $Id: siconv.c,v 1.9 2003-01-06 08:20:28 adam Exp $ */ /* mini iconv and wrapper for system iconv library (if present) */ @@ -14,6 +14,9 @@ #include #include #include +#if HAVE_WCHAR_H +#include +#endif #if HAVE_ICONV_H #include @@ -21,6 +24,9 @@ #include +unsigned long yaz_marc8_conv (unsigned char *inp, size_t inbytesleft, + size_t *no_read); + struct yaz_iconv_struct { int my_errno; int init_flag; @@ -185,6 +191,34 @@ static unsigned long yaz_read_UCS4LE (yaz_iconv_t cd, unsigned char *inp, return x; } +#if HAVE_WCHAR_H +static unsigned long yaz_read_wchar_t (yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + unsigned long x = 0; + + if (inbytesleft < sizeof(wchar_t)) + { + cd->my_errno = YAZ_ICONV_EINVAL; /* incomplete input */ + *no_read = 0; + } + else + { + wchar_t wch; + memcpy (&wch, inp, sizeof(wch)); + x = wch; + *no_read = sizeof(wch); + } + return x; +} +#endif + +static unsigned long yaz_read_marc8 (yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + return yaz_marc8_conv(inp, inbytesleft, no_read); +} + static size_t yaz_write_UTF8 (yaz_iconv_t cd, unsigned long x, char **outbuf, size_t *outbytesleft) { @@ -309,6 +343,34 @@ static size_t yaz_write_UCS4LE (yaz_iconv_t cd, unsigned long x, return 0; } +#if HAVE_WCHAR_H +static size_t yaz_write_wchar_t (yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft) +{ + unsigned char *outp = (unsigned char *) *outbuf; + + if (*outbytesleft >= sizeof(wchar_t)) + { + wchar_t wch = x; + memcpy(outp, &wch, sizeof(wch)); + outp += sizeof(wch); + (*outbytesleft) -= sizeof(wch); + } + else + { + cd->my_errno = YAZ_ICONV_E2BIG; + return (size_t)(-1); + } + *outbuf = (char *) outp; + return 0; +} +#endif + +int yaz_iconv_isbuiltin(yaz_iconv_t cd) +{ + return cd->read_handle && cd->write_handle; +} + yaz_iconv_t yaz_iconv_open (const char *tocode, const char *fromcode) { yaz_iconv_t cd = (yaz_iconv_t) xmalloc (sizeof(*cd)); @@ -318,27 +380,43 @@ yaz_iconv_t yaz_iconv_open (const char *tocode, const char *fromcode) cd->init_handle = 0; cd->my_errno = YAZ_ICONV_UNKNOWN; - if (!yaz_matchstr(fromcode, "UTF8")) + /* a useful hack: if fromcode has leading @, + the library not use YAZ's own conversions .. */ + if (fromcode[0] == '@') + fromcode++; + else { - cd->read_handle = yaz_read_UTF8; - cd->init_handle = yaz_init_UTF8; + if (!yaz_matchstr(fromcode, "UTF8")) + { + cd->read_handle = yaz_read_UTF8; + cd->init_handle = yaz_init_UTF8; + } + else if (!yaz_matchstr(fromcode, "ISO88591")) + cd->read_handle = yaz_read_ISO8859_1; + else if (!yaz_matchstr(fromcode, "UCS4")) + cd->read_handle = yaz_read_UCS4; + else if (!yaz_matchstr(fromcode, "UCS4LE")) + cd->read_handle = yaz_read_UCS4LE; + else if (!yaz_matchstr(fromcode, "MARC8")) + cd->read_handle = yaz_read_marc8; +#if HAVE_WCHAR_H + else if (!yaz_matchstr(fromcode, "WCHAR_T")) + cd->read_handle = yaz_read_wchar_t; +#endif + + if (!yaz_matchstr(tocode, "UTF8")) + cd->write_handle = yaz_write_UTF8; + else if (!yaz_matchstr(tocode, "ISO88591")) + cd->write_handle = yaz_write_ISO8859_1; + else if (!yaz_matchstr (tocode, "UCS4")) + cd->write_handle = yaz_write_UCS4; + else if (!yaz_matchstr(tocode, "UCS4LE")) + cd->write_handle = yaz_write_UCS4LE; +#if HAVE_WCHAR_H + else if (!yaz_matchstr(tocode, "WCHAR_T")) + cd->write_handle = yaz_write_wchar_t; +#endif } - else if (!yaz_matchstr(fromcode, "ISO88591")) - cd->read_handle = yaz_read_ISO8859_1; - else if (!yaz_matchstr(fromcode, "UCS4")) - cd->read_handle = yaz_read_UCS4; - else if (!yaz_matchstr(fromcode, "UCS4LE")) - cd->read_handle = yaz_read_UCS4LE; - - if (!yaz_matchstr(tocode, "UTF8")) - cd->write_handle = yaz_write_UTF8; - else if (!yaz_matchstr(tocode, "ISO88591")) - cd->write_handle = yaz_write_ISO8859_1; - else if (!yaz_matchstr (tocode, "UCS4")) - cd->write_handle = yaz_write_UCS4; - else if (!yaz_matchstr(tocode, "UCS4LE")) - cd->write_handle = yaz_write_UCS4LE; - #if HAVE_ICONV_H cd->iconv_cd = 0; if (!cd->read_handle || !cd->write_handle) @@ -373,7 +451,7 @@ size_t yaz_iconv (yaz_iconv_t cd, char **inbuf, size_t *inbytesleft, iconv(cd->iconv_cd, inbuf, inbytesleft, outbuf, outbytesleft); if (r == (size_t)(-1)) { - switch (errno) + switch (yaz_errno()) { case E2BIG: cd->my_errno = YAZ_ICONV_E2BIG;