6492398d4c2fb9995353df3b42152db413c4e7bf
[yaz-moved-to-github.git] / odr / ber_any.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: ber_any.c,v $
7  * Revision 1.6  1995-03-08 12:12:02  quinn
8  * Added better error checking.
9  *
10  * Revision 1.5  1995/02/14  20:39:54  quinn
11  * Fixed bugs in completeBER and (serious one in) ber_oid.
12  *
13  * Revision 1.4  1995/02/14  11:54:33  quinn
14  * Adjustments.
15  *
16  * Revision 1.3  1995/02/10  18:57:24  quinn
17  * More in the way of error-checking.
18  *
19  * Revision 1.2  1995/02/10  15:55:28  quinn
20  * Bug fixes, mostly.
21  *
22  * Revision 1.1  1995/02/09  15:51:45  quinn
23  * Works better now.
24  *
25  */
26
27 #include <odr.h>
28
29 int ber_any(ODR o, Odr_any **p)
30 {
31     int res;
32
33     switch (o->direction)
34     {
35         case ODR_DECODE:
36             if ((res = completeBER(o->bp, o->left)) <= 0)        /* FIX THIS */
37             {
38                 o->error = OPROTO;
39                 return 0;
40             }
41             (*p)->buf = nalloc(o, res);
42             memcpy((*p)->buf, o->bp, res);
43             (*p)->len = (*p)->size = res;
44             o->bp += res;
45             o->left -= res;
46             return 1;
47         case ODR_ENCODE:
48             if ((*p)->len > o->left)
49             {
50                 o->error = OSPACE;
51                 return 0;
52             }
53             memcpy(o->bp , (*p)->buf, (*p)->len);
54             o->bp += (*p)->len;
55             o->left -= (*p)->len;
56             return 1;
57         default: o->error = OOTHER; return 0;
58     }
59 }
60
61 /*
62  * Return length of BER-package or 0.
63  */
64 int completeBER(unsigned char *buf, int len)
65 {
66     int res, ll, class, tag, cons;
67     unsigned char *b = buf;
68     
69     if (!len)
70         return 0;
71     if (!buf[0] && !buf[1])
72         return 0;
73     if ((res = ber_dectag(b, &class, &tag, &cons)) <= 0)
74         return 0;
75     if (res > len)
76         return 0;
77     b += res;
78     len -= res;
79     if ((res = ber_declen(b, &ll)) <= 0)
80         return 0;
81     if (res > len)
82         return 0;
83     b += res;
84     len -= res;
85     if (ll >= 0)
86         return (len >= ll ? ll + (b-buf) : 0);
87     if (!cons)
88         return 0;    
89     /* constructed - cycle through children */
90     while (len >= 2)
91     {
92         if (*b == 0 && *(b + 1) == 0)
93             break;
94         if (!(res = completeBER(b, len)))
95             return 0;
96         b += res;
97         len -= res;
98     }
99     return (b - buf) + 2;
100 }