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