22f9b21d925ef0fb59a6c1461cbac49cb35b8fee
[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.39 2003-01-06 08:20:27 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 (o->op->iconv_handle)
64         yaz_iconv_close (o->op->iconv_handle);
65
66     o->op->iconv_handle = yaz_iconv_open (to, from);
67     if (o->op->iconv_handle == 0)
68         return -1;
69     return 0;
70 }
71
72 #include <yaz/log.h>
73
74 ODR odr_createmem(int direction)
75 {
76     ODR r;
77
78     if (!(r = (ODR)xmalloc(sizeof(*r))))
79         return 0;
80     r->direction = direction;
81     r->print = stderr;
82     r->buf = 0;
83     r->size = r->pos = r->top = 0;
84     r->can_grow = 1;
85     r->mem = nmem_create();
86     r->enable_bias = 1;
87     r->op = (struct Odr_private *) xmalloc (sizeof(*r->op));
88     r->op->odr_ber_tag.lclass = -1;
89     r->op->iconv_handle = 0;
90     odr_reset(r);
91     yaz_log (LOG_DEBUG, "odr_createmem dir=%d o=%p", direction, r);
92     return r;
93 }
94
95 void odr_reset(ODR o)
96 {
97     o->error = ONONE;
98     o->bp = o->buf;
99     odr_seek(o, ODR_S_SET, 0);
100     o->top = 0;
101     o->t_class = -1;
102     o->t_tag = -1;
103     o->indent = 0;
104     o->op->stackp = -1;
105     nmem_reset(o->mem);
106     o->choice_bias = -1;
107     o->lenlen = 1;
108     if (o->op->iconv_handle != 0)
109         yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
110     yaz_log (LOG_DEBUG, "odr_reset o=%p", o);
111 }
112     
113 void odr_destroy(ODR o)
114 {
115     nmem_destroy(o->mem);
116     if (o->buf && o->can_grow)
117        xfree(o->buf);
118     if (o->print && o->print != stderr)
119         fclose(o->print);
120     if (o->op->iconv_handle != 0)
121         yaz_iconv_close (o->op->iconv_handle);
122     xfree(o->op);
123     xfree(o);
124     yaz_log (LOG_DEBUG, "odr_destroy o=%p", o);
125 }
126
127 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
128 {
129     o->bp = (unsigned char *) buf;
130
131     o->buf = (unsigned char *) buf;
132     o->can_grow = can_grow;
133     o->top = o->pos = 0;
134     o->size = len;
135 }
136
137 char *odr_getbuf(ODR o, int *len, int *size)
138 {
139     *len = o->top;
140     if (size)
141         *size = o->size;
142     return (char*) o->buf;
143 }