6530f2db738f81b96a9bae88bab397d21378e6b9
[yaz-moved-to-github.git] / src / advancegreek.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_advancegreek(yaz_iconv_t cd, unsigned char *inp,
24                                     size_t inbytesleft, size_t *no_read)
25 {
26     unsigned long x = 0;
27     int shift = 0;
28     int tonos = 0;
29     int dialitika = 0;
30
31     *no_read = 0;
32     while (inbytesleft > 0)
33     {
34         if (*inp == 0x9d)
35         {
36             tonos = 1;
37         }
38         else if (*inp == 0x9e)
39         {
40             dialitika = 1;
41         }
42         else if (*inp == 0x9f)
43         {
44             shift = 1;
45         }
46         else
47             break;
48         inp++;
49         --inbytesleft;
50         (*no_read)++;
51     }    
52     if (inbytesleft == 0)
53     {
54         yaz_iconv_set_errno(cd, YAZ_ICONV_EINVAL); /* incomplete input */
55         *no_read = 0;
56         return 0;
57     }
58     switch (*inp) {
59     case 0x81:
60         if (shift) 
61             if (tonos) 
62                 x = 0x0386;
63             else 
64                 x = 0x0391;
65         else 
66             if (tonos) 
67                 x = 0x03ac;
68             else 
69                 x = 0x03b1;
70         break;
71     case 0x82:
72         if (shift) 
73             x = 0x0392;
74         else 
75             x = 0x03b2;
76         
77         break;
78     case 0x83:
79         if (shift) 
80             x = 0x0393;
81         else 
82             x = 0x03b3;
83         break;
84     case 0x84:
85         if (shift) 
86             x = 0x0394;
87         else 
88             x = 0x03b4;
89         break;
90     case 0x85:
91         if (shift) 
92             if (tonos) 
93                 x = 0x0388;
94             else 
95                 x = 0x0395;
96         else 
97             if (tonos) 
98                 x = 0x03ad;
99             else 
100                 x = 0x03b5;
101         break;
102     case 0x86:
103         if (shift) 
104             x = 0x0396;
105         else 
106             x = 0x03b6;
107         break;
108     case 0x87:
109         if (shift) 
110             if (tonos) 
111                 x = 0x0389;
112             else 
113                 x = 0x0397;
114         else 
115             if (tonos) 
116                 x = 0x03ae;
117             else 
118                 x = 0x03b7;
119         break;
120     case 0x88:
121         if (shift) 
122             x = 0x0398;
123         else 
124             x = 0x03b8;
125         break;
126     case 0x89:
127         if (shift) 
128             if (tonos) 
129                 x = 0x038a;
130             else 
131                 if (dialitika) 
132                     x = 0x03aa;
133                 else 
134                     x = 0x0399;
135         else 
136             if (tonos) 
137                 if (dialitika) 
138                     x = 0x0390;
139                 else 
140                     x = 0x03af;
141         
142             else 
143                 if (dialitika) 
144                     x = 0x03ca;
145                 else 
146                     x = 0x03b9;
147         break;
148     case 0x8a:
149         if (shift) 
150             x = 0x039a;
151         else 
152             x = 0x03ba;
153         
154         break;
155     case 0x8b:
156         if (shift) 
157             x = 0x039b;
158         else 
159             x = 0x03bb;
160         break;
161     case 0x8c:
162         if (shift) 
163             x = 0x039c;
164         else 
165             x = 0x03bc;
166         
167         break;
168     case 0x8d:
169         if (shift) 
170             x = 0x039d;
171         else 
172             x = 0x03bd;
173         break;
174     case 0x8e:
175         if (shift) 
176             x = 0x039e;
177         else 
178             x = 0x03be;
179         break;
180     case 0x8f:
181         if (shift) 
182             if (tonos) 
183                 x = 0x038c;
184             else 
185                 x = 0x039f;
186         else 
187             if (tonos) 
188                 x = 0x03cc;
189             else 
190                 x = 0x03bf;
191         break;
192     case 0x90:
193         if (shift) 
194             x = 0x03a0;
195         else 
196             x = 0x03c0;
197         break;
198     case 0x91:
199         if (shift) 
200             x = 0x03a1;
201         else 
202             x = 0x03c1;
203         break;
204     case 0x92:
205         x = 0x03c2;
206         break;
207     case 0x93:
208         if (shift) 
209             x = 0x03a3;
210         else 
211             x = 0x03c3;
212         break;
213     case 0x94:
214         if (shift) 
215             x = 0x03a4;
216         else 
217             x = 0x03c4;
218         break;
219     case 0x95:
220         if (shift) 
221             if (tonos) 
222                 x = 0x038e;
223             else 
224                 if (dialitika) 
225                     x = 0x03ab;
226                 else 
227                     x = 0x03a5;
228         else 
229             if (tonos) 
230                 if (dialitika) 
231                     x = 0x03b0;
232                 else 
233                     x = 0x03cd;
234         
235             else 
236                 if (dialitika) 
237                     x = 0x03cb;
238                 else 
239                     x = 0x03c5;
240         break;
241     case 0x96:
242         if (shift) 
243             x = 0x03a6;
244         else 
245             x = 0x03c6;
246         break;
247     case 0x97:
248         if (shift) 
249             x = 0x03a7;
250         else 
251             x = 0x03c7;
252         break;
253     case 0x98:
254         if (shift) 
255             x = 0x03a8;
256         else 
257             x = 0x03c8;
258         
259         break;
260         
261     case 0x99:
262         if (shift) 
263             if (tonos) 
264                 x = 0x038f;
265             else 
266                 x = 0x03a9;
267         else 
268             if (tonos) 
269                 x = 0x03ce;
270             else 
271                 x = 0x03c9;
272         break;
273     default:
274         x = *inp;
275         break;
276     }
277     (*no_read)++;
278     
279     return x;
280 }
281
282 size_t yaz_write_advancegreek(yaz_iconv_t cd, 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++]=0x96; 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++] = x;
370         break;
371     }
372     *outbytesleft -= k;
373     (*outbuf) += k;
374     return 0;
375 }
376
377 /*
378  * Local variables:
379  * c-basic-offset: 4
380  * indent-tabs-mode: nil
381  * End:
382  * vim: shiftwidth=4 tabstop=8 expandtab
383  */