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