Comment.
[yaz-moved-to-github.git] / src / odr.c
1 /*
2  * Copyright (c) 1995-2003, Index Data
3  * See the file LICENSE for details.
4  *
5  * $Id: odr.c,v 1.1 2003-10-27 12:21:33 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, const char *message)
48 {
49     const char *e = odr_getelement(o);
50     int err, x;
51
52     err =  odr_geterrorx(o, &x);
53     fprintf(stderr, "%s: %s (code %d:%d)", message, odr_errlist[err], err, x);
54     if (e && *e)
55         fprintf (stderr, " element %s", e);
56     fprintf(stderr, "\n");
57 }
58
59 int odr_geterror(ODR o)
60 {
61     return o->error;
62 }
63
64 int odr_geterrorx(ODR o, int *x)
65 {
66     if (x)
67         *x = o->op->error_id;
68     return o->error;
69 }
70
71 char *odr_getelement(ODR o)
72 {
73     return o->op->element;
74 }
75
76 void odr_seterror(ODR o, int error, int id)
77 {
78     o->error = error;
79     o->op->error_id = id;
80     o->op->element[0] = '\0';
81 }
82
83 void odr_setelement(ODR o, const char *element)
84 {
85     if (element)
86     {
87         strncpy(o->op->element, element, sizeof(o->op->element)-1);
88         o->op->element[sizeof(o->op->element)-1] = '\0';
89     }
90 }
91
92 void odr_setprint(ODR o, FILE *file)
93 {
94     o->print = file;
95 }
96
97 int odr_set_charset(ODR o, const char *to, const char *from)
98 {
99     if (o->op->iconv_handle)
100         yaz_iconv_close (o->op->iconv_handle);
101     o->op->iconv_handle = 0;
102     if (to && from)
103     {
104         o->op->iconv_handle = yaz_iconv_open (to, from);
105         if (o->op->iconv_handle == 0)
106             return -1;
107     }
108     return 0;
109 }
110
111 #include <yaz/log.h>
112
113 ODR odr_createmem(int direction)
114 {
115     ODR r;
116
117     if (!(r = (ODR)xmalloc(sizeof(*r))))
118         return 0;
119     r->direction = direction;
120     r->print = stderr;
121     r->buf = 0;
122     r->size = r->pos = r->top = 0;
123     r->can_grow = 1;
124     r->mem = nmem_create();
125     r->enable_bias = 1;
126     r->op = (struct Odr_private *) xmalloc (sizeof(*r->op));
127     r->op->odr_ber_tag.lclass = -1;
128     r->op->iconv_handle = 0;
129     odr_reset(r);
130     yaz_log (LOG_DEBUG, "odr_createmem dir=%d o=%p", direction, r);
131     return r;
132 }
133
134 void odr_reset(ODR o)
135 {
136     odr_seterror(o, ONONE, 0);
137     o->bp = o->buf;
138     odr_seek(o, ODR_S_SET, 0);
139     o->top = 0;
140     o->t_class = -1;
141     o->t_tag = -1;
142     o->indent = 0;
143     o->op->stackp = -1;
144     nmem_reset(o->mem);
145     o->choice_bias = -1;
146     o->lenlen = 1;
147     if (o->op->iconv_handle != 0)
148         yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
149     yaz_log (LOG_DEBUG, "odr_reset o=%p", o);
150 }
151     
152 void odr_destroy(ODR o)
153 {
154     nmem_destroy(o->mem);
155     if (o->buf && o->can_grow)
156        xfree(o->buf);
157     if (o->print && o->print != stderr)
158         fclose(o->print);
159     if (o->op->iconv_handle != 0)
160         yaz_iconv_close (o->op->iconv_handle);
161     xfree(o->op);
162     xfree(o);
163     yaz_log (LOG_DEBUG, "odr_destroy o=%p", o);
164 }
165
166 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
167 {
168     o->bp = (unsigned char *) buf;
169
170     o->buf = (unsigned char *) buf;
171     o->can_grow = can_grow;
172     o->top = o->pos = 0;
173     o->size = len;
174 }
175
176 char *odr_getbuf(ODR o, int *len, int *size)
177 {
178     *len = o->top;
179     if (size)
180         *size = o->size;
181     return (char*) o->buf;
182 }
183