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