More in the way of error-checking.
[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.5  1995-02-10 18:57:25  quinn
8  * More in the way of error-checking.
9  *
10  * Revision 1.4  1995/02/10  15:55:29  quinn
11  * Bug fixes, mostly.
12  *
13  * Revision 1.3  1995/02/09  15:51:48  quinn
14  * Works better now.
15  *
16  * Revision 1.2  1995/02/07  17:52:59  quinn
17  * A damn mess, but now things work, I think.
18  *
19  * Revision 1.1  1995/02/02  16:21:53  quinn
20  * First kick.
21  *
22  */
23
24 #include <odr.h>
25
26 int odr_constructed_begin(ODR o, void *p, int class, int tag)
27 {
28     int res;
29     int cons = 1;
30
31     if (o->t_class < 0)
32     {
33         o->t_class = class;
34         o->t_tag = tag;
35     }
36     if ((res = ber_tag(o, p, o->t_class, o->t_tag, &cons)) < 0)
37         return 0;
38     if (!res || !cons)
39         return 0;
40
41     o->stack[++(o->stackp)].lenb = o->bp;
42     if (o->direction == ODR_ENCODE || o->direction == ODR_PRINT)
43     {
44         o->stack[o->stackp].lenlen = 1;
45         o->bp++;
46         o->left--;
47     }
48     else if (o->direction == ODR_DECODE)
49     {
50         if ((res = ber_declen(o->bp, &o->stack[o->stackp].len)) < 0)
51             return 0;
52         o->stack[o->stackp].lenlen = res;
53         o->bp += res;
54         o->left -= res;
55     }
56     else return 0;
57
58     o->stack[o->stackp].base = o->bp;
59     return 1;
60 }
61
62 int odr_constructed_more(ODR o)
63 {
64     if (o->stackp < 0)
65         return 0;
66     if (o->stack[o->stackp].len >= 0)
67         return o->bp - o->stack[o->stackp].base < o->stack[o->stackp].len;
68     else
69         return (!(*o->bp == 0 && *(o->bp + 1) == 0));
70 }
71
72 int odr_constructed_end(ODR o)
73 {
74     int res;
75
76     if (o->stackp < 0)
77         return 0;
78     switch (o->direction)
79     {
80         case ODR_DECODE:
81             if (o->stack[o->stackp].len < 0)
82             {
83                 if (*o->bp++ == 0 && *(o->bp++) == 0)
84                 {
85                     o->left -= 2;
86                     return 1;
87                 }
88                 else
89                     return 0;
90             }
91             else if (o->bp - o->stack[o->stackp].base !=
92                 o->stack[o->stackp].len)
93                 return 0;
94             o->stackp--;
95             return 1;
96         case ODR_ENCODE:
97             if ((res = ber_enclen(o->stack[o->stackp].lenb,
98                 o->bp - o->stack[o->stackp].base,
99                 o->stack[o->stackp].lenlen, 1)) < 0)
100                     return 0;
101             if (res == 0)   /* indefinite encoding */
102             {
103                 *(o->bp++) = *(o->bp++) = 0;
104                 o->left--;
105             }
106             o->stackp--;
107             return 1;
108         case ODR_PRINT: return 1;
109         default: return 0;
110     }
111 }