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