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