39ebd2545844648ed021d3deefca2fc2ae15a1b8
[yaz-moved-to-github.git] / odr / ber_any.c
1 /*
2  * Copyright (c) 1995-2000, Index Data
3  * See the file LICENSE for details.
4  *
5  * $Log: ber_any.c,v $
6  * Revision 1.17  2000-01-31 13:15:21  adam
7  * Removed uses of assert(3). Cleanup of ODR. CCL parser update so
8  * that some characters are not surrounded by spaces in resulting term.
9  * ILL-code updates.
10  *
11  * Revision 1.16  1999/11/30 13:47:11  adam
12  * Improved installation. Moved header files to include/yaz.
13  *
14  * Revision 1.15  1999/01/08 11:23:20  adam
15  * Added const modifier to some of the BER/ODR encoding routines.
16  *
17  * Revision 1.14  1998/02/11 11:53:34  adam
18  * Changed code so that it compiles as C++.
19  *
20  * Revision 1.13  1997/05/14 06:53:56  adam
21  * C++ support.
22  *
23  * Revision 1.12  1995/09/29 17:12:15  quinn
24  * Smallish
25  *
26  * Revision 1.11  1995/09/27  15:02:54  quinn
27  * Modified function heads & prototypes.
28  *
29  * Revision 1.10  1995/05/16  08:50:42  quinn
30  * License, documentation, and memory fixes
31  *
32  * Revision 1.9  1995/04/18  08:15:12  quinn
33  * Added dynamic memory allocation on encoding (whew). Code is now somewhat
34  * neater. We'll make the same change for decoding one day.
35  *
36  * Revision 1.8  1995/04/17  09:37:42  quinn
37  * *** empty log message ***
38  *
39  * Revision 1.7  1995/03/17  10:17:39  quinn
40  * Added memory management.
41  *
42  * Revision 1.6  1995/03/08  12:12:02  quinn
43  * Added better error checking.
44  *
45  * Revision 1.5  1995/02/14  20:39:54  quinn
46  * Fixed bugs in completeBER and (serious one in) ber_oid.
47  *
48  * Revision 1.4  1995/02/14  11:54:33  quinn
49  * Adjustments.
50  *
51  * Revision 1.3  1995/02/10  18:57:24  quinn
52  * More in the way of error-checking.
53  *
54  * Revision 1.2  1995/02/10  15:55:28  quinn
55  * Bug fixes, mostly.
56  *
57  * Revision 1.1  1995/02/09  15:51:45  quinn
58  * Works better now.
59  *
60  */
61
62 #include <yaz/odr.h>
63
64 int ber_any(ODR o, Odr_any **p)
65 {
66     int res;
67     int left = o->size - (o->bp - o->buf);
68
69     switch (o->direction)
70     {
71         case ODR_DECODE:
72             if ((res = completeBER(o->bp, left)) <= 0)        /* FIX THIS */
73             {
74                 o->error = OPROTO;
75                 return 0;
76             }
77             (*p)->buf = (unsigned char *)odr_malloc(o, res);
78             memcpy((*p)->buf, o->bp, res);
79             (*p)->len = (*p)->size = res;
80             o->bp += res;
81             return 1;
82         case ODR_ENCODE:
83             if (odr_write(o, (*p)->buf, (*p)->len) < 0)
84                 return 0;
85             return 1;
86         default: o->error = OOTHER; return 0;
87     }
88 }
89
90 /*
91  * Return length of BER-package or 0.
92  */
93 int completeBER(const unsigned char *buf, int len)
94 {
95     int res, ll, zclass, tag, cons;
96     const unsigned char *b = buf;
97     
98     if (!len)
99         return 0;
100     if (!buf[0] && !buf[1])
101         return 0;
102     if ((res = ber_dectag(b, &zclass, &tag, &cons)) <= 0)
103         return 0;
104     if (res > len)
105         return 0;
106     b += res;
107     len -= res;
108     if ((res = ber_declen(b, &ll)) <= 0)
109         return 0;
110     if (res > len)
111         return 0;
112     b += res;
113     len -= res;
114     if (ll >= 0)
115         return (len >= ll ? ll + (b-buf) : 0);
116     if (!cons)
117         return 0;    
118     /* constructed - cycle through children */
119     while (len >= 2)
120     {
121         if (*b == 0 && *(b + 1) == 0)
122             break;
123         if (!(res = completeBER(b, len)))
124             return 0;
125         b += res;
126         len -= res;
127     }
128     if (len < 2)
129         return 0;
130     return (b - buf) + 2;
131 }