X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fsiconv.c;h=945b6cc2bb796e33996ec0dcfcb676d589a59443;hb=f66b53c033be535cc3fab8bcb2949fa2927b25d4;hp=1420e783f2ad04d8ce5115e72bf8995f8e8a1c1d;hpb=5d13a8684c8637334d17f2b0577fc511aa275477;p=yaz-moved-to-github.git diff --git a/src/siconv.c b/src/siconv.c index 1420e78..945b6cc 100644 --- a/src/siconv.c +++ b/src/siconv.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2007, Index Data ApS * See the file LICENSE for details. * - * $Id: siconv.c,v 1.41 2007-05-23 08:50:11 adam Exp $ + * $Id: siconv.c,v 1.47 2007-10-12 14:22:19 adam Exp $ */ /** * \file siconv.c @@ -36,44 +36,58 @@ #include -unsigned long yaz_marc8_1_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_42_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_2_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_45_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_3_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_67_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_4_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_62_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_5_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_70_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_6_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_32_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_7_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_4E_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_8_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_51_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8_9_conv(unsigned char *inp, size_t inbytesleft, +unsigned long yaz_marc8_33_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8_34_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8_53_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8_31_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); -unsigned long yaz_marc8r_1_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_2_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_3_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_4_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_5_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_6_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_7_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_8_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); -unsigned long yaz_marc8r_9_conv(unsigned char *inp, size_t inbytesleft, - size_t *no_read, int *combining); +unsigned long yaz_marc8r_42_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_45_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_67_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_62_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_70_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_32_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_4E_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_51_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_33_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_34_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_53_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); +unsigned long yaz_marc8r_31_conv(unsigned char *inp, size_t inbytesleft, + size_t *no_read, int *combining); + +#define ESC "\033" struct yaz_iconv_struct { int my_errno; @@ -103,7 +117,8 @@ struct yaz_iconv_struct { size_t write_marc8_comb_no; unsigned write_marc8_second_half_char; unsigned long write_marc8_last; - const char *write_marc8_page_chr; + const char *write_marc8_g0; + const char *write_marc8_g1; }; static struct { @@ -1170,6 +1185,11 @@ static unsigned long yaz_read_marc8_comb(yaz_iconv_t cd, unsigned char *inp, } if (inbytesleft <= 0) return 0; + else if (*inp == ' ') + { + *no_read += 1; + return ' '; + } else { unsigned long x; @@ -1179,35 +1199,44 @@ static unsigned long yaz_read_marc8_comb(yaz_iconv_t cd, unsigned char *inp, switch(cd->marc8_esc_mode) { case 'B': /* Basic ASCII */ - case 'E': /* ANSEL */ case 's': /* ASCII */ - x = yaz_marc8_1_conv(inp, inbytesleft, &no_read_sub, comb); + case 'E': /* ANSEL */ + x = yaz_marc8_42_conv(inp, inbytesleft, &no_read_sub, comb); + if (!x) + { + no_read_sub = 0; + x = yaz_marc8_45_conv(inp, inbytesleft, &no_read_sub, comb); + } break; case 'g': /* Greek */ - x = yaz_marc8_2_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_67_conv(inp, inbytesleft, &no_read_sub, comb); break; case 'b': /* Subscripts */ - x = yaz_marc8_3_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_62_conv(inp, inbytesleft, &no_read_sub, comb); break; case 'p': /* Superscripts */ - x = yaz_marc8_4_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_70_conv(inp, inbytesleft, &no_read_sub, comb); break; case '2': /* Basic Hebrew */ - x = yaz_marc8_5_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_32_conv(inp, inbytesleft, &no_read_sub, comb); break; case 'N': /* Basic Cyrillic */ + x = yaz_marc8_4E_conv(inp, inbytesleft, &no_read_sub, comb); + break; case 'Q': /* Extended Cyrillic */ - x = yaz_marc8_6_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_51_conv(inp, inbytesleft, &no_read_sub, comb); break; case '3': /* Basic Arabic */ + x = yaz_marc8_33_conv(inp, inbytesleft, &no_read_sub, comb); + break; case '4': /* Extended Arabic */ - x = yaz_marc8_7_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_34_conv(inp, inbytesleft, &no_read_sub, comb); break; case 'S': /* Greek */ - x = yaz_marc8_8_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_53_conv(inp, inbytesleft, &no_read_sub, comb); break; case '1': /* Chinese, Japanese, Korean (EACC) */ - x = yaz_marc8_9_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8_31_conv(inp, inbytesleft, &no_read_sub, comb); break; default: *no_read = 0; @@ -1426,59 +1455,82 @@ static unsigned long lookup_marc8(yaz_iconv_t cd, *utf8_outbuf = '\0'; inp = (unsigned char *) utf8_buf; inbytesleft = strlen(utf8_buf); - - x = yaz_marc8r_1_conv(inp, inbytesleft, &no_read_sub, comb); + + x = yaz_marc8r_42_conv(inp, inbytesleft, &no_read_sub, comb); + if (x) + { + *page_chr = ESC "(B"; + return x; + } + x = yaz_marc8r_45_conv(inp, inbytesleft, &no_read_sub, comb); + if (x) + { +#if 1 + *page_chr = ESC "(B"; +#else + /* this possibly solves bug #1778 */ + *page_chr = ESC ")!E"; +#endif + return x; + } + x = yaz_marc8r_67_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(B"; + *page_chr = ESC "g"; return x; } - x = yaz_marc8r_2_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_62_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033g"; + *page_chr = ESC "b"; return x; } - x = yaz_marc8r_3_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_70_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033b"; + *page_chr = ESC "p"; return x; } - x = yaz_marc8r_4_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_32_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033p"; + *page_chr = ESC "(2"; return x; } - x = yaz_marc8r_5_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_4E_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(2"; + *page_chr = ESC "(N"; return x; } - x = yaz_marc8r_6_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_51_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(N"; + *page_chr = ESC "(Q"; return x; } - x = yaz_marc8r_7_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_33_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(3"; + *page_chr = ESC "(3"; return x; } - x = yaz_marc8r_8_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_34_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(S"; + *page_chr = ESC "(4"; return x; } - x = yaz_marc8r_9_conv(inp, inbytesleft, &no_read_sub, comb); + x = yaz_marc8r_53_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033$1"; + *page_chr = ESC "(S"; + return x; + } + x = yaz_marc8r_31_conv(inp, inbytesleft, &no_read_sub, comb); + if (x) + { + *page_chr = ESC "$1"; return x; } cd->my_errno = YAZ_ICONV_EILSEQ; @@ -1539,8 +1591,13 @@ static size_t yaz_write_marc8_page_chr(yaz_iconv_t cd, char **outbuf, size_t *outbytesleft, const char *page_chr) { - const char *old_page_chr = cd->write_marc8_page_chr; - if (strcmp(page_chr, old_page_chr)) + const char **old_page_chr = &cd->write_marc8_g0; + + /* are we going to a G1-set (such as such as ESC ")!E") */ + if (page_chr && page_chr[1] == ')') + old_page_chr = &cd->write_marc8_g1; + + if (!*old_page_chr || strcmp(page_chr, *old_page_chr)) { size_t plen = 0; const char *page_out = page_chr; @@ -1551,24 +1608,27 @@ static size_t yaz_write_marc8_page_chr(yaz_iconv_t cd, return (size_t) (-1); } - cd->write_marc8_page_chr = page_chr; - - if (!strcmp(old_page_chr, "\033p") - || !strcmp(old_page_chr, "\033g") - || !strcmp(old_page_chr, "\033b")) + + if (*old_page_chr) { - /* Technique 1 leave */ - page_out = "\033s"; - if (strcmp(page_chr, "\033(B")) /* Not going ASCII page? */ + if (!strcmp(*old_page_chr, ESC "p") + || !strcmp(*old_page_chr, ESC "g") + || !strcmp(*old_page_chr, ESC "b")) { - /* Must leave script + enter new page */ - plen = strlen(page_out); - memcpy(*outbuf, page_out, plen); - (*outbuf) += plen; - (*outbytesleft) -= plen; - page_out = page_chr; + page_out = ESC "s"; + /* Technique 1 leave */ + if (strcmp(page_chr, ESC "(B")) /* Not going ASCII page? */ + { + /* Must leave script + enter new page */ + plen = strlen(page_out); + memcpy(*outbuf, page_out, plen); + (*outbuf) += plen; + (*outbytesleft) -= plen; + page_out = ESC "(B"; + } } } + *old_page_chr = page_chr; plen = strlen(page_out); memcpy(*outbuf, page_out, plen); (*outbuf) += plen; @@ -1590,6 +1650,12 @@ static size_t yaz_write_marc8_2(yaz_iconv_t cd, unsigned long x, if (comb) { + if (page_chr) + { + size_t r = yaz_write_marc8_page_chr(cd, outbuf, outbytesleft, page_chr); + if (r) + return r; + } if (x == 0x0361) cd->write_marc8_second_half_char = 0xEC; else if (x == 0x0360) @@ -1604,9 +1670,12 @@ static size_t yaz_write_marc8_2(yaz_iconv_t cd, unsigned long x, if (r) return r; - r = yaz_write_marc8_page_chr(cd, outbuf, outbytesleft, page_chr); - if (r) - return r; + if (page_chr) + { + r = yaz_write_marc8_page_chr(cd, outbuf, outbytesleft, page_chr); + if (r) + return r; + } cd->write_marc8_last = y; } return 0; @@ -1618,7 +1687,8 @@ static size_t yaz_flush_marc8(yaz_iconv_t cd, size_t r = flush_combos(cd, outbuf, outbytesleft); if (r) return r; - return yaz_write_marc8_page_chr(cd, outbuf, outbytesleft, "\033(B"); + cd->write_marc8_g1 = 0; + return yaz_write_marc8_page_chr(cd, outbuf, outbytesleft, ESC "(B"); } static size_t yaz_write_marc8(yaz_iconv_t cd, unsigned long x, @@ -1718,6 +1788,8 @@ yaz_iconv_t yaz_iconv_open (const char *tocode, const char *fromcode) cd->read_handle = yaz_read_advancegreek; else if (!yaz_matchstr(fromcode, "iso54281984")) cd->read_handle = yaz_read_iso5428_1984; + else if (!yaz_matchstr(fromcode, "iso5428:1984")) + cd->read_handle = yaz_read_iso5428_1984; #if HAVE_WCHAR_H else if (!yaz_matchstr(fromcode, "WCHAR_T")) cd->read_handle = yaz_read_wchar_t; @@ -1752,6 +1824,10 @@ yaz_iconv_t yaz_iconv_open (const char *tocode, const char *fromcode) { cd->write_handle = yaz_write_iso5428_1984; } + else if (!yaz_matchstr(tocode, "iso5428:1984")) + { + cd->write_handle = yaz_write_iso5428_1984; + } #if HAVE_WCHAR_H else if (!yaz_matchstr(tocode, "WCHAR_T")) cd->write_handle = yaz_write_wchar_t; @@ -1825,7 +1901,8 @@ size_t yaz_iconv(yaz_iconv_t cd, char **inbuf, size_t *inbytesleft, cd->write_marc8_comb_no = 0; cd->write_marc8_second_half_char = 0; cd->write_marc8_last = 0; - cd->write_marc8_page_chr = "\033(B"; + cd->write_marc8_g0 = ESC "(B"; + cd->write_marc8_g1 = 0; cd->unget_x = 0; cd->no_read_x = 0;