Modified function heads & prototypes.
[yaz-moved-to-github.git] / odr / odr_cons.c
1 /*
2  * Copyright (c) 1995, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: odr_cons.c,v $
7  * Revision 1.14  1995-09-27 15:02:58  quinn
8  * Modified function heads & prototypes.
9  *
10  * Revision 1.13  1995/08/15  11:16:39  quinn
11  * Fixed pretty-printers.
12  * CV:e ----------------------------------------------------------------------
13  * CV:e ----------------------------------------------------------------------
14  *
15  * Revision 1.12  1995/06/19  12:38:47  quinn
16  * Added BER dumper.
17  *
18  * Revision 1.11  1995/05/16  08:50:53  quinn
19  * License, documentation, and memory fixes
20  *
21  * Revision 1.10  1995/04/18  08:15:21  quinn
22  * Added dynamic memory allocation on encoding (whew). Code is now somewhat
23  * neater. We'll make the same change for decoding one day.
24  *
25  * Revision 1.9  1995/03/28  09:15:49  quinn
26  * Fixed bug in the printing mode
27  *
28  * Revision 1.8  1995/03/15  11:18:04  quinn
29  * Fixed serious bug in odr_cons
30  *
31  * Revision 1.7  1995/03/10  11:44:41  quinn
32  * Fixed serious stack-bug in odr_cons_begin
33  *
34  * Revision 1.6  1995/03/08  12:12:23  quinn
35  * Added better error checking.
36  *
37  * Revision 1.5  1995/02/10  18:57:25  quinn
38  * More in the way of error-checking.
39  *
40  * Revision 1.4  1995/02/10  15:55:29  quinn
41  * Bug fixes, mostly.
42  *
43  * Revision 1.3  1995/02/09  15:51:48  quinn
44  * Works better now.
45  *
46  * Revision 1.2  1995/02/07  17:52:59  quinn
47  * A damn mess, but now things work, I think.
48  *
49  * Revision 1.1  1995/02/02  16:21:53  quinn
50  * First kick.
51  *
52  */
53
54 #include <odr.h>
55 #include <assert.h>
56
57 int MDF odr_constructed_begin(ODR o, void *p, int class, int tag)
58 {
59     int res;
60     int cons = 1;
61
62     if (o->error)
63         return 0;
64     if (o->t_class < 0)
65     {
66         o->t_class = class;
67         o->t_tag = tag;
68     }
69     if ((res = ber_tag(o, p, o->t_class, o->t_tag, &cons, 1)) < 0)
70         return 0;
71     if (!res || !cons)
72         return 0;
73
74     if (o->stackp == ODR_MAX_STACK - 1)
75     {
76         o->error = OSTACK;
77         return 0;
78     }
79     o->stack[++(o->stackp)].lenb = o->bp;
80     o->stack[o->stackp].len_offset = odr_tell(o);
81 #ifdef ODR_DEBUG
82     fprintf(stderr, "[cons_begin(%d)]", o->stackp);
83 #endif
84     if (o->direction == ODR_ENCODE)
85     {
86         o->stack[o->stackp].lenlen = 1;
87         if (odr_putc(o, 0) < 0)     /* dummy */
88             return 0;
89     }
90     else if (o->direction == ODR_DECODE)
91     {
92         if ((res = ber_declen(o->bp, &o->stack[o->stackp].len)) < 0)
93             return 0;
94         o->stack[o->stackp].lenlen = res;
95         o->bp += res;
96         o->left -= res;
97     }
98     else if (o->direction == ODR_PRINT)
99     {
100         fprintf(o->print, "%s{\n", odr_indent(o));
101         o->indent++;
102     }
103     else
104     {
105         o->error = OOTHER;
106         return 0;
107     }
108     o->stack[o->stackp].base = o->bp;
109     o->stack[o->stackp].base_offset = odr_tell(o);
110     return 1;
111 }
112
113 int MDF odr_constructed_more(ODR o)
114 {
115     if (o->error)
116         return 0;
117     if (o->stackp < 0)
118         return 0;
119     if (o->stack[o->stackp].len >= 0)
120         return o->bp - o->stack[o->stackp].base < o->stack[o->stackp].len;
121     else
122         return (!(*o->bp == 0 && *(o->bp + 1) == 0));
123 }
124
125 int MDF odr_constructed_end(ODR o)
126 {
127     int res;
128     int pos;
129
130     if (o->error)
131         return 0;
132     if (o->stackp < 0)
133     {
134         o->error = OOTHER;
135         return 0;
136     }
137     switch (o->direction)
138     {
139         case ODR_DECODE:
140             if (o->stack[o->stackp].len < 0)
141             {
142                 if (*o->bp++ == 0 && *(o->bp++) == 0)
143                 {
144                     o->left -= 2;
145                     o->stackp--;
146                     return 1;
147                 }
148                 else
149                 {
150                     o->error = OOTHER;
151                     return 0;
152                 }
153             }
154             else if (o->bp - o->stack[o->stackp].base !=
155                 o->stack[o->stackp].len)
156             {
157                 o->error = OCONLEN;
158                 return 0;
159             }
160             o->stackp--;
161             return 1;
162         case ODR_ENCODE:
163             pos = odr_tell(o);
164             odr_seek(o, ODR_S_SET, o->stack[o->stackp].len_offset);
165             if ((res = ber_enclen(o, pos - o->stack[o->stackp].base_offset,
166                 o->stack[o->stackp].lenlen, 1)) < 0)
167                 return 0;
168             odr_seek(o, ODR_S_END, 0);
169             if (res == 0)   /* indefinite encoding */
170             {
171 #ifdef ODR_DEBUG
172                 fprintf(stderr, "[cons_end(%d): indefinite]", o->stackp);
173 #endif
174                 if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0)
175                     return 0;
176             }
177 #ifdef ODR_DEBUG
178             else
179             {
180                 fprintf(stderr, "[cons_end(%d): definite]", o->stackp);
181             }
182 #endif
183             o->stackp--;
184             return 1;
185         case ODR_PRINT:
186             assert(o->indent > 0);
187             o->stackp--;
188             o->indent--;
189             fprintf(o->print, "%s}\n", odr_indent(o));
190             return 1;
191         default:
192             o->error = OOTHER;
193             return 0;
194     }
195 }