X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=util%2Fsiconv.c;h=73d7148c06942fe3629c78419fd5f1875cfb5128;hp=c89de49d8140675b978e6ffe7fa2213e7d1c80b1;hb=4b3d1e197d75fcb2607be8d86d244f20c4180000;hpb=d054cdd41417401fbba915e20203882159f32283 diff --git a/util/siconv.c b/util/siconv.c index c89de49..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.6 2002-09-25 12:37:08 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)