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