ZOOM: diagnostics for invalid ES usage, bug #3893.
[yaz-moved-to-github.git] / src / advancegreek.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2011 Index Data
3  * See the file LICENSE for details.
4  */
5 /**
6  * \file
7  * \brief Advance Greek encoding and decoding
8  */
9
10 #if HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <assert.h>
15 #include <errno.h>
16 #include <string.h>
17 #include <ctype.h>
18
19 #include "iconv-p.h"
20
21 static unsigned long read_advancegreek(yaz_iconv_t cd, yaz_iconv_decoder_t d,
22                                        unsigned char *inp,
23                                        size_t inbytesleft, size_t *no_read)
24 {
25     unsigned long x = 0;
26     int shift = 0;
27     int tonos = 0;
28     int dialitika = 0;
29
30     *no_read = 0;
31     while (inbytesleft > 0)
32     {
33         if (*inp == 0x9d)
34         {
35             tonos = 1;
36         }
37         else if (*inp == 0x9e)
38         {
39             dialitika = 1;
40         }
41         else if (*inp == 0x9f)
42         {
43             shift = 1;
44         }
45         else
46             break;
47         inp++;
48         --inbytesleft;
49         (*no_read)++;
50     }    
51     if (inbytesleft == 0)
52     {
53         yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */
54         *no_read = 0;
55         return 0;
56     }
57     switch (*inp) {
58     case 0x81:
59         if (shift) 
60             if (tonos) 
61                 x = 0x0386;
62             else 
63                 x = 0x0391;
64         else 
65             if (tonos) 
66                 x = 0x03ac;
67             else 
68                 x = 0x03b1;
69         break;
70     case 0x82:
71         if (shift) 
72             x = 0x0392;
73         else 
74             x = 0x03b2;
75         
76         break;
77     case 0x83:
78         if (shift) 
79             x = 0x0393;
80         else 
81             x = 0x03b3;
82         break;
83     case 0x84:
84         if (shift) 
85             x = 0x0394;
86         else 
87             x = 0x03b4;
88         break;
89     case 0x85:
90         if (shift) 
91             if (tonos) 
92                 x = 0x0388;
93             else 
94                 x = 0x0395;
95         else 
96             if (tonos) 
97                 x = 0x03ad;
98             else 
99                 x = 0x03b5;
100         break;
101     case 0x86:
102         if (shift) 
103             x = 0x0396;
104         else 
105             x = 0x03b6;
106         break;
107     case 0x87:
108         if (shift) 
109             if (tonos) 
110                 x = 0x0389;
111             else 
112                 x = 0x0397;
113         else 
114             if (tonos) 
115                 x = 0x03ae;
116             else 
117                 x = 0x03b7;
118         break;
119     case 0x88:
120         if (shift) 
121             x = 0x0398;
122         else 
123             x = 0x03b8;
124         break;
125     case 0x89:
126         if (shift) 
127             if (tonos) 
128                 x = 0x038a;
129             else 
130                 if (dialitika) 
131                     x = 0x03aa;
132                 else 
133                     x = 0x0399;
134         else 
135             if (tonos) 
136                 if (dialitika) 
137                     x = 0x0390;
138                 else 
139                     x = 0x03af;
140         
141             else 
142                 if (dialitika) 
143                     x = 0x03ca;
144                 else 
145                     x = 0x03b9;
146         break;
147     case 0x8a:
148         if (shift) 
149             x = 0x039a;
150         else 
151             x = 0x03ba;
152         
153         break;
154     case 0x8b:
155         if (shift) 
156             x = 0x039b;
157         else 
158             x = 0x03bb;
159         break;
160     case 0x8c:
161         if (shift) 
162             x = 0x039c;
163         else 
164             x = 0x03bc;
165         
166         break;
167     case 0x8d:
168         if (shift) 
169             x = 0x039d;
170         else 
171             x = 0x03bd;
172         break;
173     case 0x8e:
174         if (shift) 
175             x = 0x039e;
176         else 
177             x = 0x03be;
178         break;
179     case 0x8f:
180         if (shift) 
181             if (tonos) 
182                 x = 0x038c;
183             else 
184                 x = 0x039f;
185         else 
186             if (tonos) 
187                 x = 0x03cc;
188             else 
189                 x = 0x03bf;
190         break;
191     case 0x90:
192         if (shift) 
193             x = 0x03a0;
194         else 
195             x = 0x03c0;
196         break;
197     case 0x91:
198         if (shift) 
199             x = 0x03a1;
200         else 
201             x = 0x03c1;
202         break;
203     case 0x92:
204         x = 0x03c2;
205         break;
206     case 0x93:
207         if (shift) 
208             x = 0x03a3;
209         else 
210             x = 0x03c3;
211         break;
212     case 0x94:
213         if (shift) 
214             x = 0x03a4;
215         else 
216             x = 0x03c4;
217         break;
218     case 0x95:
219         if (shift) 
220             if (tonos) 
221                 x = 0x038e;
222             else 
223                 if (dialitika) 
224                     x = 0x03ab;
225                 else 
226                     x = 0x03a5;
227         else 
228             if (tonos) 
229                 if (dialitika) 
230                     x = 0x03b0;
231                 else 
232                     x = 0x03cd;
233         
234             else 
235                 if (dialitika) 
236                     x = 0x03cb;
237                 else 
238                     x = 0x03c5;
239         break;
240     case 0x96:
241         if (shift) 
242             x = 0x03a6;
243         else 
244             x = 0x03c6;
245         break;
246     case 0x97:
247         if (shift) 
248             x = 0x03a7;
249         else 
250             x = 0x03c7;
251         break;
252     case 0x98:
253         if (shift) 
254             x = 0x03a8;
255         else 
256             x = 0x03c8;
257         
258         break;
259         
260     case 0x99:
261         if (shift) 
262             if (tonos) 
263                 x = 0x038f;
264             else 
265                 x = 0x03a9;
266         else 
267             if (tonos) 
268                 x = 0x03ce;
269             else 
270                 x = 0x03c9;
271         break;
272     default:
273         x = *inp;
274         break;
275     }
276     (*no_read)++;
277     
278     return x;
279 }
280
281 static size_t write_advancegreek(yaz_iconv_t cd, yaz_iconv_encoder_t w,
282                                  unsigned long x,
283                                  char **outbuf, size_t *outbytesleft)
284 {
285     size_t k = 0;
286     unsigned char *out = (unsigned char*) *outbuf;
287     if (*outbytesleft < 3)
288     {
289         yaz_iconv_set_errno(cd, YAZ_ICONV_E2BIG);  /* not room for output */
290         return (size_t)(-1);
291     }
292     switch (x)
293     {
294     case 0x03ac : out[k++]=0x9d; out[k++]=0x81; break;
295     case 0x03ad : out[k++]=0x9d; out[k++]=0x85; break;
296     case 0x03ae : out[k++]=0x9d; out[k++]=0x87; break;
297     case 0x03af : out[k++]=0x9d; out[k++]=0x89; break;
298     case 0x03cc : out[k++]=0x9d; out[k++]=0x8f; break;
299     case 0x03cd : out[k++]=0x9d; out[k++]=0x95; break;
300     case 0x03ce : out[k++]=0x9d; out[k++]=0x99; break;
301     case 0x0390 : out[k++]=0x9d; out[k++]=0x9e; out[k++]=0x89; break;
302     case 0x03b0 : out[k++]=0x9d; out[k++]=0x9e; out[k++]=0x95; break;
303     case 0x0386 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x81; break;
304     case 0x0388 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x85; break;
305     case 0x0389 : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x87; break;
306     case 0x038a : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x89; break;
307     case 0x038c : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x8f; break;
308     case 0x038e : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x95; break;
309     case 0x038f : out[k++]=0x9d; out[k++]=0x9f; out[k++]=0x99; break;
310     case 0x03ca : out[k++]=0x9e; out[k++]=0x89; break;
311     case 0x03cb : out[k++]=0x9e; out[k++]=0x95; break;
312     case 0x03aa : out[k++]=0x9e; out[k++]=0x9f; out[k++]=0x89; break;
313     case 0x03ab : out[k++]=0x9e; out[k++]=0x9f; out[k++]=0x95; break;
314     case 0x0391 : out[k++]=0x9f; out[k++]=0x81; break;
315     case 0x0392 : out[k++]=0x9f; out[k++]=0x82; break;
316     case 0x0393 : out[k++]=0x9f; out[k++]=0x83; break;
317     case 0x0394 : out[k++]=0x9f; out[k++]=0x84; break;
318     case 0x0395 : out[k++]=0x9f; out[k++]=0x85; break;
319     case 0x0396 : out[k++]=0x9f; out[k++]=0x86; break;
320     case 0x0397 : out[k++]=0x9f; out[k++]=0x87; break;
321     case 0x0398 : out[k++]=0x9f; out[k++]=0x88; break;
322     case 0x0399 : out[k++]=0x9f; out[k++]=0x89; break;
323     case 0x039a : out[k++]=0x9f; out[k++]=0x8a; break;
324     case 0x039b : out[k++]=0x9f; out[k++]=0x8b; break;
325     case 0x039c : out[k++]=0x9f; out[k++]=0x8c; break;
326     case 0x039d : out[k++]=0x9f; out[k++]=0x8d; break;
327     case 0x039e : out[k++]=0x9f; out[k++]=0x8e; break;
328     case 0x039f : out[k++]=0x9f; out[k++]=0x8f; break;
329     case 0x03a0 : out[k++]=0x9f; out[k++]=0x90; break;
330     case 0x03a1 : out[k++]=0x9f; out[k++]=0x91; break;
331     case 0x03a3 : out[k++]=0x9f; out[k++]=0x93; break;
332     case 0x03a4 : out[k++]=0x9f; out[k++]=0x94; break;
333     case 0x03a5 : out[k++]=0x9f; out[k++]=0x95; break;
334     case 0x03a6 : out[k++]=0x9f; out[k++]=0x96; break;
335     case 0x03a7 : out[k++]=0x9f; out[k++]=0x97; break;
336     case 0x03a8 : out[k++]=0x9f; out[k++]=0x98; break;
337     case 0x03a9 : out[k++]=0x9f; out[k++]=0x99; break;
338     case 0x03b1 : out[k++]=0x81; break;
339     case 0x03b2 : out[k++]=0x82; break;
340     case 0x03b3 : out[k++]=0x83; break;
341     case 0x03b4 : out[k++]=0x84; break;
342     case 0x03b5 : out[k++]=0x85; break;
343     case 0x03b6 : out[k++]=0x86; break;
344     case 0x03b7 : out[k++]=0x87; break;
345     case 0x03b8 : out[k++]=0x88; break;
346     case 0x03b9 : out[k++]=0x89; break;
347     case 0x03ba : out[k++]=0x8a; break;
348     case 0x03bb : out[k++]=0x8b; break;
349     case 0x03bc : out[k++]=0x8c; break;
350     case 0x03bd : out[k++]=0x8d; break;
351     case 0x03be : out[k++]=0x8e; break;
352     case 0x03bf : out[k++]=0x8f; break;
353     case 0x03c0 : out[k++]=0x90; break;
354     case 0x03c1 : out[k++]=0x91; break;
355     case 0x03c2 : out[k++]=0x92; break;
356     case 0x03c3 : out[k++]=0x93; break;
357     case 0x03c4 : out[k++]=0x94; break;
358     case 0x03c5 : out[k++]=0x95; break;
359     case 0x03c6 : out[k++]=0x96; break;
360     case 0x03c7 : out[k++]=0x97; break;
361     case 0x03c8 : out[k++]=0x98; break;
362     case 0x03c9 : out[k++]=0x99; break;
363     default:
364         if (x > 255)
365         {
366             yaz_iconv_set_errno(cd, YAZ_ICONV_EILSEQ);
367             return (size_t) -1;
368         }
369         out[k++] = (unsigned char ) x;
370         break;
371     }
372     *outbytesleft -= k;
373     (*outbuf) += k;
374     return 0;
375 }
376
377 yaz_iconv_encoder_t yaz_advancegreek_encoder(const char *name,
378                                              yaz_iconv_encoder_t e)
379 {
380     if (!yaz_matchstr(name, "advancegreek"))
381     {
382         e->write_handle = write_advancegreek;
383         return e;
384     }
385     return 0;
386 }
387
388 yaz_iconv_decoder_t yaz_advancegreek_decoder(const char *name,
389                                              yaz_iconv_decoder_t d)
390 {
391     if (!yaz_matchstr(name, "advancegreek"))
392     {
393         d->read_handle = read_advancegreek;
394         return d;
395     }
396     return 0;
397 }
398
399 /*
400  * Local variables:
401  * c-basic-offset: 4
402  * c-file-style: "Stroustrup"
403  * indent-tabs-mode: nil
404  * End:
405  * vim: shiftwidth=4 tabstop=8 expandtab
406  */
407