Describe cql_strerror()
[yaz-moved-to-github.git] / odr / odr.c
1 /*
2  * Copyright (c) 1995-2003, Index Data
3  * See the file LICENSE for details.
4  *
5  * $Id: odr.c,v 1.44 2003-05-24 19:20:14 adam Exp $
6  *
7  */
8 #if HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdio.h>
13 #include <stdlib.h>
14
15 #include <yaz/xmalloc.h>
16 #include "odr-priv.h"
17
18 Odr_null *ODR_NULLVAL = (Odr_null *) "NULL";  /* the presence of a null value */
19
20 Odr_null *odr_nullval (void)
21 {
22     return ODR_NULLVAL;
23 }
24
25 char *odr_errlist[] =
26 {
27     "No (unknown) error",
28     "Memory allocation failed",
29     "System error",
30     "No space in buffer",
31     "Required data element missing",
32     "Unexpected tag",
33     "Other error",
34     "Protocol error",
35     "Malformed data",
36     "Stack overflow",
37     "Length of constructed type different from sum of members",
38     "Overflow writing definite length of constructed type",
39     "Bad HTTP Request"
40 };
41
42 char *odr_errmsg(int n)
43 {
44     return odr_errlist[n];
45 }
46
47 void odr_perror(ODR o, char *message)
48 {
49     const char *e = odr_getelement(o);
50
51     fprintf(stderr, "%s: %s", message, odr_errlist[o->error]);
52     if (e && *e)
53         fprintf (stderr, " element %s", e);
54     fprintf(stderr, "\n");
55 }
56
57 int odr_geterror(ODR o)
58 {
59     return o->error;
60 }
61
62 int odr_geterrorx(ODR o, int *x)
63 {
64     if (x)
65         *x = o->op->error_id;
66     return o->error;
67 }
68
69 char *odr_getelement(ODR o)
70 {
71     return o->op->element;
72 }
73
74 void odr_seterror(ODR o, int error, int id)
75 {
76     o->error = error;
77     o->op->error_id = id;
78     o->op->element[0] = '\0';
79 }
80
81 void odr_setelement(ODR o, const char *element)
82 {
83     if (element)
84     {
85         strncpy(o->op->element, element, sizeof(o->op->element)-1);
86         o->op->element[sizeof(o->op->element)-1] = '\0';
87     }
88 }
89
90 void odr_setprint(ODR o, FILE *file)
91 {
92     o->print = file;
93 }
94
95 int odr_set_charset(ODR o, const char *to, const char *from)
96 {
97     if (o->op->iconv_handle)
98         yaz_iconv_close (o->op->iconv_handle);
99     o->op->iconv_handle = 0;
100     if (to && from)
101     {
102         o->op->iconv_handle = yaz_iconv_open (to, from);
103         if (o->op->iconv_handle == 0)
104             return -1;
105     }
106     return 0;
107 }
108
109 #include <yaz/log.h>
110
111 ODR odr_createmem(int direction)
112 {
113     ODR r;
114
115     if (!(r = (ODR)xmalloc(sizeof(*r))))
116         return 0;
117     r->direction = direction;
118     r->print = stderr;
119     r->buf = 0;
120     r->size = r->pos = r->top = 0;
121     r->can_grow = 1;
122     r->mem = nmem_create();
123     r->enable_bias = 1;
124     r->op = (struct Odr_private *) xmalloc (sizeof(*r->op));
125     r->op->odr_ber_tag.lclass = -1;
126     r->op->iconv_handle = 0;
127     odr_reset(r);
128     yaz_log (LOG_DEBUG, "odr_createmem dir=%d o=%p", direction, r);
129     return r;
130 }
131
132 void odr_reset(ODR o)
133 {
134     odr_seterror(o, ONONE, 0);
135     o->bp = o->buf;
136     odr_seek(o, ODR_S_SET, 0);
137     o->top = 0;
138     o->t_class = -1;
139     o->t_tag = -1;
140     o->indent = 0;
141     o->op->stackp = -1;
142     nmem_reset(o->mem);
143     o->choice_bias = -1;
144     o->lenlen = 1;
145     if (o->op->iconv_handle != 0)
146         yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
147     yaz_log (LOG_DEBUG, "odr_reset o=%p", o);
148 }
149     
150 void odr_destroy(ODR o)
151 {
152     nmem_destroy(o->mem);
153     if (o->buf && o->can_grow)
154        xfree(o->buf);
155     if (o->print && o->print != stderr)
156         fclose(o->print);
157     if (o->op->iconv_handle != 0)
158         yaz_iconv_close (o->op->iconv_handle);
159     xfree(o->op);
160     xfree(o);
161     yaz_log (LOG_DEBUG, "odr_destroy o=%p", o);
162 }
163
164 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
165 {
166     o->bp = (unsigned char *) buf;
167
168     o->buf = (unsigned char *) buf;
169     o->can_grow = can_grow;
170     o->top = o->pos = 0;
171     o->size = len;
172 }
173
174 char *odr_getbuf(ODR o, int *len, int *size)
175 {
176     *len = o->top;
177     if (size)
178         *size = o->size;
179     return (char*) o->buf;
180 }
181