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