From cccb7ecd623450d5b3ca2391327788c84aed71c8 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 18 Mar 2008 00:14:11 +0100 Subject: [PATCH] Factor iconv conversions to separate C files. --- src/Makefile.am | 2 +- src/advancegreek.c | 383 ++++++++++++++++++++ src/iconv-p.h | 57 +++ src/iso5428.c | 375 ++++++++++++++++++++ src/siconv.c | 987 +--------------------------------------------------- src/ucs4.c | 109 ++++++ src/unix.c | 2 +- src/utf8.c | 226 ++++++++++++ 8 files changed, 1167 insertions(+), 974 deletions(-) create mode 100644 src/advancegreek.c create mode 100644 src/iconv-p.h create mode 100644 src/iso5428.c create mode 100644 src/ucs4.c create mode 100644 src/utf8.c diff --git a/src/Makefile.am b/src/Makefile.am index 47d405f..15ae8f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -72,7 +72,7 @@ libyaz_la_SOURCES=version.c options.c log.c \ marcdisp.c marc_read_xml.c marc_read_iso2709.c marc_read_line.c \ wrbuf.c oid_db.c \ nmemsdup.c xmalloc.c readconf.c tpath.c nmem.c matchstr.c atoin.c \ - siconv.c \ + siconv.c utf8.c ucs4.c iso5428.c advancegreek.c \ odr_bool.c ber_bool.c ber_len.c ber_tag.c odr_util.c \ odr_null.c ber_null.c odr_int.c ber_int.c odr_tag.c odr_cons.c \ odr_seq.c odr_oct.c ber_oct.c odr_bit.c ber_bit.c odr_oid.c \ diff --git a/src/advancegreek.c b/src/advancegreek.c new file mode 100644 index 0000000..6530f2d --- /dev/null +++ b/src/advancegreek.c @@ -0,0 +1,383 @@ +/* + * Copyright (C) 1995-2008, Index Data ApS + * See the file LICENSE for details. + * + * $Id: siconv.c,v 1.50 2008-03-12 08:53:28 adam Exp $ + */ +/** + * \file + * \brief ISO-5428 character mapping (iconv) + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "iconv-p.h" + +unsigned long yaz_read_advancegreek(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + unsigned long x = 0; + int shift = 0; + int tonos = 0; + int dialitika = 0; + + *no_read = 0; + while (inbytesleft > 0) + { + if (*inp == 0x9d) + { + tonos = 1; + } + else if (*inp == 0x9e) + { + dialitika = 1; + } + else if (*inp == 0x9f) + { + shift = 1; + } + else + break; + inp++; + --inbytesleft; + (*no_read)++; + } + if (inbytesleft == 0) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */ + *no_read = 0; + return 0; + } + switch (*inp) { + case 0x81: + if (shift) + if (tonos) + x = 0x0386; + else + x = 0x0391; + else + if (tonos) + x = 0x03ac; + else + x = 0x03b1; + break; + case 0x82: + if (shift) + x = 0x0392; + else + x = 0x03b2; + + break; + case 0x83: + if (shift) + x = 0x0393; + else + x = 0x03b3; + break; + case 0x84: + if (shift) + x = 0x0394; + else + x = 0x03b4; + break; + case 0x85: + if (shift) + if (tonos) + x = 0x0388; + else + x = 0x0395; + else + if (tonos) + x = 0x03ad; + else + x = 0x03b5; + break; + case 0x86: + if (shift) + x = 0x0396; + else + x = 0x03b6; + break; + case 0x87: + if (shift) + if (tonos) + x = 0x0389; + else + x = 0x0397; + else + if (tonos) + x = 0x03ae; + else + x = 0x03b7; + break; + case 0x88: + if (shift) + x = 0x0398; + else + x = 0x03b8; + break; + case 0x89: + if (shift) + if (tonos) + x = 0x038a; + else + if (dialitika) + x = 0x03aa; + else + x = 0x0399; + else + if (tonos) + if (dialitika) + x = 0x0390; + else + x = 0x03af; + + else + if (dialitika) + x = 0x03ca; + else + x = 0x03b9; + break; + case 0x8a: + if (shift) + x = 0x039a; + else + x = 0x03ba; + + break; + case 0x8b: + if (shift) + x = 0x039b; + else + x = 0x03bb; + break; + case 0x8c: + if (shift) + x = 0x039c; + else + x = 0x03bc; + + break; + case 0x8d: + if (shift) + x = 0x039d; + else + x = 0x03bd; + break; + case 0x8e: + if (shift) + x = 0x039e; + else + x = 0x03be; + break; + case 0x8f: + if (shift) + if (tonos) + x = 0x038c; + else + x = 0x039f; + else + if (tonos) + x = 0x03cc; + else + x = 0x03bf; + break; + case 0x90: + if (shift) + x = 0x03a0; + else + x = 0x03c0; + break; + case 0x91: + if (shift) + x = 0x03a1; + else + x = 0x03c1; + break; + case 0x92: + x = 0x03c2; + break; + case 0x93: + if (shift) + x = 0x03a3; + else + x = 0x03c3; + break; + case 0x94: + if (shift) + x = 0x03a4; + else + x = 0x03c4; + break; + case 0x95: + if (shift) + if (tonos) + x = 0x038e; + else + if (dialitika) + x = 0x03ab; + else + x = 0x03a5; + else + if (tonos) + if (dialitika) + x = 0x03b0; + else + x = 0x03cd; + + else + if (dialitika) + x = 0x03cb; + else + x = 0x03c5; + break; + case 0x96: + if (shift) + x = 0x03a6; + else + x = 0x03c6; + break; + case 0x97: + if (shift) + x = 0x03a7; + else + x = 0x03c7; + break; + case 0x98: + if (shift) + x = 0x03a8; + else + x = 0x03c8; + + break; + + case 0x99: + if (shift) + if (tonos) + x = 0x038f; + else + x = 0x03a9; + else + if (tonos) + x = 0x03ce; + else + x = 0x03c9; + break; + default: + x = *inp; + break; + } + (*no_read)++; + + return x; +} + +size_t yaz_write_advancegreek(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft) +{ + size_t k = 0; + unsigned char *out = (unsigned char*) *outbuf; + if (*outbytesleft < 3) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG); /* not room for output */ + return (size_t)(-1); + } + switch (x) + { + case 0x03ac : out[k++]=0x9d; out[k++]=0x81; break; + case 0x03ad : out[k++]=0x9d; out[k++]=0x85; break; + case 0x03ae : out[k++]=0x9d; out[k++]=0x87; break; + case 0x03af : out[k++]=0x9d; out[k++]=0x89; break; + case 0x03cc : out[k++]=0x9d; out[k++]=0x8f; break; + case 0x03cd : out[k++]=0x9d; out[k++]=0x95; break; + case 0x03ce : out[k++]=0x9d; out[k++]=0x99; break; + case 0x0390 : out[k++]=0x9d; out[k++]=0x9e; out[k++]=0x89; break; + case 0x03b0 : out[k++]=0x9d; out[k++]=0x9e; out[k++]=0x95; break; + case 0x0386 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x81; break; + case 0x0388 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x85; break; + case 0x0389 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x87; break; + case 0x038a : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x89; break; + case 0x038c : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x8f; break; + case 0x038e : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x95; break; + case 0x038f : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x99; break; + case 0x03ca : out[k++]=0x9e; out[k++]=0x89; break; + case 0x03cb : out[k++]=0x9e; out[k++]=0x95; break; + case 0x03aa : out[k++]=0x9e; out[k++]=0x9f; out[k++]=0x89; break; + case 0x03ab : out[k++]=0x9e; out[k++]=0x9f; out[k++]=0x95; break; + case 0x0391 : out[k++]=0x9f; out[k++]=0x81; break; + case 0x0392 : out[k++]=0x9f; out[k++]=0x82; break; + case 0x0393 : out[k++]=0x9f; out[k++]=0x83; break; + case 0x0394 : out[k++]=0x9f; out[k++]=0x84; break; + case 0x0395 : out[k++]=0x9f; out[k++]=0x85; break; + case 0x0396 : out[k++]=0x9f; out[k++]=0x86; break; + case 0x0397 : out[k++]=0x9f; out[k++]=0x87; break; + case 0x0398 : out[k++]=0x9f; out[k++]=0x88; break; + case 0x0399 : out[k++]=0x9f; out[k++]=0x89; break; + case 0x039a : out[k++]=0x9f; out[k++]=0x8a; break; + case 0x039b : out[k++]=0x9f; out[k++]=0x8b; break; + case 0x039c : out[k++]=0x9f; out[k++]=0x8c; break; + case 0x039d : out[k++]=0x9f; out[k++]=0x8d; break; + case 0x039e : out[k++]=0x9f; out[k++]=0x8e; break; + case 0x039f : out[k++]=0x9f; out[k++]=0x8f; break; + case 0x03a0 : out[k++]=0x9f; out[k++]=0x90; break; + case 0x03a1 : out[k++]=0x9f; out[k++]=0x91; break; + case 0x03a3 : out[k++]=0x9f; out[k++]=0x93; break; + case 0x03a4 : out[k++]=0x9f; out[k++]=0x94; break; + case 0x03a5 : out[k++]=0x9f; out[k++]=0x95; break; + case 0x03a6 : out[k++]=0x9f; out[k++]=0x96; break; + case 0x03a7 : out[k++]=0x9f; out[k++]=0x97; break; + case 0x03a8 : out[k++]=0x9f; out[k++]=0x98; break; + case 0x03a9 : out[k++]=0x9f; out[k++]=0x99; break; + case 0x03b1 : out[k++]=0x81; break; + case 0x03b2 : out[k++]=0x82; break; + case 0x03b3 : out[k++]=0x83; break; + case 0x03b4 : out[k++]=0x84; break; + case 0x03b5 : out[k++]=0x85; break; + case 0x03b6 : out[k++]=0x86; break; + case 0x03b7 : out[k++]=0x87; break; + case 0x03b8 : out[k++]=0x88; break; + case 0x03b9 : out[k++]=0x89; break; + case 0x03ba : out[k++]=0x8a; break; + case 0x03bb : out[k++]=0x8b; break; + case 0x03bc : out[k++]=0x8c; break; + case 0x03bd : out[k++]=0x8d; break; + case 0x03be : out[k++]=0x8e; break; + case 0x03bf : out[k++]=0x8f; break; + case 0x03c0 : out[k++]=0x90; break; + case 0x03c1 : out[k++]=0x91; break; + case 0x03c2 : out[k++]=0x92; break; + case 0x03c3 : out[k++]=0x93; break; + case 0x03c4 : out[k++]=0x94; break; + case 0x03c5 : out[k++]=0x95; break; + case 0x03c6 : out[k++]=0x96; break; + case 0x03c7 : out[k++]=0x96; break; + case 0x03c8 : out[k++]=0x98; break; + case 0x03c9 : out[k++]=0x99; break; + default: + if (x > 255) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_EILSEQ); + return (size_t) -1; + } + out[k++] = x; + break; + } + *outbytesleft -= k; + (*outbuf) += k; + return 0; +} + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/src/iconv-p.h b/src/iconv-p.h new file mode 100644 index 0000000..04a51b0 --- /dev/null +++ b/src/iconv-p.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2005-2008, Index Data ApS + * See the file LICENSE for details. + * + * $Id: zoom-p.h,v 1.25 2007-09-11 08:40:28 adam Exp $ + */ +/** + * \file + * \brief Internal header for conv + */ + +#ifndef ICONV_P_H +#define ICONV_P_H + +#include + +#include + +void yaz_iconv_set_errno(yaz_iconv_t cd, int no); + +unsigned long yaz_read_iso5428_1984(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read); + +size_t yaz_write_iso5428_1984(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft); + +size_t yaz_init_UTF8(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read); +unsigned long yaz_read_UTF8(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read); + + +size_t yaz_write_UTF8(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft); + +unsigned long yaz_read_UCS4(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read); +unsigned long yaz_read_UCS4LE(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read); +size_t yaz_write_UCS4(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft); +size_t yaz_write_UCS4LE(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft); +unsigned long yaz_read_advancegreek(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read); +size_t yaz_write_advancegreek(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft); + +#endif +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/iso5428.c b/src/iso5428.c new file mode 100644 index 0000000..a78b00d --- /dev/null +++ b/src/iso5428.c @@ -0,0 +1,375 @@ +/* + * Copyright (C) 1995-2008, Index Data ApS + * See the file LICENSE for details. + * + * $Id: siconv.c,v 1.50 2008-03-12 08:53:28 adam Exp $ + */ +/** + * \file + * \brief ISO-5428 character mapping (iconv) + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "iconv-p.h" + +unsigned long yaz_read_iso5428_1984(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + unsigned long x = 0; + int tonos = 0; + int dialitika = 0; + + *no_read = 0; + while (inbytesleft > 0) + { + if (*inp == 0xa2) + { + tonos = 1; + } + else if (*inp == 0xa3) + { + dialitika = 1; + } + else + break; + inp++; + --inbytesleft; + (*no_read)++; + } + if (inbytesleft == 0) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */ + *no_read = 0; + return 0; + } + switch (*inp) { + case 0xe1: /* alpha small */ + if (tonos) + x = 0x03ac; + else + x = 0x03b1; + break; + case 0xc1: /* alpha capital */ + if (tonos) + x = 0x0386; + else + x = 0x0391; + break; + + case 0xe2: /* Beta small */ + x = 0x03b2; + break; + case 0xc2: /* Beta capital */ + x = 0x0392; + break; + + case 0xe4: /* Gamma small */ + x = 0x03b3; + break; + case 0xc4: /* Gamma capital */ + x = 0x0393; + break; + + case 0xe5: /* Delta small */ + x = 0x03b4; + break; + case 0xc5: /* Delta capital */ + x = 0x0394; + break; + case 0xe6: /* epsilon small */ + if (tonos) + x = 0x03ad; + else + x = 0x03b5; + break; + case 0xc6: /* epsilon capital */ + if (tonos) + x = 0x0388; + else + x = 0x0395; + break; + case 0xe9: /* Zeta small */ + x = 0x03b6; + break; + case 0xc9: /* Zeta capital */ + x = 0x0396; + break; + case 0xea: /* Eta small */ + if (tonos) + x = 0x03ae; + else + x = 0x03b7; + break; + case 0xca: /* Eta capital */ + if (tonos) + x = 0x0389; + else + x = 0x0397; + break; + case 0xeb: /* Theta small */ + x = 0x03b8; + break; + case 0xcb: /* Theta capital */ + x = 0x0398; + break; + case 0xec: /* Iota small */ + if (tonos) + if (dialitika) + x = 0x0390; + else + x = 0x03af; + else + if (dialitika) + x = 0x03ca; + else + x = 0x03b9; + break; + case 0xcc: /* Iota capital */ + if (tonos) + x = 0x038a; + else + if (dialitika) + x = 0x03aa; + else + x = 0x0399; + break; + case 0xed: /* Kappa small */ + x = 0x03ba; + break; + case 0xcd: /* Kappa capital */ + x = 0x039a; + break; + case 0xee: /* Lambda small */ + x = 0x03bb; + break; + case 0xce: /* Lambda capital */ + x = 0x039b; + break; + case 0xef: /* Mu small */ + x = 0x03bc; + break; + case 0xcf: /* Mu capital */ + x = 0x039c; + break; + case 0xf0: /* Nu small */ + x = 0x03bd; + break; + case 0xd0: /* Nu capital */ + x = 0x039d; + break; + case 0xf1: /* Xi small */ + x = 0x03be; + break; + case 0xd1: /* Xi capital */ + x = 0x039e; + break; + case 0xf2: /* Omicron small */ + if (tonos) + x = 0x03cc; + else + x = 0x03bf; + break; + case 0xd2: /* Omicron capital */ + if (tonos) + x = 0x038c; + else + x = 0x039f; + break; + case 0xf3: /* Pi small */ + x = 0x03c0; + break; + case 0xd3: /* Pi capital */ + x = 0x03a0; + break; + case 0xf5: /* Rho small */ + x = 0x03c1; + break; + case 0xd5: /* Rho capital */ + x = 0x03a1; + break; + case 0xf7: /* Sigma small (end of words) */ + x = 0x03c2; + break; + case 0xf6: /* Sigma small */ + x = 0x03c3; + break; + case 0xd6: /* Sigma capital */ + x = 0x03a3; + break; + case 0xf8: /* Tau small */ + x = 0x03c4; + break; + case 0xd8: /* Tau capital */ + x = 0x03a4; + break; + case 0xf9: /* Upsilon small */ + if (tonos) + if (dialitika) + x = 0x03b0; + else + x = 0x03cd; + else + if (dialitika) + x = 0x03cb; + else + x = 0x03c5; + break; + case 0xd9: /* Upsilon capital */ + if (tonos) + x = 0x038e; + else + if (dialitika) + x = 0x03ab; + else + x = 0x03a5; + break; + case 0xfa: /* Phi small */ + x = 0x03c6; + break; + case 0xda: /* Phi capital */ + x = 0x03a6; + break; + case 0xfb: /* Chi small */ + x = 0x03c7; + break; + case 0xdb: /* Chi capital */ + x = 0x03a7; + break; + case 0xfc: /* Psi small */ + x = 0x03c8; + break; + case 0xdc: /* Psi capital */ + x = 0x03a8; + break; + case 0xfd: /* Omega small */ + if (tonos) + x = 0x03ce; + else + x = 0x03c9; + break; + case 0xdd: /* Omega capital */ + if (tonos) + x = 0x038f; + else + x = 0x03a9; + break; + default: + x = *inp; + break; + } + (*no_read)++; + + return x; +} + +size_t yaz_write_iso5428_1984(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft) +{ + size_t k = 0; + unsigned char *out = (unsigned char*) *outbuf; + if (*outbytesleft < 3) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG); /* not room for output */ + return (size_t)(-1); + } + switch (x) + { + case 0x03ac : out[k++]=0xa2; out[k++]=0xe1; break; + case 0x03b1 : out[k++]=0xe1; break; + case 0x0386 : out[k++]=0xa2; out[k++]=0xc1; break; + case 0x0391 : out[k++]=0xc1; break; + case 0x03b2 : out[k++]=0xe2; break; + case 0x0392 : out[k++]=0xc2; break; + case 0x03b3 : out[k++]=0xe4; break; + case 0x0393 : out[k++]=0xc4; break; + case 0x03b4 : out[k++]=0xe5; break; + case 0x0394 : out[k++]=0xc5; break; + case 0x03ad : out[k++]=0xa2; out[k++]=0xe6; break; + case 0x03b5 : out[k++]=0xe6; break; + case 0x0388 : out[k++]=0xa2; out[k++]=0xc6; break; + case 0x0395 : out[k++]=0xc6; break; + case 0x03b6 : out[k++]=0xe9; break; + case 0x0396 : out[k++]=0xc9; break; + case 0x03ae : out[k++]=0xa2; out[k++]=0xea; break; + case 0x03b7 : out[k++]=0xea; break; + case 0x0389 : out[k++]=0xa2; out[k++]=0xca; break; + case 0x0397 : out[k++]=0xca; break; + case 0x03b8 : out[k++]=0xeb; break; + case 0x0398 : out[k++]=0xcb; break; + case 0x0390 : out[k++]=0xa2; out[k++]=0xa3; out[k++]=0xec; break; + case 0x03af : out[k++]=0xa2; out[k++]=0xec; break; + case 0x03ca : out[k++]=0xa3; out[k++]=0xec; break; + case 0x03b9 : out[k++]=0xec; break; + case 0x038a : out[k++]=0xa2; out[k++]=0xcc; break; + case 0x03aa : out[k++]=0xa3; out[k++]=0xcc; break; + case 0x0399 : out[k++]=0xcc; break; + case 0x03ba : out[k++]=0xed; break; + case 0x039a : out[k++]=0xcd; break; + case 0x03bb : out[k++]=0xee; break; + case 0x039b : out[k++]=0xce; break; + case 0x03bc : out[k++]=0xef; break; + case 0x039c : out[k++]=0xcf; break; + case 0x03bd : out[k++]=0xf0; break; + case 0x039d : out[k++]=0xd0; break; + case 0x03be : out[k++]=0xf1; break; + case 0x039e : out[k++]=0xd1; break; + case 0x03cc : out[k++]=0xa2; out[k++]=0xf2; break; + case 0x03bf : out[k++]=0xf2; break; + case 0x038c : out[k++]=0xa2; out[k++]=0xd2; break; + case 0x039f : out[k++]=0xd2; break; + case 0x03c0 : out[k++]=0xf3; break; + case 0x03a0 : out[k++]=0xd3; break; + case 0x03c1 : out[k++]=0xf5; break; + case 0x03a1 : out[k++]=0xd5; break; + case 0x03c2 : out[k++]=0xf7; break; + case 0x03c3 : out[k++]=0xf6; break; + case 0x03a3 : out[k++]=0xd6; break; + case 0x03c4 : out[k++]=0xf8; break; + case 0x03a4 : out[k++]=0xd8; break; + case 0x03b0 : out[k++]=0xa2; out[k++]=0xa3; out[k++]=0xf9; break; + case 0x03cd : out[k++]=0xa2; out[k++]=0xf9; break; + case 0x03cb : out[k++]=0xa3; out[k++]=0xf9; break; + case 0x03c5 : out[k++]=0xf9; break; + case 0x038e : out[k++]=0xa2; out[k++]=0xd9; break; + case 0x03ab : out[k++]=0xa3; out[k++]=0xd9; break; + case 0x03a5 : out[k++]=0xd9; break; + case 0x03c6 : out[k++]=0xfa; break; + case 0x03a6 : out[k++]=0xda; break; + case 0x03c7 : out[k++]=0xfb; break; + case 0x03a7 : out[k++]=0xdb; break; + case 0x03c8 : out[k++]=0xfc; break; + case 0x03a8 : out[k++]=0xdc; break; + case 0x03ce : out[k++]=0xa2; out[k++]=0xfd; break; + case 0x03c9 : out[k++]=0xfd; break; + case 0x038f : out[k++]=0xa2; out[k++]=0xdd; break; + case 0x03a9 : out[k++]=0xdd; break; + default: + if (x > 255) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_EILSEQ); + return (size_t) -1; + } + out[k++] = x; + break; + } + *outbytesleft -= k; + (*outbuf) += k; + return 0; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/src/siconv.c b/src/siconv.c index 1639759..8557bbd 100644 --- a/src/siconv.c +++ b/src/siconv.c @@ -33,8 +33,10 @@ #include #endif +#include +#include +#include "iconv-p.h" -#include unsigned long yaz_marc8_42_conv(unsigned char *inp, size_t inbytesleft, size_t *no_read, int *combining); @@ -87,8 +89,6 @@ 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; @@ -121,6 +121,7 @@ struct yaz_iconv_struct { const char *write_marc8_g1; }; + static struct { unsigned long x1, x2; unsigned y; @@ -192,12 +193,14 @@ static struct { { 0, 0, 0} }; +#define ESC "\033" + 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) +static unsigned long yaz_read_ISO8859_1(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) { unsigned long x = inp[0]; *no_read = 1; @@ -205,164 +208,6 @@ static unsigned long yaz_read_ISO8859_1 (yaz_iconv_t cd, unsigned char *inp, } -static size_t yaz_init_UTF8 (yaz_iconv_t cd, unsigned char *inp, - size_t inbytesleft, size_t *no_read) -{ - if (inp[0] != 0xef) - { - *no_read = 0; - return 0; - } - if (inbytesleft < 3) - { - cd->my_errno = YAZ_ICONV_EINVAL; - return (size_t) -1; - } - if (inp[1] != 0xbb && inp[2] == 0xbf) - *no_read = 3; - else - *no_read = 0; - return 0; -} - -unsigned long yaz_read_UTF8_char(unsigned char *inp, - size_t inbytesleft, size_t *no_read, - int *error) -{ - unsigned long x = 0; - - *no_read = 0; /* by default */ - if (inp[0] <= 0x7f) - { - x = inp[0]; - *no_read = 1; - } - else if (inp[0] <= 0xbf || inp[0] >= 0xfe) - { - *error = YAZ_ICONV_EILSEQ; - } - else if (inp[0] <= 0xdf && inbytesleft >= 2) - { - if ((inp[1] & 0xc0) == 0x80) - { - x = ((inp[0] & 0x1f) << 6) | (inp[1] & 0x3f); - if (x >= 0x80) - *no_read = 2; - else - *error = YAZ_ICONV_EILSEQ; - } - else - *error = YAZ_ICONV_EILSEQ; - } - else if (inp[0] <= 0xef && inbytesleft >= 3) - { - if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80) - { - x = ((inp[0] & 0x0f) << 12) | ((inp[1] & 0x3f) << 6) | - (inp[2] & 0x3f); - if (x >= 0x800) - *no_read = 3; - else - *error = YAZ_ICONV_EILSEQ; - } - else - *error = YAZ_ICONV_EILSEQ; - } - else if (inp[0] <= 0xf7 && inbytesleft >= 4) - { - if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80 - && (inp[3] & 0xc0) == 0x80) - { - x = ((inp[0] & 0x07) << 18) | ((inp[1] & 0x3f) << 12) | - ((inp[2] & 0x3f) << 6) | (inp[3] & 0x3f); - if (x >= 0x10000) - *no_read = 4; - else - *error = YAZ_ICONV_EILSEQ; - } - else - *error = YAZ_ICONV_EILSEQ; - } - else if (inp[0] <= 0xfb && inbytesleft >= 5) - { - if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80 - && (inp[3] & 0xc0) == 0x80 && (inp[4] & 0xc0) == 0x80) - { - x = ((inp[0] & 0x03) << 24) | ((inp[1] & 0x3f) << 18) | - ((inp[2] & 0x3f) << 12) | ((inp[3] & 0x3f) << 6) | - (inp[4] & 0x3f); - if (x >= 0x200000) - *no_read = 5; - else - *error = YAZ_ICONV_EILSEQ; - } - else - *error = YAZ_ICONV_EILSEQ; - } - else if (inp[0] <= 0xfd && inbytesleft >= 6) - { - if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80 - && (inp[3] & 0xc0) == 0x80 && (inp[4] & 0xc0) == 0x80 - && (inp[5] & 0xc0) == 0x80) - { - x = ((inp[0] & 0x01) << 30) | ((inp[1] & 0x3f) << 24) | - ((inp[2] & 0x3f) << 18) | ((inp[3] & 0x3f) << 12) | - ((inp[4] & 0x3f) << 6) | (inp[5] & 0x3f); - if (x >= 0x4000000) - *no_read = 6; - else - *error = YAZ_ICONV_EILSEQ; - } - else - *error = YAZ_ICONV_EILSEQ; - } - else - *error = YAZ_ICONV_EINVAL; /* incomplete sentence */ - - return x; -} - -static unsigned long yaz_read_UTF8 (yaz_iconv_t cd, unsigned char *inp, - size_t inbytesleft, size_t *no_read) -{ - return yaz_read_UTF8_char(inp, inbytesleft, no_read, &cd->my_errno); -} - -static unsigned long yaz_read_UCS4 (yaz_iconv_t cd, unsigned char *inp, - size_t inbytesleft, size_t *no_read) -{ - unsigned long x = 0; - - if (inbytesleft < 4) - { - cd->my_errno = YAZ_ICONV_EINVAL; /* incomplete input */ - *no_read = 0; - } - else - { - x = (inp[0]<<24) | (inp[1]<<16) | (inp[2]<<8) | inp[3]; - *no_read = 4; - } - return x; -} - -static unsigned long yaz_read_UCS4LE (yaz_iconv_t cd, unsigned char *inp, - size_t inbytesleft, size_t *no_read) -{ - unsigned long x = 0; - - if (inbytesleft < 4) - { - cd->my_errno = YAZ_ICONV_EINVAL; /* incomplete input */ - *no_read = 0; - } - else - { - x = (inp[3]<<24) | (inp[2]<<16) | (inp[1]<<8) | inp[0]; - *no_read = 4; - } - return x; -} #if HAVE_WCHAR_H static unsigned long yaz_read_wchar_t (yaz_iconv_t cd, unsigned char *inp, @@ -386,705 +231,6 @@ static unsigned long yaz_read_wchar_t (yaz_iconv_t cd, unsigned char *inp, } #endif -static unsigned long yaz_read_iso5428_1984(yaz_iconv_t cd, unsigned char *inp, - size_t inbytesleft, size_t *no_read) -{ - unsigned long x = 0; - int tonos = 0; - int dialitika = 0; - - *no_read = 0; - while (inbytesleft > 0) - { - if (*inp == 0xa2) - { - tonos = 1; - } - else if (*inp == 0xa3) - { - dialitika = 1; - } - else - break; - inp++; - --inbytesleft; - (*no_read)++; - } - if (inbytesleft == 0) - { - cd->my_errno = YAZ_ICONV_EINVAL; /* incomplete input */ - *no_read = 0; - return 0; - } - switch (*inp) { - case 0xe1: /* alpha small */ - if (tonos) - x = 0x03ac; - else - x = 0x03b1; - break; - case 0xc1: /* alpha capital */ - if (tonos) - x = 0x0386; - else - x = 0x0391; - break; - - case 0xe2: /* Beta small */ - x = 0x03b2; - break; - case 0xc2: /* Beta capital */ - x = 0x0392; - break; - - case 0xe4: /* Gamma small */ - x = 0x03b3; - break; - case 0xc4: /* Gamma capital */ - x = 0x0393; - break; - - case 0xe5: /* Delta small */ - x = 0x03b4; - break; - case 0xc5: /* Delta capital */ - x = 0x0394; - break; - case 0xe6: /* epsilon small */ - if (tonos) - x = 0x03ad; - else - x = 0x03b5; - break; - case 0xc6: /* epsilon capital */ - if (tonos) - x = 0x0388; - else - x = 0x0395; - break; - case 0xe9: /* Zeta small */ - x = 0x03b6; - break; - case 0xc9: /* Zeta capital */ - x = 0x0396; - break; - case 0xea: /* Eta small */ - if (tonos) - x = 0x03ae; - else - x = 0x03b7; - break; - case 0xca: /* Eta capital */ - if (tonos) - x = 0x0389; - else - x = 0x0397; - break; - case 0xeb: /* Theta small */ - x = 0x03b8; - break; - case 0xcb: /* Theta capital */ - x = 0x0398; - break; - case 0xec: /* Iota small */ - if (tonos) - if (dialitika) - x = 0x0390; - else - x = 0x03af; - else - if (dialitika) - x = 0x03ca; - else - x = 0x03b9; - break; - case 0xcc: /* Iota capital */ - if (tonos) - x = 0x038a; - else - if (dialitika) - x = 0x03aa; - else - x = 0x0399; - break; - case 0xed: /* Kappa small */ - x = 0x03ba; - break; - case 0xcd: /* Kappa capital */ - x = 0x039a; - break; - case 0xee: /* Lambda small */ - x = 0x03bb; - break; - case 0xce: /* Lambda capital */ - x = 0x039b; - break; - case 0xef: /* Mu small */ - x = 0x03bc; - break; - case 0xcf: /* Mu capital */ - x = 0x039c; - break; - case 0xf0: /* Nu small */ - x = 0x03bd; - break; - case 0xd0: /* Nu capital */ - x = 0x039d; - break; - case 0xf1: /* Xi small */ - x = 0x03be; - break; - case 0xd1: /* Xi capital */ - x = 0x039e; - break; - case 0xf2: /* Omicron small */ - if (tonos) - x = 0x03cc; - else - x = 0x03bf; - break; - case 0xd2: /* Omicron capital */ - if (tonos) - x = 0x038c; - else - x = 0x039f; - break; - case 0xf3: /* Pi small */ - x = 0x03c0; - break; - case 0xd3: /* Pi capital */ - x = 0x03a0; - break; - case 0xf5: /* Rho small */ - x = 0x03c1; - break; - case 0xd5: /* Rho capital */ - x = 0x03a1; - break; - case 0xf7: /* Sigma small (end of words) */ - x = 0x03c2; - break; - case 0xf6: /* Sigma small */ - x = 0x03c3; - break; - case 0xd6: /* Sigma capital */ - x = 0x03a3; - break; - case 0xf8: /* Tau small */ - x = 0x03c4; - break; - case 0xd8: /* Tau capital */ - x = 0x03a4; - break; - case 0xf9: /* Upsilon small */ - if (tonos) - if (dialitika) - x = 0x03b0; - else - x = 0x03cd; - else - if (dialitika) - x = 0x03cb; - else - x = 0x03c5; - break; - case 0xd9: /* Upsilon capital */ - if (tonos) - x = 0x038e; - else - if (dialitika) - x = 0x03ab; - else - x = 0x03a5; - break; - case 0xfa: /* Phi small */ - x = 0x03c6; - break; - case 0xda: /* Phi capital */ - x = 0x03a6; - break; - case 0xfb: /* Chi small */ - x = 0x03c7; - break; - case 0xdb: /* Chi capital */ - x = 0x03a7; - break; - case 0xfc: /* Psi small */ - x = 0x03c8; - break; - case 0xdc: /* Psi capital */ - x = 0x03a8; - break; - case 0xfd: /* Omega small */ - if (tonos) - x = 0x03ce; - else - x = 0x03c9; - break; - case 0xdd: /* Omega capital */ - if (tonos) - x = 0x038f; - else - x = 0x03a9; - break; - default: - x = *inp; - break; - } - (*no_read)++; - - return x; -} - -static size_t yaz_write_iso5428_1984(yaz_iconv_t cd, unsigned long x, - char **outbuf, size_t *outbytesleft) -{ - size_t k = 0; - unsigned char *out = (unsigned char*) *outbuf; - if (*outbytesleft < 3) - { - cd->my_errno = YAZ_ICONV_E2BIG; /* not room for output */ - return (size_t)(-1); - } - switch (x) - { - case 0x03ac : out[k++]=0xa2; out[k++]=0xe1; break; - case 0x03b1 : out[k++]=0xe1; break; - case 0x0386 : out[k++]=0xa2; out[k++]=0xc1; break; - case 0x0391 : out[k++]=0xc1; break; - case 0x03b2 : out[k++]=0xe2; break; - case 0x0392 : out[k++]=0xc2; break; - case 0x03b3 : out[k++]=0xe4; break; - case 0x0393 : out[k++]=0xc4; break; - case 0x03b4 : out[k++]=0xe5; break; - case 0x0394 : out[k++]=0xc5; break; - case 0x03ad : out[k++]=0xa2; out[k++]=0xe6; break; - case 0x03b5 : out[k++]=0xe6; break; - case 0x0388 : out[k++]=0xa2; out[k++]=0xc6; break; - case 0x0395 : out[k++]=0xc6; break; - case 0x03b6 : out[k++]=0xe9; break; - case 0x0396 : out[k++]=0xc9; break; - case 0x03ae : out[k++]=0xa2; out[k++]=0xea; break; - case 0x03b7 : out[k++]=0xea; break; - case 0x0389 : out[k++]=0xa2; out[k++]=0xca; break; - case 0x0397 : out[k++]=0xca; break; - case 0x03b8 : out[k++]=0xeb; break; - case 0x0398 : out[k++]=0xcb; break; - case 0x0390 : out[k++]=0xa2; out[k++]=0xa3; out[k++]=0xec; break; - case 0x03af : out[k++]=0xa2; out[k++]=0xec; break; - case 0x03ca : out[k++]=0xa3; out[k++]=0xec; break; - case 0x03b9 : out[k++]=0xec; break; - case 0x038a : out[k++]=0xa2; out[k++]=0xcc; break; - case 0x03aa : out[k++]=0xa3; out[k++]=0xcc; break; - case 0x0399 : out[k++]=0xcc; break; - case 0x03ba : out[k++]=0xed; break; - case 0x039a : out[k++]=0xcd; break; - case 0x03bb : out[k++]=0xee; break; - case 0x039b : out[k++]=0xce; break; - case 0x03bc : out[k++]=0xef; break; - case 0x039c : out[k++]=0xcf; break; - case 0x03bd : out[k++]=0xf0; break; - case 0x039d : out[k++]=0xd0; break; - case 0x03be : out[k++]=0xf1; break; - case 0x039e : out[k++]=0xd1; break; - case 0x03cc : out[k++]=0xa2; out[k++]=0xf2; break; - case 0x03bf : out[k++]=0xf2; break; - case 0x038c : out[k++]=0xa2; out[k++]=0xd2; break; - case 0x039f : out[k++]=0xd2; break; - case 0x03c0 : out[k++]=0xf3; break; - case 0x03a0 : out[k++]=0xd3; break; - case 0x03c1 : out[k++]=0xf5; break; - case 0x03a1 : out[k++]=0xd5; break; - case 0x03c2 : out[k++]=0xf7; break; - case 0x03c3 : out[k++]=0xf6; break; - case 0x03a3 : out[k++]=0xd6; break; - case 0x03c4 : out[k++]=0xf8; break; - case 0x03a4 : out[k++]=0xd8; break; - case 0x03b0 : out[k++]=0xa2; out[k++]=0xa3; out[k++]=0xf9; break; - case 0x03cd : out[k++]=0xa2; out[k++]=0xf9; break; - case 0x03cb : out[k++]=0xa3; out[k++]=0xf9; break; - case 0x03c5 : out[k++]=0xf9; break; - case 0x038e : out[k++]=0xa2; out[k++]=0xd9; break; - case 0x03ab : out[k++]=0xa3; out[k++]=0xd9; break; - case 0x03a5 : out[k++]=0xd9; break; - case 0x03c6 : out[k++]=0xfa; break; - case 0x03a6 : out[k++]=0xda; break; - case 0x03c7 : out[k++]=0xfb; break; - case 0x03a7 : out[k++]=0xdb; break; - case 0x03c8 : out[k++]=0xfc; break; - case 0x03a8 : out[k++]=0xdc; break; - case 0x03ce : out[k++]=0xa2; out[k++]=0xfd; break; - case 0x03c9 : out[k++]=0xfd; break; - case 0x038f : out[k++]=0xa2; out[k++]=0xdd; break; - case 0x03a9 : out[k++]=0xdd; break; - default: - if (x > 255) - { - cd->my_errno = YAZ_ICONV_EILSEQ; - return (size_t) -1; - } - out[k++] = x; - break; - } - *outbytesleft -= k; - (*outbuf) += k; - return 0; -} - -static unsigned long yaz_read_advancegreek(yaz_iconv_t cd, unsigned char *inp, - size_t inbytesleft, size_t *no_read) -{ - unsigned long x = 0; - int shift = 0; - int tonos = 0; - int dialitika = 0; - - *no_read = 0; - while (inbytesleft > 0) - { - if (*inp == 0x9d) - { - tonos = 1; - } - else if (*inp == 0x9e) - { - dialitika = 1; - } - else if (*inp == 0x9f) - { - shift = 1; - } - else - break; - inp++; - --inbytesleft; - (*no_read)++; - } - if (inbytesleft == 0) - { - cd->my_errno = YAZ_ICONV_EINVAL; /* incomplete input */ - *no_read = 0; - return 0; - } - switch (*inp) { - case 0x81: - if (shift) - if (tonos) - x = 0x0386; - else - x = 0x0391; - else - if (tonos) - x = 0x03ac; - else - x = 0x03b1; - break; - case 0x82: - if (shift) - x = 0x0392; - else - x = 0x03b2; - - break; - case 0x83: - if (shift) - x = 0x0393; - else - x = 0x03b3; - break; - case 0x84: - if (shift) - x = 0x0394; - else - x = 0x03b4; - break; - case 0x85: - if (shift) - if (tonos) - x = 0x0388; - else - x = 0x0395; - else - if (tonos) - x = 0x03ad; - else - x = 0x03b5; - break; - case 0x86: - if (shift) - x = 0x0396; - else - x = 0x03b6; - break; - case 0x87: - if (shift) - if (tonos) - x = 0x0389; - else - x = 0x0397; - else - if (tonos) - x = 0x03ae; - else - x = 0x03b7; - break; - case 0x88: - if (shift) - x = 0x0398; - else - x = 0x03b8; - break; - case 0x89: - if (shift) - if (tonos) - x = 0x038a; - else - if (dialitika) - x = 0x03aa; - else - x = 0x0399; - else - if (tonos) - if (dialitika) - x = 0x0390; - else - x = 0x03af; - - else - if (dialitika) - x = 0x03ca; - else - x = 0x03b9; - break; - case 0x8a: - if (shift) - x = 0x039a; - else - x = 0x03ba; - - break; - case 0x8b: - if (shift) - x = 0x039b; - else - x = 0x03bb; - break; - case 0x8c: - if (shift) - x = 0x039c; - else - x = 0x03bc; - - break; - case 0x8d: - if (shift) - x = 0x039d; - else - x = 0x03bd; - break; - case 0x8e: - if (shift) - x = 0x039e; - else - x = 0x03be; - break; - case 0x8f: - if (shift) - if (tonos) - x = 0x038c; - else - x = 0x039f; - else - if (tonos) - x = 0x03cc; - else - x = 0x03bf; - break; - case 0x90: - if (shift) - x = 0x03a0; - else - x = 0x03c0; - break; - case 0x91: - if (shift) - x = 0x03a1; - else - x = 0x03c1; - break; - case 0x92: - x = 0x03c2; - break; - case 0x93: - if (shift) - x = 0x03a3; - else - x = 0x03c3; - break; - case 0x94: - if (shift) - x = 0x03a4; - else - x = 0x03c4; - break; - case 0x95: - if (shift) - if (tonos) - x = 0x038e; - else - if (dialitika) - x = 0x03ab; - else - x = 0x03a5; - else - if (tonos) - if (dialitika) - x = 0x03b0; - else - x = 0x03cd; - - else - if (dialitika) - x = 0x03cb; - else - x = 0x03c5; - break; - case 0x96: - if (shift) - x = 0x03a6; - else - x = 0x03c6; - break; - case 0x97: - if (shift) - x = 0x03a7; - else - x = 0x03c7; - break; - case 0x98: - if (shift) - x = 0x03a8; - else - x = 0x03c8; - - break; - - case 0x99: - if (shift) - if (tonos) - x = 0x038f; - else - x = 0x03a9; - else - if (tonos) - x = 0x03ce; - else - x = 0x03c9; - break; - default: - x = *inp; - break; - } - (*no_read)++; - - return x; -} - -static size_t yaz_write_advancegreek(yaz_iconv_t cd, unsigned long x, - char **outbuf, size_t *outbytesleft) -{ - size_t k = 0; - unsigned char *out = (unsigned char*) *outbuf; - if (*outbytesleft < 3) - { - cd->my_errno = YAZ_ICONV_E2BIG; /* not room for output */ - return (size_t)(-1); - } - switch (x) - { - case 0x03ac : out[k++]=0x9d; out[k++]=0x81; break; - case 0x03ad : out[k++]=0x9d; out[k++]=0x85; break; - case 0x03ae : out[k++]=0x9d; out[k++]=0x87; break; - case 0x03af : out[k++]=0x9d; out[k++]=0x89; break; - case 0x03cc : out[k++]=0x9d; out[k++]=0x8f; break; - case 0x03cd : out[k++]=0x9d; out[k++]=0x95; break; - case 0x03ce : out[k++]=0x9d; out[k++]=0x99; break; - case 0x0390 : out[k++]=0x9d; out[k++]=0x9e; out[k++]=0x89; break; - case 0x03b0 : out[k++]=0x9d; out[k++]=0x9e; out[k++]=0x95; break; - case 0x0386 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x81; break; - case 0x0388 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x85; break; - case 0x0389 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x87; break; - case 0x038a : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x89; break; - case 0x038c : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x8f; break; - case 0x038e : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x95; break; - case 0x038f : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x99; break; - case 0x03ca : out[k++]=0x9e; out[k++]=0x89; break; - case 0x03cb : out[k++]=0x9e; out[k++]=0x95; break; - case 0x03aa : out[k++]=0x9e; out[k++]=0x9f; out[k++]=0x89; break; - case 0x03ab : out[k++]=0x9e; out[k++]=0x9f; out[k++]=0x95; break; - case 0x0391 : out[k++]=0x9f; out[k++]=0x81; break; - case 0x0392 : out[k++]=0x9f; out[k++]=0x82; break; - case 0x0393 : out[k++]=0x9f; out[k++]=0x83; break; - case 0x0394 : out[k++]=0x9f; out[k++]=0x84; break; - case 0x0395 : out[k++]=0x9f; out[k++]=0x85; break; - case 0x0396 : out[k++]=0x9f; out[k++]=0x86; break; - case 0x0397 : out[k++]=0x9f; out[k++]=0x87; break; - case 0x0398 : out[k++]=0x9f; out[k++]=0x88; break; - case 0x0399 : out[k++]=0x9f; out[k++]=0x89; break; - case 0x039a : out[k++]=0x9f; out[k++]=0x8a; break; - case 0x039b : out[k++]=0x9f; out[k++]=0x8b; break; - case 0x039c : out[k++]=0x9f; out[k++]=0x8c; break; - case 0x039d : out[k++]=0x9f; out[k++]=0x8d; break; - case 0x039e : out[k++]=0x9f; out[k++]=0x8e; break; - case 0x039f : out[k++]=0x9f; out[k++]=0x8f; break; - case 0x03a0 : out[k++]=0x9f; out[k++]=0x90; break; - case 0x03a1 : out[k++]=0x9f; out[k++]=0x91; break; - case 0x03a3 : out[k++]=0x9f; out[k++]=0x93; break; - case 0x03a4 : out[k++]=0x9f; out[k++]=0x94; break; - case 0x03a5 : out[k++]=0x9f; out[k++]=0x95; break; - case 0x03a6 : out[k++]=0x9f; out[k++]=0x96; break; - case 0x03a7 : out[k++]=0x9f; out[k++]=0x97; break; - case 0x03a8 : out[k++]=0x9f; out[k++]=0x98; break; - case 0x03a9 : out[k++]=0x9f; out[k++]=0x99; break; - case 0x03b1 : out[k++]=0x81; break; - case 0x03b2 : out[k++]=0x82; break; - case 0x03b3 : out[k++]=0x83; break; - case 0x03b4 : out[k++]=0x84; break; - case 0x03b5 : out[k++]=0x85; break; - case 0x03b6 : out[k++]=0x86; break; - case 0x03b7 : out[k++]=0x87; break; - case 0x03b8 : out[k++]=0x88; break; - case 0x03b9 : out[k++]=0x89; break; - case 0x03ba : out[k++]=0x8a; break; - case 0x03bb : out[k++]=0x8b; break; - case 0x03bc : out[k++]=0x8c; break; - case 0x03bd : out[k++]=0x8d; break; - case 0x03be : out[k++]=0x8e; break; - case 0x03bf : out[k++]=0x8f; break; - case 0x03c0 : out[k++]=0x90; break; - case 0x03c1 : out[k++]=0x91; break; - case 0x03c2 : out[k++]=0x92; break; - case 0x03c3 : out[k++]=0x93; break; - case 0x03c4 : out[k++]=0x94; break; - case 0x03c5 : out[k++]=0x95; break; - case 0x03c6 : out[k++]=0x96; break; - case 0x03c7 : out[k++]=0x96; break; - case 0x03c8 : out[k++]=0x98; break; - case 0x03c9 : out[k++]=0x99; break; - default: - if (x > 255) - { - cd->my_errno = YAZ_ICONV_EILSEQ; - return (size_t) -1; - } - out[k++] = x; - break; - } - *outbytesleft -= k; - (*outbuf) += k; - return 0; -} - static unsigned long yaz_read_marc8_comb (yaz_iconv_t cd, unsigned char *inp, size_t inbytesleft, size_t *no_read, @@ -1278,74 +424,8 @@ incomplete: return 0; } -static size_t yaz_write_UTF8(yaz_iconv_t cd, unsigned long x, - char **outbuf, size_t *outbytesleft) -{ - return yaz_write_UTF8_char(x, outbuf, outbytesleft, &cd->my_errno); -} - -size_t yaz_write_UTF8_char(unsigned long x, - char **outbuf, size_t *outbytesleft, - int *error) -{ - unsigned char *outp = (unsigned char *) *outbuf; - - if (x <= 0x7f && *outbytesleft >= 1) - { - *outp++ = (unsigned char) x; - (*outbytesleft)--; - } - else if (x <= 0x7ff && *outbytesleft >= 2) - { - *outp++ = (unsigned char) ((x >> 6) | 0xc0); - *outp++ = (unsigned char) ((x & 0x3f) | 0x80); - (*outbytesleft) -= 2; - } - else if (x <= 0xffff && *outbytesleft >= 3) - { - *outp++ = (unsigned char) ((x >> 12) | 0xe0); - *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); - *outp++ = (unsigned char) ((x & 0x3f) | 0x80); - (*outbytesleft) -= 3; - } - else if (x <= 0x1fffff && *outbytesleft >= 4) - { - *outp++ = (unsigned char) ((x >> 18) | 0xf0); - *outp++ = (unsigned char) (((x >> 12) & 0x3f) | 0x80); - *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); - *outp++ = (unsigned char) ((x & 0x3f) | 0x80); - (*outbytesleft) -= 4; - } - else if (x <= 0x3ffffff && *outbytesleft >= 5) - { - *outp++ = (unsigned char) ((x >> 24) | 0xf8); - *outp++ = (unsigned char) (((x >> 18) & 0x3f) | 0x80); - *outp++ = (unsigned char) (((x >> 12) & 0x3f) | 0x80); - *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); - *outp++ = (unsigned char) ((x & 0x3f) | 0x80); - (*outbytesleft) -= 5; - } - else if (*outbytesleft >= 6) - { - *outp++ = (unsigned char) ((x >> 30) | 0xfc); - *outp++ = (unsigned char) (((x >> 24) & 0x3f) | 0x80); - *outp++ = (unsigned char) (((x >> 18) & 0x3f) | 0x80); - *outp++ = (unsigned char) (((x >> 12) & 0x3f) | 0x80); - *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); - *outp++ = (unsigned char) ((x & 0x3f) | 0x80); - (*outbytesleft) -= 6; - } - else - { - *error = YAZ_ICONV_E2BIG; /* not room for output */ - return (size_t)(-1); - } - *outbuf = (char *) outp; - return 0; -} - -static size_t yaz_write_ISO8859_1 (yaz_iconv_t cd, unsigned long x, - char **outbuf, size_t *outbytesleft) +static size_t yaz_write_ISO8859_1(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft) { /* list of two char unicode sequence that, when combined, are equivalent to single unicode chars that can be represented in @@ -1420,48 +500,6 @@ static size_t yaz_flush_ISO8859_1(yaz_iconv_t cd, return 0; } -static size_t yaz_write_UCS4 (yaz_iconv_t cd, unsigned long x, - char **outbuf, size_t *outbytesleft) -{ - unsigned char *outp = (unsigned char *) *outbuf; - if (*outbytesleft >= 4) - { - *outp++ = (unsigned char) (x>>24); - *outp++ = (unsigned char) (x>>16); - *outp++ = (unsigned char) (x>>8); - *outp++ = (unsigned char) x; - (*outbytesleft) -= 4; - } - else - { - cd->my_errno = YAZ_ICONV_E2BIG; - return (size_t)(-1); - } - *outbuf = (char *) outp; - return 0; -} - -static size_t yaz_write_UCS4LE (yaz_iconv_t cd, unsigned long x, - char **outbuf, size_t *outbytesleft) -{ - unsigned char *outp = (unsigned char *) *outbuf; - if (*outbytesleft >= 4) - { - *outp++ = (unsigned char) x; - *outp++ = (unsigned char) (x>>8); - *outp++ = (unsigned char) (x>>16); - *outp++ = (unsigned char) (x>>24); - (*outbytesleft) -= 4; - } - else - { - cd->my_errno = YAZ_ICONV_E2BIG; - return (size_t)(-1); - } - *outbuf = (char *) outp; - return 0; -} - static unsigned long lookup_marc8(yaz_iconv_t cd, unsigned long x, int *comb, const char **page_chr) @@ -2029,6 +1067,11 @@ int yaz_iconv_close (yaz_iconv_t cd) return 0; } +void yaz_iconv_set_errno(yaz_iconv_t cd, int no) +{ + cd->my_errno = no; +} + /* * Local variables: * c-basic-offset: 4 diff --git a/src/ucs4.c b/src/ucs4.c new file mode 100644 index 0000000..dedf4ec --- /dev/null +++ b/src/ucs4.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 1995-2008, Index Data ApS + * See the file LICENSE for details. + * + * $Id: siconv.c,v 1.50 2008-03-12 08:53:28 adam Exp $ + */ +/** + * \file + * \brief ISO-5428 character mapping (iconv) + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "iconv-p.h" + +unsigned long yaz_read_UCS4(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + unsigned long x = 0; + + if (inbytesleft < 4) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */ + *no_read = 0; + } + else + { + x = (inp[0]<<24) | (inp[1]<<16) | (inp[2]<<8) | inp[3]; + *no_read = 4; + } + return x; +} + +unsigned long yaz_read_UCS4LE(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + unsigned long x = 0; + + if (inbytesleft < 4) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */ + *no_read = 0; + } + else + { + x = (inp[3]<<24) | (inp[2]<<16) | (inp[1]<<8) | inp[0]; + *no_read = 4; + } + return x; +} + +size_t yaz_write_UCS4(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft) +{ + unsigned char *outp = (unsigned char *) *outbuf; + if (*outbytesleft >= 4) + { + *outp++ = (unsigned char) (x>>24); + *outp++ = (unsigned char) (x>>16); + *outp++ = (unsigned char) (x>>8); + *outp++ = (unsigned char) x; + (*outbytesleft) -= 4; + } + else + { + yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG); + return (size_t)(-1); + } + *outbuf = (char *) outp; + return 0; +} + +size_t yaz_write_UCS4LE(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft) +{ + unsigned char *outp = (unsigned char *) *outbuf; + if (*outbytesleft >= 4) + { + *outp++ = (unsigned char) x; + *outp++ = (unsigned char) (x>>8); + *outp++ = (unsigned char) (x>>16); + *outp++ = (unsigned char) (x>>24); + (*outbytesleft) -= 4; + } + else + { + yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG); + return (size_t)(-1); + } + *outbuf = (char *) outp; + return 0; +} + + + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ diff --git a/src/unix.c b/src/unix.c index 73bd7c5..41b3bc6 100644 --- a/src/unix.c +++ b/src/unix.c @@ -3,7 +3,7 @@ * See the file LICENSE for details. * * $Id: unix.c,v 1.20 2007-10-09 06:00:56 adam Exp $ - * UNIX socket COMSTACK. By Morten Bøgeskov. + * UNIX socket COMSTACK. By Morten Bogeskov. */ /** * \file unix.c diff --git a/src/utf8.c b/src/utf8.c new file mode 100644 index 0000000..b893e0d --- /dev/null +++ b/src/utf8.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 1995-2008, Index Data ApS + * See the file LICENSE for details. + * + * $Id: siconv.c,v 1.50 2008-03-12 08:53:28 adam Exp $ + */ +/** + * \file + * \brief ISO-5428 character mapping (iconv) + */ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "iconv-p.h" + +size_t yaz_init_UTF8(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + if (inp[0] != 0xef) + { + *no_read = 0; + return 0; + } + if (inbytesleft < 3) + { + yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); + return (size_t) -1; + } + if (inp[1] != 0xbb && inp[2] == 0xbf) + *no_read = 3; + else + *no_read = 0; + return 0; +} + +unsigned long yaz_read_UTF8_char(unsigned char *inp, + size_t inbytesleft, size_t *no_read, + int *error) +{ + unsigned long x = 0; + + *no_read = 0; /* by default */ + if (inp[0] <= 0x7f) + { + x = inp[0]; + *no_read = 1; + } + else if (inp[0] <= 0xbf || inp[0] >= 0xfe) + { + *error = YAZ_ICONV_EILSEQ; + } + else if (inp[0] <= 0xdf && inbytesleft >= 2) + { + if ((inp[1] & 0xc0) == 0x80) + { + x = ((inp[0] & 0x1f) << 6) | (inp[1] & 0x3f); + if (x >= 0x80) + *no_read = 2; + else + *error = YAZ_ICONV_EILSEQ; + } + else + *error = YAZ_ICONV_EILSEQ; + } + else if (inp[0] <= 0xef && inbytesleft >= 3) + { + if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80) + { + x = ((inp[0] & 0x0f) << 12) | ((inp[1] & 0x3f) << 6) | + (inp[2] & 0x3f); + if (x >= 0x800) + *no_read = 3; + else + *error = YAZ_ICONV_EILSEQ; + } + else + *error = YAZ_ICONV_EILSEQ; + } + else if (inp[0] <= 0xf7 && inbytesleft >= 4) + { + if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80 + && (inp[3] & 0xc0) == 0x80) + { + x = ((inp[0] & 0x07) << 18) | ((inp[1] & 0x3f) << 12) | + ((inp[2] & 0x3f) << 6) | (inp[3] & 0x3f); + if (x >= 0x10000) + *no_read = 4; + else + *error = YAZ_ICONV_EILSEQ; + } + else + *error = YAZ_ICONV_EILSEQ; + } + else if (inp[0] <= 0xfb && inbytesleft >= 5) + { + if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80 + && (inp[3] & 0xc0) == 0x80 && (inp[4] & 0xc0) == 0x80) + { + x = ((inp[0] & 0x03) << 24) | ((inp[1] & 0x3f) << 18) | + ((inp[2] & 0x3f) << 12) | ((inp[3] & 0x3f) << 6) | + (inp[4] & 0x3f); + if (x >= 0x200000) + *no_read = 5; + else + *error = YAZ_ICONV_EILSEQ; + } + else + *error = YAZ_ICONV_EILSEQ; + } + else if (inp[0] <= 0xfd && inbytesleft >= 6) + { + if ((inp[1] & 0xc0) == 0x80 && (inp[2] & 0xc0) == 0x80 + && (inp[3] & 0xc0) == 0x80 && (inp[4] & 0xc0) == 0x80 + && (inp[5] & 0xc0) == 0x80) + { + x = ((inp[0] & 0x01) << 30) | ((inp[1] & 0x3f) << 24) | + ((inp[2] & 0x3f) << 18) | ((inp[3] & 0x3f) << 12) | + ((inp[4] & 0x3f) << 6) | (inp[5] & 0x3f); + if (x >= 0x4000000) + *no_read = 6; + else + *error = YAZ_ICONV_EILSEQ; + } + else + *error = YAZ_ICONV_EILSEQ; + } + else + *error = YAZ_ICONV_EINVAL; /* incomplete sentence */ + + return x; +} + +unsigned long yaz_read_UTF8(yaz_iconv_t cd, unsigned char *inp, + size_t inbytesleft, size_t *no_read) +{ + int err = 0; + int r = yaz_read_UTF8_char(inp, inbytesleft, no_read, &err); + yaz_iconv_set_errno(cd, err); + return r; +} + + +size_t yaz_write_UTF8(yaz_iconv_t cd, unsigned long x, + char **outbuf, size_t *outbytesleft) +{ + int err = 0; + int r = yaz_write_UTF8_char(x, outbuf, outbytesleft, &err); + yaz_iconv_set_errno(cd, err); + return r; +} + +size_t yaz_write_UTF8_char(unsigned long x, + char **outbuf, size_t *outbytesleft, + int *error) +{ + unsigned char *outp = (unsigned char *) *outbuf; + + if (x <= 0x7f && *outbytesleft >= 1) + { + *outp++ = (unsigned char) x; + (*outbytesleft)--; + } + else if (x <= 0x7ff && *outbytesleft >= 2) + { + *outp++ = (unsigned char) ((x >> 6) | 0xc0); + *outp++ = (unsigned char) ((x & 0x3f) | 0x80); + (*outbytesleft) -= 2; + } + else if (x <= 0xffff && *outbytesleft >= 3) + { + *outp++ = (unsigned char) ((x >> 12) | 0xe0); + *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); + *outp++ = (unsigned char) ((x & 0x3f) | 0x80); + (*outbytesleft) -= 3; + } + else if (x <= 0x1fffff && *outbytesleft >= 4) + { + *outp++ = (unsigned char) ((x >> 18) | 0xf0); + *outp++ = (unsigned char) (((x >> 12) & 0x3f) | 0x80); + *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); + *outp++ = (unsigned char) ((x & 0x3f) | 0x80); + (*outbytesleft) -= 4; + } + else if (x <= 0x3ffffff && *outbytesleft >= 5) + { + *outp++ = (unsigned char) ((x >> 24) | 0xf8); + *outp++ = (unsigned char) (((x >> 18) & 0x3f) | 0x80); + *outp++ = (unsigned char) (((x >> 12) & 0x3f) | 0x80); + *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); + *outp++ = (unsigned char) ((x & 0x3f) | 0x80); + (*outbytesleft) -= 5; + } + else if (*outbytesleft >= 6) + { + *outp++ = (unsigned char) ((x >> 30) | 0xfc); + *outp++ = (unsigned char) (((x >> 24) & 0x3f) | 0x80); + *outp++ = (unsigned char) (((x >> 18) & 0x3f) | 0x80); + *outp++ = (unsigned char) (((x >> 12) & 0x3f) | 0x80); + *outp++ = (unsigned char) (((x >> 6) & 0x3f) | 0x80); + *outp++ = (unsigned char) ((x & 0x3f) | 0x80); + (*outbytesleft) -= 6; + } + else + { + *error = YAZ_ICONV_E2BIG; /* not room for output */ + return (size_t)(-1); + } + *outbuf = (char *) outp; + return 0; +} + + +/* + * Local variables: + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ -- 1.7.10.4