Ignore unknown XML attributes in MARCXML parsing.
[yaz-moved-to-github.git] / src / iso5428.c
1 /*
2  * Copyright (C) 1995-2008, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: siconv.c,v 1.50 2008-03-12 08:53:28 adam Exp $
6  */
7 /**
8  * \file
9  * \brief ISO-5428 character mapping (iconv)
10  */
11
12 #if HAVE_CONFIG_H
13 #include <config.h>
14 #endif
15
16 #include <assert.h>
17 #include <errno.h>
18 #include <string.h>
19 #include <ctype.h>
20
21 #include "iconv-p.h"
22
23 unsigned long yaz_read_iso5428_1984(yaz_iconv_t cd, unsigned char *inp,
24                                     size_t inbytesleft, size_t *no_read)
25 {
26     unsigned long x = 0;
27     int tonos = 0;
28     int dialitika = 0;
29
30     *no_read = 0;
31     while (inbytesleft > 0)
32     {
33         if (*inp == 0xa2)
34         {
35             tonos = 1;
36         }
37         else if (*inp == 0xa3)
38         {
39             dialitika = 1;
40         }
41         else
42             break;
43         inp++;
44         --inbytesleft;
45         (*no_read)++;
46     }    
47     if (inbytesleft == 0)
48     {
49         yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */
50         *no_read = 0;
51         return 0;
52     }
53     switch (*inp) {
54     case 0xe1: /*  alpha small */
55             if (tonos) 
56                 x = 0x03ac;
57             else 
58                 x = 0x03b1;
59             break;
60     case 0xc1: /*  alpha capital */
61             if (tonos) 
62                 x = 0x0386;
63             else 
64                 x = 0x0391;
65             break;
66
67     case 0xe2: /*  Beta small */
68             x = 0x03b2;
69             break;
70     case 0xc2: /*  Beta capital */
71             x = 0x0392;
72             break;
73
74     case 0xe4: /*  Gamma small */
75             x = 0x03b3;
76             break;
77     case 0xc4: /*  Gamma capital */
78             x = 0x0393;
79             break;
80
81     case 0xe5: /*  Delta small */
82             x = 0x03b4;
83             break;
84     case 0xc5: /*  Delta capital */
85             x = 0x0394;
86             break;
87     case 0xe6: /*  epsilon small */
88             if (tonos) 
89                 x = 0x03ad;
90             else 
91                 x = 0x03b5;
92             break;
93     case 0xc6: /*  epsilon capital */
94             if (tonos) 
95                 x = 0x0388;
96             else 
97                 x = 0x0395;
98             break;
99     case 0xe9: /*  Zeta small */
100             x = 0x03b6;
101             break;
102     case 0xc9: /*  Zeta capital */
103             x = 0x0396;
104             break;
105     case 0xea: /*  Eta small */
106             if (tonos) 
107                 x = 0x03ae;
108             else 
109                 x = 0x03b7;
110             break;
111     case 0xca: /*  Eta capital */
112             if (tonos) 
113                 x = 0x0389;
114             else 
115                 x = 0x0397;
116             break;
117     case 0xeb: /*  Theta small */
118             x = 0x03b8;
119             break;
120     case 0xcb: /*  Theta capital */
121             x = 0x0398;
122             break;
123     case 0xec: /*  Iota small */
124             if (tonos) 
125                 if (dialitika) 
126                     x = 0x0390;
127                 else 
128                     x = 0x03af;
129             else 
130                 if (dialitika) 
131                     x = 0x03ca;
132                 else 
133                     x = 0x03b9;
134             break;
135     case 0xcc: /*  Iota capital */
136             if (tonos) 
137                 x = 0x038a;
138             else 
139                 if (dialitika) 
140                     x = 0x03aa;
141                 else 
142                     x = 0x0399;
143             break;
144     case 0xed: /*  Kappa small */
145             x = 0x03ba;
146             break;
147     case 0xcd: /*  Kappa capital */
148             x = 0x039a;
149             break;
150     case 0xee: /*  Lambda small */
151             x = 0x03bb;
152             break;
153     case 0xce: /*  Lambda capital */
154             x = 0x039b;
155             break;
156     case 0xef: /*  Mu small */
157             x = 0x03bc;
158             break;
159     case 0xcf: /*  Mu capital */
160             x = 0x039c;
161             break;
162     case 0xf0: /*  Nu small */
163             x = 0x03bd;
164             break;
165     case 0xd0: /*  Nu capital */
166             x = 0x039d;
167             break;
168     case 0xf1: /*  Xi small */
169             x = 0x03be;
170             break;
171     case 0xd1: /*  Xi capital */
172             x = 0x039e;
173             break;
174     case 0xf2: /*  Omicron small */
175             if (tonos) 
176                 x = 0x03cc;
177             else 
178                 x = 0x03bf;
179             break;
180     case 0xd2: /*  Omicron capital */
181             if (tonos) 
182                 x = 0x038c;
183             else 
184                 x = 0x039f;
185             break;
186     case 0xf3: /*  Pi small */
187             x = 0x03c0;
188             break;
189     case 0xd3: /*  Pi capital */
190             x = 0x03a0;
191             break;
192     case 0xf5: /*  Rho small */
193             x = 0x03c1;
194             break;
195     case 0xd5: /*  Rho capital */
196             x = 0x03a1;
197             break;
198     case 0xf7: /*  Sigma small (end of words) */
199             x = 0x03c2;
200             break;
201     case 0xf6: /*  Sigma small */
202             x = 0x03c3;
203             break;
204     case 0xd6: /*  Sigma capital */
205             x = 0x03a3;
206             break;
207     case 0xf8: /*  Tau small */
208             x = 0x03c4;
209             break;
210     case 0xd8: /*  Tau capital */
211             x = 0x03a4;
212             break;
213     case 0xf9: /*  Upsilon small */
214             if (tonos) 
215                 if (dialitika) 
216                     x = 0x03b0;
217                 else 
218                     x = 0x03cd;
219             else 
220                 if (dialitika) 
221                     x = 0x03cb;
222                 else 
223                     x = 0x03c5;
224             break;
225     case 0xd9: /*  Upsilon capital */
226             if (tonos) 
227                 x = 0x038e;
228             else 
229                 if (dialitika) 
230                     x = 0x03ab;
231                 else 
232                     x = 0x03a5;
233             break;
234     case 0xfa: /*  Phi small */
235             x = 0x03c6;
236             break;
237     case 0xda: /*  Phi capital */
238             x = 0x03a6;
239             break;
240     case 0xfb: /*  Chi small */
241             x = 0x03c7;
242             break;
243     case 0xdb: /*  Chi capital */
244             x = 0x03a7;
245             break;
246     case 0xfc: /*  Psi small */
247             x = 0x03c8;
248             break;
249     case 0xdc: /*  Psi capital */
250             x = 0x03a8;
251             break;
252     case 0xfd: /*  Omega small */
253             if (tonos) 
254                 x = 0x03ce;
255             else 
256                 x = 0x03c9;
257             break;
258     case 0xdd: /*  Omega capital */
259             if (tonos) 
260                 x = 0x038f;
261             else 
262                 x = 0x03a9;
263             break;
264     default:
265         x = *inp;
266         break;
267     }
268     (*no_read)++;
269     
270     return x;
271 }
272
273 size_t yaz_write_iso5428_1984(yaz_iconv_t cd, unsigned long x,
274                               char **outbuf, size_t *outbytesleft)
275 {
276     size_t k = 0;
277     unsigned char *out = (unsigned char*) *outbuf;
278     if (*outbytesleft < 3)
279     {
280         yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG);  /* not room for output */
281         return (size_t)(-1);
282     }
283     switch (x)
284     {
285     case 0x03ac : out[k++]=0xa2; out[k++]=0xe1; break;
286     case 0x03b1 : out[k++]=0xe1; break;
287     case 0x0386 : out[k++]=0xa2; out[k++]=0xc1; break;
288     case 0x0391 : out[k++]=0xc1; break;
289     case 0x03b2 : out[k++]=0xe2; break;
290     case 0x0392 : out[k++]=0xc2; break;
291     case 0x03b3 : out[k++]=0xe4; break;
292     case 0x0393 : out[k++]=0xc4; break;
293     case 0x03b4 : out[k++]=0xe5; break;
294     case 0x0394 : out[k++]=0xc5; break;
295     case 0x03ad : out[k++]=0xa2; out[k++]=0xe6; break;
296     case 0x03b5 : out[k++]=0xe6; break;
297     case 0x0388 : out[k++]=0xa2; out[k++]=0xc6; break;
298     case 0x0395 : out[k++]=0xc6; break;
299     case 0x03b6 : out[k++]=0xe9; break;
300     case 0x0396 : out[k++]=0xc9; break;
301     case 0x03ae : out[k++]=0xa2; out[k++]=0xea; break;
302     case 0x03b7 : out[k++]=0xea; break;
303     case 0x0389 : out[k++]=0xa2; out[k++]=0xca; break;
304     case 0x0397 : out[k++]=0xca; break;
305     case 0x03b8 : out[k++]=0xeb; break;
306     case 0x0398 : out[k++]=0xcb; break;
307     case 0x0390 : out[k++]=0xa2; out[k++]=0xa3; out[k++]=0xec; break;
308     case 0x03af : out[k++]=0xa2; out[k++]=0xec; break;
309     case 0x03ca : out[k++]=0xa3; out[k++]=0xec; break;
310     case 0x03b9 : out[k++]=0xec; break;
311     case 0x038a : out[k++]=0xa2; out[k++]=0xcc; break;
312     case 0x03aa : out[k++]=0xa3; out[k++]=0xcc; break;
313     case 0x0399 : out[k++]=0xcc; break;
314     case 0x03ba : out[k++]=0xed; break;
315     case 0x039a : out[k++]=0xcd; break;
316     case 0x03bb : out[k++]=0xee; break;
317     case 0x039b : out[k++]=0xce; break;
318     case 0x03bc : out[k++]=0xef; break;
319     case 0x039c : out[k++]=0xcf; break;
320     case 0x03bd : out[k++]=0xf0; break;
321     case 0x039d : out[k++]=0xd0; break;
322     case 0x03be : out[k++]=0xf1; break;
323     case 0x039e : out[k++]=0xd1; break;
324     case 0x03cc : out[k++]=0xa2; out[k++]=0xf2; break;
325     case 0x03bf : out[k++]=0xf2; break;
326     case 0x038c : out[k++]=0xa2; out[k++]=0xd2; break;
327     case 0x039f : out[k++]=0xd2; break;
328     case 0x03c0 : out[k++]=0xf3; break;
329     case 0x03a0 : out[k++]=0xd3; break;
330     case 0x03c1 : out[k++]=0xf5; break;
331     case 0x03a1 : out[k++]=0xd5; break;
332     case 0x03c2 : out[k++]=0xf7; break;
333     case 0x03c3 : out[k++]=0xf6; break;
334     case 0x03a3 : out[k++]=0xd6; break;
335     case 0x03c4 : out[k++]=0xf8; break;
336     case 0x03a4 : out[k++]=0xd8; break;
337     case 0x03b0 : out[k++]=0xa2; out[k++]=0xa3; out[k++]=0xf9; break;
338     case 0x03cd : out[k++]=0xa2; out[k++]=0xf9; break;
339     case 0x03cb : out[k++]=0xa3; out[k++]=0xf9; break;
340     case 0x03c5 : out[k++]=0xf9; break;
341     case 0x038e : out[k++]=0xa2; out[k++]=0xd9; break;
342     case 0x03ab : out[k++]=0xa3; out[k++]=0xd9; break;
343     case 0x03a5 : out[k++]=0xd9; break;
344     case 0x03c6 : out[k++]=0xfa; break;
345     case 0x03a6 : out[k++]=0xda; break;
346     case 0x03c7 : out[k++]=0xfb; break;
347     case 0x03a7 : out[k++]=0xdb; break;
348     case 0x03c8 : out[k++]=0xfc; break;
349     case 0x03a8 : out[k++]=0xdc; break;
350     case 0x03ce : out[k++]=0xa2; out[k++]=0xfd; break;
351     case 0x03c9 : out[k++]=0xfd; break;
352     case 0x038f : out[k++]=0xa2; out[k++]=0xdd; break;
353     case 0x03a9 : out[k++]=0xdd; break;
354     default:
355         if (x > 255)
356         {
357             yaz_iconv_set_errno(cd, YAZ_ICONV_EILSEQ);
358             return (size_t) -1;
359         }
360         out[k++] = x;
361         break;
362     }
363     *outbytesleft -= k;
364     (*outbuf) += k;
365     return 0;
366 }
367
368
369 /*
370  * Local variables:
371  * c-basic-offset: 4
372  * indent-tabs-mode: nil
373  * End:
374  * vim: shiftwidth=4 tabstop=8 expandtab
375  */