Added prettier client.
[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.11  1995-05-16 08:50:53  quinn
8  * License, documentation, and memory fixes
9  *
10  * Revision 1.10  1995/04/18  08:15:21  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/03/28  09:15:49  quinn
15  * Fixed bug in the printing mode
16  *
17  * Revision 1.8  1995/03/15  11:18:04  quinn
18  * Fixed serious bug in odr_cons
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:23  quinn
24  * Added better error checking.
25  *
26  * Revision 1.5  1995/02/10  18:57:25  quinn
27  * More in the way of error-checking.
28  *
29  * Revision 1.4  1995/02/10  15:55:29  quinn
30  * Bug fixes, mostly.
31  *
32  * Revision 1.3  1995/02/09  15:51:48  quinn
33  * Works better now.
34  *
35  * Revision 1.2  1995/02/07  17:52:59  quinn
36  * A damn mess, but now things work, I think.
37  *
38  * Revision 1.1  1995/02/02  16:21:53  quinn
39  * First kick.
40  *
41  */
42
43 #include <odr.h>
44
45 int odr_constructed_begin(ODR o, void *p, int class, int tag)
46 {
47     int res;
48     int cons = 1;
49
50     if (o->error)
51         return 0;
52     if (o->t_class < 0)
53     {
54         o->t_class = class;
55         o->t_tag = tag;
56     }
57     if ((res = ber_tag(o, p, o->t_class, o->t_tag, &cons, 1)) < 0)
58         return 0;
59     if (!res || !cons)
60         return 0;
61
62     if (o->stackp == ODR_MAX_STACK - 1)
63     {
64         o->error = OSTACK;
65         return 0;
66     }
67     o->stack[++(o->stackp)].lenb = o->bp;
68     o->stack[o->stackp].len_offset = odr_tell(o);
69 #ifdef ODR_DEBUG
70     fprintf(stderr, "[cons_begin(%d)]", o->stackp);
71 #endif
72     if (o->direction == ODR_ENCODE || o->direction == ODR_PRINT)
73     {
74         o->stack[o->stackp].lenlen = 1;
75         if (odr_putc(o, 0) < 0)     /* dummy */
76             return 0;
77     }
78     else if (o->direction == ODR_DECODE)
79     {
80         if ((res = ber_declen(o->bp, &o->stack[o->stackp].len)) < 0)
81             return 0;
82         o->stack[o->stackp].lenlen = res;
83         o->bp += res;
84         o->left -= res;
85     }
86     else return 0;
87
88     o->stack[o->stackp].base = o->bp;
89     o->stack[o->stackp].base_offset = odr_tell(o);
90     return 1;
91 }
92
93 int odr_constructed_more(ODR o)
94 {
95     if (o->error)
96         return 0;
97     if (o->stackp < 0)
98         return 0;
99     if (o->stack[o->stackp].len >= 0)
100         return o->bp - o->stack[o->stackp].base < o->stack[o->stackp].len;
101     else
102         return (!(*o->bp == 0 && *(o->bp + 1) == 0));
103 }
104
105 int odr_constructed_end(ODR o)
106 {
107     int res;
108     int pos;
109
110     if (o->error)
111         return 0;
112     if (o->stackp < 0)
113     {
114         o->error = OOTHER;
115         return 0;
116     }
117     switch (o->direction)
118     {
119         case ODR_DECODE:
120             if (o->stack[o->stackp].len < 0)
121             {
122                 if (*o->bp++ == 0 && *(o->bp++) == 0)
123                 {
124                     o->left -= 2;
125                     o->stackp--;
126                     return 1;
127                 }
128                 else
129                 {
130                     o->error = OOTHER;
131                     return 0;
132                 }
133             }
134             else if (o->bp - o->stack[o->stackp].base !=
135                 o->stack[o->stackp].len)
136             {
137                 o->error = OOTHER;
138                 return 0;
139             }
140             o->stackp--;
141             return 1;
142         case ODR_ENCODE:
143             pos = odr_tell(o);
144             odr_seek(o, ODR_S_SET, o->stack[o->stackp].len_offset);
145             if ((res = ber_enclen(o, pos - o->stack[o->stackp].base_offset,
146                 o->stack[o->stackp].lenlen, 1)) < 0)
147                 return 0;
148             odr_seek(o, ODR_S_END, 0);
149             if (res == 0)   /* indefinite encoding */
150             {
151 #ifdef ODR_DEBUG
152                 fprintf(stderr, "[cons_end(%d): indefinite]", o->stackp);
153 #endif
154                 if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0)
155                     return 0;
156             }
157 #ifdef ODR_DEBUG
158             else
159             {
160                 fprintf(stderr, "[cons_end(%d): definite]", o->stackp);
161             }
162 #endif
163             o->stackp--;
164             return 1;
165         case ODR_PRINT: o->stackp--;  return 1;
166         default:
167             o->error = OOTHER;
168             return 0;
169     }
170 }