Works better now.
[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.1  1995-02-09 15:51:45  quinn
8  * Works better now.
9  *
10  */
11
12 #include <odr.h>
13
14 int ber_any(ODR o, Odr_any **p)
15 {
16     int res;
17
18     switch (o->direction)
19     {
20         case ODR_DECODE:
21             if ((res = completeBER(o->bp, o->left)) <= 0)
22                 return 0;
23             (*p)->buf = nalloc(o, res);
24             memcpy((*p)->buf, o->bp, res);
25             (*p)->len = (*p)->size = res;
26             o->bp += res;
27             o->left -= res;
28             return 1;
29         case ODR_ENCODE:
30             if ((*p)->len > o->left)
31                 return 0;
32             memcpy(o->bp , (*p)->buf, (*p)->len);
33             o->bp += (*p)->len;
34             o->left -= (*p)->len;
35             return 1;
36         default: return 0;
37     }
38 }
39
40 /*
41  * Return length of BER-package or -1.
42  */
43 int completeBER(unsigned char *buf, int len)
44 {
45     int res, ll, class, tag, cons;
46     unsigned char *b = buf;
47     
48     if (!buf[0] && !buf[1])
49         return -1;
50     if ((res = ber_dectag(b, &class, &tag, &cons)) <= 0)
51         return 0;
52     if (res > len)
53         return -1;
54     b += res;
55     len -= res;
56     if ((res = ber_declen(b, &ll)) <= 0)
57         return -1;
58     if (res > len)
59         return -1;
60     b += res;
61     len -= res;
62     if (ll >= 0)
63         return (len >= ll ? len + (b-buf) : -1);
64     if (!cons)
65         return -1;    
66     while (1)
67     {
68         if ((res = completeBER(b, len)) < 0)
69             return -1;
70         b += res;
71         len -= res;
72         if (len < 2)
73             return -1;
74         if (*b == 0 && *(b + 1) == 0)
75             return (b - buf) + 2;
76     }
77 }