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