X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fsiconv.c;h=663d03a470fc4e7d61c49493cff7eedb5d4e9e6f;hp=a770a6ca7f13b53713d54cbb0d0d2a04bf84f573;hb=2979c8fc3b5c53c06facad850dcae09645b43044;hpb=386fc8aa64d01486aa4fb3dac0dde1003a3b3d3f diff --git a/src/siconv.c b/src/siconv.c index a770a6c..663d03a 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.45 2007-09-24 12:51:10 adam Exp $ + * $Id: siconv.c,v 1.48 2007-10-15 20:45:05 adam Exp $ */ /** * \file siconv.c @@ -87,6 +87,8 @@ unsigned long yaz_marc8r_53_conv(unsigned char *inp, size_t inbytesleft, 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; int init_flag; @@ -111,11 +113,11 @@ struct yaz_iconv_struct { #endif unsigned long compose_char; - unsigned long write_marc8_comb_ch[8]; - 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_lpage; + const char *write_marc8_g0; + const char *write_marc8_g1; }; static struct { @@ -189,6 +191,10 @@ static struct { { 0, 0, 0} }; +static size_t yaz_write_marc8_page_chr(yaz_iconv_t cd, + char **outbuf, size_t *outbytesleft, + const char *page_chr); + static unsigned long yaz_read_ISO8859_1 (yaz_iconv_t cd, unsigned char *inp, size_t inbytesleft, size_t *no_read) { @@ -1443,8 +1449,6 @@ static unsigned long lookup_marc8(yaz_iconv_t cd, cd->my_errno = YAZ_ICONV_EILSEQ; return 0; } - else if (x == ' ') - return x; else { unsigned char *inp; @@ -1458,73 +1462,73 @@ static unsigned long lookup_marc8(yaz_iconv_t cd, x = yaz_marc8r_42_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(B"; + *page_chr = ESC "(B"; return x; } x = yaz_marc8r_45_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(B"; + *page_chr = ESC "(B"; return x; } x = yaz_marc8r_67_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033g"; + *page_chr = ESC "g"; return x; } x = yaz_marc8r_62_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033b"; + *page_chr = ESC "b"; return x; } x = yaz_marc8r_70_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033p"; + *page_chr = ESC "p"; return x; } x = yaz_marc8r_32_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(2"; + *page_chr = ESC "(2"; return x; } x = yaz_marc8r_4E_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(N"; + *page_chr = ESC "(N"; return x; } x = yaz_marc8r_51_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(Q"; + *page_chr = ESC "(Q"; return x; } 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_34_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(4"; + *page_chr = ESC "(4"; return x; } x = yaz_marc8r_53_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033(S"; + *page_chr = ESC "(S"; return x; } x = yaz_marc8r_31_conv(inp, inbytesleft, &no_read_sub, comb); if (x) { - *page_chr = "\033$1"; + *page_chr = ESC "$1"; return x; } cd->my_errno = YAZ_ICONV_EILSEQ; @@ -1537,12 +1541,21 @@ static size_t flush_combos(yaz_iconv_t cd, { unsigned long y = cd->write_marc8_last; unsigned char byte; - char out_buf[10]; - size_t i, out_no = 0; + char out_buf[4]; + size_t out_no = 0; if (!y) return 0; + assert(cd->write_marc8_lpage); + if (cd->write_marc8_lpage) + { + size_t r = yaz_write_marc8_page_chr(cd, outbuf, outbytesleft, + cd->write_marc8_lpage); + if (r) + return r; + } + byte = (unsigned char )((y>>16) & 0xff); if (byte) out_buf[out_no++] = byte; @@ -1553,19 +1566,12 @@ static size_t flush_combos(yaz_iconv_t cd, if (byte) out_buf[out_no++] = byte; - if (out_no + cd->write_marc8_comb_no + 1 > *outbytesleft) + if (out_no + 2 >= *outbytesleft) { cd->my_errno = YAZ_ICONV_E2BIG; return (size_t) (-1); } - for (i = 0; i < cd->write_marc8_comb_no; i++) - { - /* all MARC-8 combined characters are simple bytes */ - byte = (unsigned char )(cd->write_marc8_comb_ch[i]); - *(*outbuf)++ = byte; - (*outbytesleft)--; - } memcpy(*outbuf, out_buf, out_no); *outbuf += out_no; (*outbytesleft) -= out_no; @@ -1576,7 +1582,7 @@ static size_t flush_combos(yaz_iconv_t cd, } cd->write_marc8_last = 0; - cd->write_marc8_comb_no = 0; + cd->write_marc8_lpage = 0; cd->write_marc8_second_half_char = 0; return 0; } @@ -1585,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; @@ -1597,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; @@ -1636,13 +1650,25 @@ 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) cd->write_marc8_second_half_char = 0xFB; - if (cd->write_marc8_comb_no < 6) - cd->write_marc8_comb_ch[cd->write_marc8_comb_no++] = y; + if (*outbytesleft <= 1) + { + cd->my_errno = YAZ_ICONV_E2BIG; + return (size_t) (-1); + } + *(*outbuf)++ = y; + (*outbytesleft)--; } else { @@ -1650,13 +1676,8 @@ static size_t yaz_write_marc8_2(yaz_iconv_t cd, unsigned long x, 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; + cd->write_marc8_lpage = page_chr; } return 0; } @@ -1667,7 +1688,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, @@ -1683,6 +1705,7 @@ static size_t yaz_write_marc8(yaz_iconv_t cd, unsigned long x, char *outbuf0 = *outbuf; size_t outbytesleft0 = *outbytesleft; int last_ch = cd->write_marc8_last; + const char *lpage = cd->write_marc8_lpage; r = yaz_write_marc8_2(cd, latin1_comb[i].x1, outbuf, outbytesleft); @@ -1696,6 +1719,7 @@ static size_t yaz_write_marc8(yaz_iconv_t cd, unsigned long x, *outbuf = outbuf0; *outbytesleft = outbytesleft0; cd->write_marc8_last = last_ch; + cd->write_marc8_lpage = lpage; } return r; } @@ -1877,10 +1901,11 @@ size_t yaz_iconv(yaz_iconv_t cd, char **inbuf, size_t *inbytesleft, cd->comb_offset = cd->comb_size = 0; cd->compose_char = 0; - 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_lpage = 0; + cd->write_marc8_g0 = ESC "(B"; + cd->write_marc8_g1 = 0; cd->unget_x = 0; cd->no_read_x = 0;