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