3208e7a80ec189d0921cd2f148126b8064d8ded7
[yaz-moved-to-github.git] / odr / odr.c
1 /*
2  * Copyright (c) 1995-1997, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: odr.c,v $
7  * Revision 1.27  1998-02-11 11:53:34  adam
8  * Changed code so that it compiles as C++.
9  *
10  * Revision 1.26  1997/11/24 11:33:56  adam
11  * Using function odr_nullval() instead of global ODR_NULLVAL when
12  * appropriate.
13  *
14  * Revision 1.25  1997/10/31 12:20:08  adam
15  * Improved memory debugging for xmalloc/nmem.c. References to NMEM
16  * instead of ODR in n ESPEC-1 handling in source d1_espec.c.
17  * Bug fix: missing fclose in data1_read_espec1.
18  *
19  * Revision 1.24  1997/09/01 08:51:07  adam
20  * New windows NT/95 port using MSV5.0. Had to avoid a few static
21  * variables used in function ber_tag. These are now part of the
22  * ODR structure.
23  *
24  * Revision 1.23  1997/04/30 08:52:10  quinn
25  * Null
26  *
27  * Revision 1.22  1996/10/08  12:58:17  adam
28  * New ODR function, odr_choice_enable_bias, to control behaviour of
29  * odr_choice_bias.
30  *
31  * Revision 1.21  1996/07/26  13:38:19  quinn
32  * Various smaller things. Gathered header-files.
33  *
34  * Revision 1.20  1995/11/08  17:41:32  quinn
35  * Smallish.
36  *
37  * Revision 1.19  1995/11/01  13:54:41  quinn
38  * Minor adjustments
39  *
40  * Revision 1.18  1995/09/29  17:12:22  quinn
41  * Smallish
42  *
43  * Revision 1.17  1995/09/29  17:01:50  quinn
44  * More Windows work
45  *
46  * Revision 1.16  1995/09/27  15:02:57  quinn
47  * Modified function heads & prototypes.
48  *
49  * Revision 1.15  1995/08/15  12:00:22  quinn
50  * Updated External
51  *
52  * Revision 1.14  1995/06/19  12:38:46  quinn
53  * Added BER dumper.
54  *
55  * Revision 1.13  1995/05/22  11:32:02  quinn
56  * Fixing Interface to odr_null.
57  *
58  * Revision 1.12  1995/05/16  08:50:49  quinn
59  * License, documentation, and memory fixes
60  *
61  * Revision 1.11  1995/05/15  11:56:08  quinn
62  * More work on memory management.
63  *
64  * Revision 1.10  1995/04/18  08:15:20  quinn
65  * Added dynamic memory allocation on encoding (whew). Code is now somewhat
66  * neater. We'll make the same change for decoding one day.
67  *
68  * Revision 1.9  1995/04/10  10:23:11  quinn
69  * Smallish changes.
70  *
71  * Revision 1.8  1995/03/17  10:17:43  quinn
72  * Added memory management.
73  *
74  * Revision 1.7  1995/03/10  11:44:41  quinn
75  * Fixed serious stack-bug in odr_cons_begin
76  *
77  * Revision 1.6  1995/03/08  12:12:15  quinn
78  * Added better error checking.
79  *
80  * Revision 1.5  1995/03/07  13:28:57  quinn
81  * *** empty log message ***
82  *
83  * Revision 1.4  1995/03/07  13:16:13  quinn
84  * Fixed bug in odr_reset
85  *
86  * Revision 1.3  1995/03/07  10:21:31  quinn
87  * odr_errno-->odr_error
88  *
89  * Revision 1.2  1995/03/07  10:19:05  quinn
90  * Addded some method functions to the ODR type.
91  *
92  * Revision 1.1  1995/03/07  09:23:15  quinn
93  * Installing top-level API and documentation.
94  *
95  *
96  */
97
98 #include <stdio.h>
99 #include <stdlib.h>
100
101 #include <xmalloc.h>
102 #include <odr.h>
103
104 Odr_null *ODR_NULLVAL = "NULL";  /* the presence of a null value */
105
106 Odr_null *odr_nullval (void)
107 {
108     return ODR_NULLVAL;
109 }
110
111 char *odr_errlist[] =
112 {
113     "No (unknown) error",
114     "Memory allocation failed",
115     "System error",
116     "No space in buffer",
117     "Required data element missing",
118     "Unexpected tag",
119     "Other error",
120     "Protocol error",
121     "Malformed data",
122     "Stack overflow",
123     "Length of constructed type different from sum of members",
124     "Overflow writing definite length of constructed type"
125 };
126
127 char *odr_errmsg(int n)
128 {
129     return odr_errlist[n];
130 }
131
132 void odr_perror(ODR o, char *message)
133 {
134     fprintf(stderr, "%s: %s\n", message, odr_errlist[o->error]);
135 }
136
137 int odr_geterror(ODR o)
138 {
139     return o->error;
140 }
141
142 void odr_setprint(ODR o, FILE *file)
143 {
144     o->print = file;
145 }
146
147 #include <log.h>
148
149 ODR odr_createmem(int direction)
150 {
151     ODR r;
152
153
154     logf (LOG_DEBUG, "odr_createmem dir=%d", direction);
155     if (!(r = (ODR)xmalloc(sizeof(*r))))
156         return 0;
157     r->direction = direction;
158     r->print = stderr;
159     r->buf = 0;
160     r->ecb.buf = 0;
161     r->ecb.size = r->ecb.pos = r->ecb.top = 0;
162     r->ecb.can_grow = 1;
163     r->buflen = 0;
164     r->mem = nmem_create();
165     r->enable_bias = 1;
166     r->odr_ber_tag.lclass = -1;
167     odr_reset(r);
168     return r;
169 }
170
171 void odr_reset(ODR o)
172 {
173     o->error = ONONE;
174     o->bp = o->buf;
175     odr_seek(o, ODR_S_SET, 0);
176     o->ecb.top = 0;
177     o->left = o->buflen;
178     o->t_class = -1;
179     o->t_tag = -1;
180     o->indent = 0;
181     o->stackp = -1;
182     nmem_reset(o->mem);
183     o->choice_bias = -1;
184     o->lenlen = 1;
185 }
186     
187 void odr_destroy(ODR o)
188 {
189     nmem_destroy(o->mem);
190     if (o->ecb.buf && o->ecb.can_grow)
191        xfree(o->ecb.buf);
192     if (o->print != stderr)
193         fclose(o->print);
194     xfree(o);
195 }
196
197 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
198 {
199     o->buf = o->bp = (unsigned char *) buf;
200     o->buflen = o->left = len;
201
202     o->ecb.buf = (unsigned char *) buf;
203     o->ecb.can_grow = can_grow;
204     o->ecb.top = o->ecb.pos = 0;
205     o->ecb.size = len;
206 }
207
208 char *odr_getbuf(ODR o, int *len, int *size)
209 {
210     *len = o->ecb.top;
211     if (size)
212         *size = o->ecb.size;
213     return (char*) o->ecb.buf;
214 }