Support for scanning by CQL query (not yet debugged).
[yaz-moved-to-github.git] / test / tsticonv.c
1 /*
2  * Copyright (C) 1995-2005, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: tsticonv.c,v 1.12 2005-10-28 18:36:59 adam Exp $
6  */
7
8 #if HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdlib.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <ctype.h>
16
17 #include <yaz/yaz-util.h>
18
19 static int compare_buffers(char *msg, int no,
20                            int expect_len, const char *expect_buf,
21                            int got_len, const char *got_buf)
22 {
23     int i;
24     if (expect_len == got_len
25         && !memcmp(expect_buf, got_buf, expect_len))
26         return 1;
27     printf("tsticonv test=%s i=%d failed\n", msg, no);
28     printf("off got exp\n");
29     for (i = 0; i<got_len || i<expect_len; i++)
30     {
31         char got_char[10];
32         char expect_char[10];
33
34         if (i < got_len)
35             sprintf(got_char, "%02X", got_buf[i]);
36         else
37             sprintf(got_char, "?  ");
38
39         if (i < expect_len)
40             sprintf(expect_char, "%02X", expect_buf[i]);
41         else
42             sprintf(expect_char, "?  ");
43         
44         printf("%02d  %s  %s %c\n",
45                i, got_char, expect_char, got_buf[i] == expect_buf[i] ?
46                ' ' : '*');
47
48     }
49     exit(1);
50 }
51
52 /* some test strings in ISO-8859-1 format */
53 static const char *iso_8859_1_a[] = {
54     "ax" ,
55     "\xd8",
56     "eneb\346r",
57     "\xe5" "\xd8",
58     "\xe5" "\xd8" "b",
59     "\xe5" "\xe5",
60     0 };
61
62 /* same test strings in MARC-8 format */
63 static const char *marc8_a[] = {
64     "ax",   
65     "\xa2",          /* latin capital letter o with stroke */
66     "eneb\xb5r",     /* latin small letter ae */
67     "\xea" "a\xa2",
68     "\xea" "a\xa2" "b",
69     "\xea" "a"  "\xea" "a",
70     0
71 };
72
73 static void tst_marc8_to_iso_8859_1()
74 {
75     int i;
76     yaz_iconv_t cd;
77
78     cd = yaz_iconv_open("ISO-8859-1", "MARC8");
79     if (!cd)
80     {
81         printf("tsticonv 10 yaz_iconv_open failed\n");
82         exit(10);
83     }
84     for (i = 0; iso_8859_1_a[i]; i++)
85     {
86         size_t r;
87         char *inbuf= (char*) marc8_a[i];
88         size_t inbytesleft = strlen(inbuf);
89         char outbuf0[32];
90         char *outbuf = outbuf0;
91         size_t outbytesleft = sizeof(outbuf0);
92
93         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
94         if (r == (size_t) (-1))
95         {
96             int e = yaz_iconv_error(cd);
97
98             printf ("tsticonv 11 i=%d e=%d\n", i, e);
99             exit(11);
100         }
101         compare_buffers("tsticonv 11", i,
102                         strlen(iso_8859_1_a[i]), iso_8859_1_a[i],
103                         outbuf - outbuf0, outbuf0);
104     }
105     yaz_iconv_close(cd);
106 }
107
108 static void tst_marc8_to_ucs4b()
109 {
110     static struct {
111         const char *marc8_b;
112         int len;
113         const char *ucs4_b;
114     } ar[] = {
115     { 
116         "\033$1" "\x21\x2B\x3B" /* FF1F */ "\033(B" "o",
117         8, "\x00\x00\xFF\x1F" "\x00\x00\x00o"
118     }, {
119         "\033$1" "\x6F\x77\x29" /* AE0E */ "\x6F\x52\x7C" /* c0F4 */ "\033(B",
120         8, "\x00\x00\xAE\x0E" "\x00\x00\xC0\xF4",
121     }, {
122         "\033$1"
123         "\x21\x50\x6E"  /* UCS 7CFB */
124         "\x21\x51\x31"  /* UCS 7D71 */
125         "\x21\x3A\x67"  /* UCS 5B89 */
126         "\x21\x33\x22"  /* UCS 5168 */
127         "\x21\x33\x53"  /* UCS 5206 */
128         "\x21\x44\x2B"  /* UCS 6790 */
129         "\033(B",
130         24, "\x00\x00\x7C\xFB"
131         "\x00\x00\x7D\x71"
132         "\x00\x00\x5B\x89"
133         "\x00\x00\x51\x68"
134         "\x00\x00\x52\x06"
135         "\x00\x00\x67\x90"
136     }, {
137         "\xB0\xB2",     /* AYN and oSLASH */
138         8, "\x00\x00\x02\xBB"  "\x00\x00\x00\xF8"
139     }, {
140         "\xF6\x61",     /* a underscore */
141         8, "\x00\x00\x00\x61"  "\x00\x00\x03\x32"
142     }, {
143         "\x61\xC2",     /* a, phonorecord mark */
144         8, "\x00\x00\x00\x61"  "\x00\x00\x21\x17"
145     },
146     {  /* bug #258 */
147         "el" "\xe8" "am\xe8" "an", /* elaman where a is a" */
148         32,
149         "\x00\x00\x00" "e"
150         "\x00\x00\x00" "l"
151         "\x00\x00\x00" "a"
152         "\x00\x00\x03\x08"
153         "\x00\x00\x00" "m"
154         "\x00\x00\x00" "a"
155         "\x00\x00\x03\x08"
156         "\x00\x00\x00" "n"
157     }, 
158     { /* bug #260 */
159         "\xe5\xe8\x41",
160         12, "\x00\x00\x00\x41" "\x00\x00\x03\x04" "\x00\x00\x03\x08"
161     }, 
162     { /* bug #416 */
163         "\xEB\x74\xEC\x73",
164         12, "\x00\x00\x00\x74" "\x00\x00\x03\x61" "\x00\x00\x00\x73"
165     },
166     { /* bug #416 */
167         "\xFA\x74\xFB\x73",
168         12, "\x00\x00\x00\x74" "\x00\x00\x03\x60" "\x00\x00\x00\x73"
169     },
170     {
171         0, 0, 0
172     }
173     };
174     int i;
175     yaz_iconv_t cd;
176
177     cd = yaz_iconv_open("UCS4", "MARC8");
178     if (!cd)
179     {
180         printf ("tsticonv 20 yaz_iconv_open failed\n");
181         exit(20);
182     }
183     for (i = 0; ar[i].len; i++)
184     {
185         size_t r;
186         size_t expect_len = ar[i].len;
187         char *inbuf= (char*) ar[i].marc8_b;
188         size_t inbytesleft = strlen(inbuf);
189         char outbuf0[64];
190         char *outbuf = outbuf0;
191
192         while (inbytesleft)
193         {
194             size_t outbytesleft = outbuf0 + sizeof(outbuf0) - outbuf;
195             if (outbytesleft > 12)
196                 outbytesleft = 12;
197             r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
198             if (r == (size_t) (-1))
199             {
200                 int e = yaz_iconv_error(cd);
201                 if (e != YAZ_ICONV_E2BIG)
202                 {
203                     printf ("tsticonv 21 i=%d e=%d\n", i, e);
204                     exit(21);
205                 }
206             }
207             else
208                 break;
209         }
210         compare_buffers("tsticonv 22", i,
211                         expect_len, ar[i].ucs4_b,
212                         outbuf - outbuf0, outbuf0);
213     }
214     yaz_iconv_close(cd);
215 }
216
217 static void tst_ucs4b_to_utf8()
218 {
219     static const char *ucs4_c[] = {
220         "\x00\x00\xFF\x1F\x00\x00\x00o",
221         "\x00\x00\xAE\x0E\x00\x00\xC0\xF4",
222         0
223     };
224     static const char *utf8_c[] = {
225         "\xEF\xBC\x9F\x6F",
226         "\xEA\xB8\x8E\xEC\x83\xB4",
227         0
228     };
229     
230     int i;
231     yaz_iconv_t cd;
232
233     cd = yaz_iconv_open("UTF8", "UCS4");
234     if (!cd)
235     {
236         printf ("tsticonv 30 yaz_iconv_open failed\n");
237         exit(30);
238     }
239     for (i = 0; ucs4_c[i]; i++)
240     {
241         size_t r;
242         char *inbuf= (char*) ucs4_c[i];
243         size_t inbytesleft = 8;
244         char outbuf0[24];
245         char *outbuf = outbuf0;
246         size_t outbytesleft = sizeof(outbuf0);
247
248         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
249         if (r == (size_t) (-1))
250         {
251             int e = yaz_iconv_error(cd);
252
253             printf ("tsticonv 31 i=%d e=%d\n", i, e);
254             exit(31);
255         }
256         compare_buffers("tsticonv 32", i,
257                         strlen(utf8_c[i]), utf8_c[i],
258                         outbuf - outbuf0, outbuf0);
259     }
260     yaz_iconv_close(cd);
261 }
262
263 static void dconvert(int mandatory, const char *tmpcode)
264 {
265     int i;
266     yaz_iconv_t cd;
267     for (i = 0; iso_8859_1_a[i]; i++)
268     {
269         size_t r;
270         char *inbuf = (char*) iso_8859_1_a[i];
271         size_t inbytesleft = strlen(inbuf);
272         char outbuf0[24];
273         char outbuf1[10];
274         char *outbuf = outbuf0;
275         size_t outbytesleft = sizeof(outbuf0);
276
277         cd = yaz_iconv_open(tmpcode, "ISO-8859-1");
278         if (!cd)
279         {
280             if (!mandatory)
281                 return;
282             printf ("tsticonv code=%s i=%d 1\n", tmpcode, i);
283             exit(1);
284         }
285         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
286         if (r == (size_t)(-1))
287         {
288             int e = yaz_iconv_error(cd);
289
290             printf ("tsticonv code=%s i=%d 2 e=%d\n", tmpcode, i, e);
291             exit(2);
292         }
293         yaz_iconv_close(cd);
294         
295         cd = yaz_iconv_open("ISO-8859-1", tmpcode);
296         if (!cd)
297         {
298             if (!mandatory)
299                 return;
300             printf ("tsticonv code=%s i=%d 3\n", tmpcode, i);
301             exit(3);
302         }
303         inbuf = outbuf0;
304         inbytesleft = sizeof(outbuf0) - outbytesleft;
305
306         outbuf = outbuf1;
307         outbytesleft = sizeof(outbuf1);
308         r = yaz_iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
309         if (r == (size_t)(-1)) {
310             int e = yaz_iconv_error(cd);
311
312             printf ("tsticonv code=%s i=%d 4 e=%d\n", tmpcode, i, e);
313             exit(4);
314         }
315         compare_buffers("dconvert", i,
316                         strlen(iso_8859_1_a[i]), iso_8859_1_a[i],
317                         sizeof(outbuf1) - outbytesleft, outbuf1);
318         yaz_iconv_close(cd);
319     }
320 }
321         
322 int main (int argc, char **argv)
323 {
324     dconvert(1, "UTF-8");
325     dconvert(1, "ISO-8859-1");
326     dconvert(1, "UCS4");
327     dconvert(1, "UCS4LE");
328     dconvert(0, "CP865");
329     tst_marc8_to_iso_8859_1();
330     tst_marc8_to_ucs4b();
331     tst_ucs4b_to_utf8();
332     exit(0);
333 }
334 /*
335  * Local variables:
336  * c-basic-offset: 4
337  * indent-tabs-mode: nil
338  * End:
339  * vim: shiftwidth=4 tabstop=8 expandtab
340  */
341