new file
[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.41 2003-03-11 11:03:31 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     "HTTP Bad 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     fprintf(stderr, "%s: %s\n", message, odr_errlist[o->error]);
50 }
51
52 int odr_geterror(ODR o)
53 {
54     return o->error;
55 }
56
57 int odr_geterrorx(ODR o, int *x)
58 {
59     if (x)
60         *x = o->op->error_id;
61     return o->error;
62 }
63
64 void odr_seterror(ODR o, int error, int id)
65 {
66     o->error = error;
67     o->op->error_id = id;
68 }
69
70 void odr_setprint(ODR o, FILE *file)
71 {
72     o->print = file;
73 }
74
75 int odr_set_charset(ODR o, const char *to, const char *from)
76 {
77     if (o->op->iconv_handle)
78         yaz_iconv_close (o->op->iconv_handle);
79
80     o->op->iconv_handle = yaz_iconv_open (to, from);
81     if (o->op->iconv_handle == 0)
82         return -1;
83     return 0;
84 }
85
86 #include <yaz/log.h>
87
88 ODR odr_createmem(int direction)
89 {
90     ODR r;
91
92     if (!(r = (ODR)xmalloc(sizeof(*r))))
93         return 0;
94     r->direction = direction;
95     r->print = stderr;
96     r->buf = 0;
97     r->size = r->pos = r->top = 0;
98     r->can_grow = 1;
99     r->mem = nmem_create();
100     r->enable_bias = 1;
101     r->op = (struct Odr_private *) xmalloc (sizeof(*r->op));
102     r->op->odr_ber_tag.lclass = -1;
103     r->op->iconv_handle = 0;
104     odr_reset(r);
105     yaz_log (LOG_DEBUG, "odr_createmem dir=%d o=%p", direction, r);
106     return r;
107 }
108
109 void odr_reset(ODR o)
110 {
111     odr_seterror(o, ONONE, 0);
112     o->bp = o->buf;
113     odr_seek(o, ODR_S_SET, 0);
114     o->top = 0;
115     o->t_class = -1;
116     o->t_tag = -1;
117     o->indent = 0;
118     o->op->stackp = -1;
119     nmem_reset(o->mem);
120     o->choice_bias = -1;
121     o->lenlen = 1;
122     if (o->op->iconv_handle != 0)
123         yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
124     yaz_log (LOG_DEBUG, "odr_reset o=%p", o);
125 }
126     
127 void odr_destroy(ODR o)
128 {
129     nmem_destroy(o->mem);
130     if (o->buf && o->can_grow)
131        xfree(o->buf);
132     if (o->print && o->print != stderr)
133         fclose(o->print);
134     if (o->op->iconv_handle != 0)
135         yaz_iconv_close (o->op->iconv_handle);
136     xfree(o->op);
137     xfree(o);
138     yaz_log (LOG_DEBUG, "odr_destroy o=%p", o);
139 }
140
141 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
142 {
143     o->bp = (unsigned char *) buf;
144
145     o->buf = (unsigned char *) buf;
146     o->can_grow = can_grow;
147     o->top = o->pos = 0;
148     o->size = len;
149 }
150
151 char *odr_getbuf(ODR o, int *len, int *size)
152 {
153     *len = o->top;
154     if (size)
155         *size = o->size;
156     return (char*) o->buf;
157 }
158