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