15c6e6739c6834cee834dd34c1ee01c80bcddc2f
[yaz-moved-to-github.git] / odr / odr.c
1 /*
2  * Copyright (c) 1995-2002, Index Data
3  * See the file LICENSE for details.
4  *
5  * $Id: odr.c,v 1.35 2002-07-25 12:51:08 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 };
40
41 char *odr_errmsg(int n)
42 {
43     return odr_errlist[n];
44 }
45
46 void odr_perror(ODR o, char *message)
47 {
48     fprintf(stderr, "%s: %s\n", message, odr_errlist[o->error]);
49 }
50
51 int odr_geterror(ODR o)
52 {
53     return o->error;
54 }
55
56 void odr_setprint(ODR o, FILE *file)
57 {
58     o->print = file;
59 }
60
61 int odr_set_charset(ODR o, const char *to, const char *from)
62 {
63 #if HAVE_ICONV_H
64     if (o->op->iconv_handle != (iconv_t)(-1))
65         iconv_close (o->op->iconv_handle);
66
67     o->op->iconv_handle = iconv_open (to, from);
68     if (o->op->iconv_handle == (iconv_t)(-1))
69         return -1;
70     return 0;
71 #else
72     return -1;
73 #endif
74 }
75
76 #include <yaz/log.h>
77
78 ODR odr_createmem(int direction)
79 {
80     ODR r;
81
82     if (!(r = (ODR)xmalloc(sizeof(*r))))
83         return 0;
84     r->direction = direction;
85     r->print = stderr;
86     r->buf = 0;
87     r->size = r->pos = r->top = 0;
88     r->can_grow = 1;
89     r->mem = nmem_create();
90     r->enable_bias = 1;
91     r->op = xmalloc (sizeof(*r->op));
92     r->op->odr_ber_tag.lclass = -1;
93 #if HAVE_ICONV_H
94     r->op->iconv_handle = (iconv_t)(-1);
95 #endif
96     odr_reset(r);
97     yaz_log (LOG_DEBUG, "odr_createmem dir=%d o=%p", direction, r);
98     return r;
99 }
100
101 void odr_reset(ODR o)
102 {
103     o->error = ONONE;
104     o->bp = o->buf;
105     odr_seek(o, ODR_S_SET, 0);
106     o->top = 0;
107     o->t_class = -1;
108     o->t_tag = -1;
109     o->indent = 0;
110     o->op->stackp = -1;
111     nmem_reset(o->mem);
112     o->choice_bias = -1;
113     o->lenlen = 1;
114 #if HAVE_ICONV_H
115     if (o->op->iconv_handle != (iconv_t)(-1))
116         iconv(o->op->iconv_handle, 0, 0, 0, 0);
117 #endif
118     yaz_log (LOG_DEBUG, "odr_reset o=%p", o);
119 }
120     
121 void odr_destroy(ODR o)
122 {
123     nmem_destroy(o->mem);
124     if (o->buf && o->can_grow)
125        xfree(o->buf);
126     if (o->print && o->print != stderr)
127         fclose(o->print);
128 #if HAVE_ICONV_H
129     if (o->op->iconv_handle != (iconv_t)(-1))
130         iconv_close (o->op->iconv_handle);
131 #endif
132     xfree(o->op);
133     xfree(o);
134     yaz_log (LOG_DEBUG, "odr_destroy o=%p", o);
135 }
136
137 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
138 {
139     o->bp = (unsigned char *) buf;
140
141     o->buf = (unsigned char *) buf;
142     o->can_grow = can_grow;
143     o->top = o->pos = 0;
144     o->size = len;
145 }
146
147 char *odr_getbuf(ODR o, int *len, int *size)
148 {
149     *len = o->top;
150     if (size)
151         *size = o->size;
152     return (char*) o->buf;
153 }