76f726af7c7119f69b535c8d7c593c2bcf1c5ce1
[yaz-moved-to-github.git] / odr / ber_any.c
1 /*
2  * Copyright (c) 1995, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: ber_any.c,v $
7  * Revision 1.11  1995-09-27 15:02:54  quinn
8  * Modified function heads & prototypes.
9  *
10  * Revision 1.10  1995/05/16  08:50:42  quinn
11  * License, documentation, and memory fixes
12  *
13  * Revision 1.9  1995/04/18  08:15:12  quinn
14  * Added dynamic memory allocation on encoding (whew). Code is now somewhat
15  * neater. We'll make the same change for decoding one day.
16  *
17  * Revision 1.8  1995/04/17  09:37:42  quinn
18  * *** empty log message ***
19  *
20  * Revision 1.7  1995/03/17  10:17:39  quinn
21  * Added memory management.
22  *
23  * Revision 1.6  1995/03/08  12:12:02  quinn
24  * Added better error checking.
25  *
26  * Revision 1.5  1995/02/14  20:39:54  quinn
27  * Fixed bugs in completeBER and (serious one in) ber_oid.
28  *
29  * Revision 1.4  1995/02/14  11:54:33  quinn
30  * Adjustments.
31  *
32  * Revision 1.3  1995/02/10  18:57:24  quinn
33  * More in the way of error-checking.
34  *
35  * Revision 1.2  1995/02/10  15:55:28  quinn
36  * Bug fixes, mostly.
37  *
38  * Revision 1.1  1995/02/09  15:51:45  quinn
39  * Works better now.
40  *
41  */
42
43 #include <odr.h>
44
45 int MDF ber_any(ODR o, Odr_any **p)
46 {
47     int res;
48
49     switch (o->direction)
50     {
51         case ODR_DECODE:
52             if ((res = completeBER(o->bp, o->left)) <= 0)        /* FIX THIS */
53             {
54                 o->error = OPROTO;
55                 return 0;
56             }
57             (*p)->buf = odr_malloc(o, res);
58             memcpy((*p)->buf, o->bp, res);
59             (*p)->len = (*p)->size = res;
60             o->bp += res;
61             o->left -= res;
62             return 1;
63         case ODR_ENCODE:
64             if (odr_write(o, (*p)->buf, (*p)->len) < 0)
65                 return 0;
66             return 1;
67         default: o->error = OOTHER; return 0;
68     }
69 }
70
71 /*
72  * Return length of BER-package or 0.
73  */
74 int MDF completeBER(unsigned char *buf, int len)
75 {
76     int res, ll, class, tag, cons;
77     unsigned char *b = buf;
78     
79     if (!len)
80         return 0;
81     if (!buf[0] && !buf[1])
82         return 0;
83     if ((res = ber_dectag(b, &class, &tag, &cons)) <= 0)
84         return 0;
85     if (res > len)
86         return 0;
87     b += res;
88     len -= res;
89     if ((res = ber_declen(b, &ll)) <= 0)
90         return 0;
91     if (res > len)
92         return 0;
93     b += res;
94     len -= res;
95     if (ll >= 0)
96         return (len >= ll ? ll + (b-buf) : 0);
97     if (!cons)
98         return 0;    
99     /* constructed - cycle through children */
100     while (len >= 2)
101     {
102         if (*b == 0 && *(b + 1) == 0)
103             break;
104         if (!(res = completeBER(b, len)))
105             return 0;
106         b += res;
107         len -= res;
108     }
109     if (len < 2)
110         return 0;
111     return (b - buf) + 2;
112 }