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