More work on memory management.
[yaz-moved-to-github.git] / odr / odr.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: odr.c,v $
7  * Revision 1.11  1995-05-15 11:56:08  quinn
8  * More work on memory management.
9  *
10  * Revision 1.10  1995/04/18  08:15:20  quinn
11  * Added dynamic memory allocation on encoding (whew). Code is now somewhat
12  * neater. We'll make the same change for decoding one day.
13  *
14  * Revision 1.9  1995/04/10  10:23:11  quinn
15  * Smallish changes.
16  *
17  * Revision 1.8  1995/03/17  10:17:43  quinn
18  * Added memory management.
19  *
20  * Revision 1.7  1995/03/10  11:44:41  quinn
21  * Fixed serious stack-bug in odr_cons_begin
22  *
23  * Revision 1.6  1995/03/08  12:12:15  quinn
24  * Added better error checking.
25  *
26  * Revision 1.5  1995/03/07  13:28:57  quinn
27  * *** empty log message ***
28  *
29  * Revision 1.4  1995/03/07  13:16:13  quinn
30  * Fixed bug in odr_reset
31  *
32  * Revision 1.3  1995/03/07  10:21:31  quinn
33  * odr_errno-->odr_error
34  *
35  * Revision 1.2  1995/03/07  10:19:05  quinn
36  * Addded some method functions to the ODR type.
37  *
38  * Revision 1.1  1995/03/07  09:23:15  quinn
39  * Installing top-level API and documentation.
40  *
41  *
42  */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46
47 #include <dmalloc.h>
48 #include <odr.h>
49
50 char *odr_errlist[] =
51 {
52     "No (unknown) error",
53     "Memory allocation failed",
54     "System error",
55     "No space in buffer",
56     "Required data element missing",
57     "Unexpected tag",
58     "Other error",
59     "Protocol error",
60     "Malformed data",
61     "Stack overflow"
62 };
63
64 void odr_perror(ODR o, char *message)
65 {
66     fprintf(stderr, "%s: %s\n", message, odr_errlist[o->error]);
67 }
68
69 int odr_geterror(ODR o)
70 {
71     return o->error;
72 }
73
74 void odr_setprint(ODR o, FILE *file)
75 {
76     o->print = file;
77 }
78
79 ODR odr_createmem(int direction)
80 {
81     struct odr *r;
82
83     if (!(r = malloc(sizeof(*r))))
84         return 0;
85     r->direction = direction;
86     r->print = stderr;
87     r->buf = 0;
88     r->ecb.buf = 0;
89     r->ecb.size = r->ecb.pos = r->ecb.top = 0;
90     r->ecb.can_grow = 1;
91     r->buflen = 0;
92     r->mem = 0;
93     odr_reset(r);
94     return r;
95 }
96
97 void odr_reset(ODR o)
98 {
99     o->error = ONONE;
100     o->bp = o->buf;
101     odr_seek(o, ODR_S_SET, 0);
102     o->ecb.top = 0;
103     o->left = o->buflen;
104     o->t_class = -1;
105     o->t_tag = -1;
106     o->indent = 0;
107     o->stackp = -1;
108     odr_release_mem(o->mem);
109     o->mem = 0;
110 }
111     
112 void odr_destroy(ODR o)
113 {
114     odr_release_mem(o->mem);
115     if (o->ecb.buf && o->ecb.can_grow)
116         free(o->ecb.buf);
117     if (o->print != stderr)
118         fclose(o->print);
119     free(o);
120 }
121
122 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
123 {
124     o->buf = o->bp = (unsigned char *) buf;
125     o->buflen = o->left = len;
126
127     o->ecb.buf = (unsigned char *) buf;
128     o->ecb.can_grow = can_grow;
129     o->ecb.top = o->ecb.pos = 0;
130     o->ecb.size = len;
131 }
132
133 char *odr_getbuf(ODR o, int *len, int *size)
134 {
135     *len = o->ecb.top;
136     if (size)
137         *size = o->ecb.size;
138     return (char*) o->ecb.buf;
139 }