088fc9356c1d734b060ec59198fe0babbb67ef36
[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.2 2002-08-27 14:14:01 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 8
19
20 static void convert (FILE *inf, yaz_iconv_t cd)
21 {
22     char inbuf0[CHUNK], *inbuf = inbuf0;
23     char outbuf0[CHUNK], *outbuf = outbuf0;
24     size_t outbytesleft = CHUNK;
25     size_t inbytesleft = CHUNK;
26
27     while (1)
28     {
29         size_t r = fread (inbuf, 1, inbytesleft, inf);
30         if (inbytesleft != r)
31         {
32             if (ferror(inf))
33             {
34                 fprintf (stderr, "yaziconv: error reading file\n");
35                 exit (6);
36             }
37             if (r == 0)
38             {
39                 if (outbuf != outbuf0)
40                     fwrite (outbuf0, 1, outbuf - outbuf0, stdout);
41                 break;
42             }
43         }
44         r = yaz_iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
45         if (r == (size_t)(-1))
46         {
47             if (yaz_iconv_error(cd) == YAZ_ICONV_EILSEQ)
48             {
49                 fprintf (stderr, "invalid sequence\n");
50                 return ;
51             }
52
53             if (yaz_iconv_error(cd) == EINVAL) /* incomplete input */
54             { 
55                 size_t i;
56                 for (i = 0; i<inbytesleft; i++)
57                     inbuf0[i] = inbuf[i];
58                 inbytesleft = CHUNK - inbytesleft;
59             }
60             if (yaz_iconv_error(cd) == E2BIG) /* no more output space */
61             {
62                 fwrite (outbuf0, 1, outbuf - outbuf0, stdout);
63                 outbuf = outbuf0;
64                 outbytesleft = CHUNK;
65             }
66             else
67             {
68                 fprintf (stderr, "yaziconv: unknown error\n");
69                 exit (7);
70             }
71         }
72         else
73         {
74             inbuf = inbuf0;
75             inbytesleft = CHUNK;
76         }
77     }
78 }
79
80 int main (int argc, char **argv)
81 {
82     int ret;
83     char *from = 0;
84     char *to = 0;
85     char *arg;
86     yaz_iconv_t cd;
87     FILE *inf = stdin;
88
89     while ((ret = options ("f:t:", argv, argc, &arg)) != -2)
90     {
91         switch (ret)
92         {
93         case 0:
94             inf = fopen (arg, "rb");
95             if (!inf)
96             {
97                 fprintf (stderr, "yaziconv: cannot open %s", arg);
98                 exit (2);
99             }
100             break;
101         case 'f':
102             from = arg;
103             break;
104         case 't':
105             to = arg;
106             break;
107         default:
108             fprintf (stderr, "yaziconv: Usage\n"
109                      "siconv -f encoding -t encoding [file]\n");
110             exit(1);
111         }
112     }
113     if (!to)
114     {
115         fprintf (stderr, "yaziconv: -t encoding missing\n");
116         exit (3);
117     }
118     if (!from)
119     {
120         fprintf (stderr, "yaziconv: -f encoding missing\n");
121         exit (4);
122     }
123     cd = yaz_iconv_open (to, from);
124     if (!cd)
125     {
126         fprintf (stderr, "yaziconv: unsupported encoding\n");
127         exit (5);
128     }
129
130     convert (inf, cd);
131     yaz_iconv_close (cd);
132 }