072997be3a3dfc0b0b9426e09e06a5fb5850f113
[yaz-moved-to-github.git] / util / siconvtst.c
1 /*
2  * Copyright (c) 1997-2002, Index Data
3  * See the file LICENSE for details.
4  *
5  * $Id: siconvtst.c,v 1.6 2002-12-10 10:59:28 adam Exp $
6  */
7
8 #if HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <errno.h>
13 #include <string.h>
14 #include <ctype.h>
15
16 #include <yaz/yaz-util.h>
17
18 #define CHUNK_IN 64
19 #define CHUNK_OUT 64
20
21 void convert (FILE *inf, yaz_iconv_t cd)
22 {
23     char inbuf0[CHUNK_IN], *inbuf = inbuf0;
24     char outbuf0[CHUNK_OUT], *outbuf = outbuf0;
25     size_t inbytesleft = CHUNK_IN;
26     size_t outbytesleft = CHUNK_OUT;
27     int mustread = 1;
28
29     while (1)
30     {
31         size_t r;
32         if (mustread)
33         {
34             r = fread (inbuf, 1, inbytesleft, inf);
35             if (inbytesleft != r)
36             {
37                 if (ferror(inf))
38                 {
39                     fprintf (stderr, "yaziconv: error reading file\n");
40                     exit (6);
41                 }
42                 if (r == 0)
43                 {
44                     if (outbuf != outbuf0)
45                         fwrite (outbuf0, 1, outbuf - outbuf0, stdout);
46                     break;
47                 }
48                 inbytesleft = r;
49             }
50         }
51         r = yaz_iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
52         if (r == (size_t)(-1))
53         {
54             int e = yaz_iconv_error(cd);
55             if (e == YAZ_ICONV_EILSEQ)
56             {
57                 fprintf (stderr, "invalid sequence\n");
58                 return ;
59             }
60             else if (e == YAZ_ICONV_EINVAL) /* incomplete input */
61             { 
62                 size_t i;
63                 for (i = 0; i<inbytesleft; i++)
64                     inbuf0[i] = inbuf[i];
65
66                 r = fread(inbuf0 + i, 1, CHUNK_IN - i, inf);
67                 if (r != CHUNK_IN - i)
68                 {
69                     if (ferror(inf))
70                     {
71                         fprintf (stderr, "yaziconv: error reading file\n");
72                         exit(6);
73                     }
74                 }
75                 if (r == 0)
76                 {
77                     fprintf (stderr, "invalid sequence\n");
78                     return ;
79                 }
80                 inbytesleft += r;
81                 inbuf = inbuf0;
82                 mustread = 0;
83             }
84             else if (e == YAZ_ICONV_E2BIG) /* no more output space */
85             {
86                 fwrite (outbuf0, 1, outbuf - outbuf0, stdout);
87                 outbuf = outbuf0;
88                 outbytesleft = CHUNK_OUT;
89                 mustread = 0;
90             }
91             else
92             {
93                 fprintf (stderr, "yaziconv: unknown error\n");
94                 exit (7);
95             }
96         }
97         else
98         {
99             inbuf = inbuf0;
100             inbytesleft = CHUNK_IN;
101
102             fwrite (outbuf0, 1, outbuf - outbuf0, stdout);
103             outbuf = outbuf0;
104             outbytesleft = CHUNK_OUT;
105
106             mustread = 1;
107         }
108     }
109 }
110
111 int main (int argc, char **argv)
112 {
113     int ret;
114     int verbose = 0;
115     char *from = 0;
116     char *to = 0;
117     char *arg;
118     yaz_iconv_t cd;
119     FILE *inf = stdin;
120
121     while ((ret = options ("vf:t:", argv, argc, &arg)) != -2)
122     {
123         switch (ret)
124         {
125         case 0:
126             inf = fopen (arg, "rb");
127             if (!inf)
128             {
129                 fprintf (stderr, "yaziconv: cannot open %s", arg);
130                 exit (2);
131             }
132             break;
133         case 'f':
134             from = arg;
135             break;
136         case 't':
137             to = arg;
138             break;
139         case 'v':
140             verbose++;
141             break;
142         default:
143             fprintf (stderr, "yaziconv: Usage\n"
144                      "siconv -f encoding -t encoding [-v] [file]\n");
145             exit(1);
146         }
147     }
148     if (!to)
149     {
150         fprintf (stderr, "yaziconv: -t encoding missing\n");
151         exit (3);
152     }
153     if (!from)
154     {
155         fprintf (stderr, "yaziconv: -f encoding missing\n");
156         exit (4);
157     }
158     cd = yaz_iconv_open (to, from);
159     if (!cd)
160     {
161         fprintf (stderr, "yaziconv: unsupported encoding\n");
162         exit (5);
163     }
164     else
165     {
166         if (verbose)
167         {
168             fprintf (stderr, "yaziconv: using %s\n",
169                      yaz_iconv_isbuiltin(cd) ? "YAZ" : "iconv");
170         }
171     }
172     convert (inf, cd);
173     yaz_iconv_close (cd);
174     return 0;
175 }