cql available in yaz-client
[yaz-moved-to-github.git] / odr / ber_any.c
1 /*
2  * Copyright (c) 1995-2003, Index Data
3  * See the file LICENSE for details.
4  *
5  * $Id: ber_any.c,v 1.23 2003-02-21 12:08:58 adam Exp $
6  */
7 #if HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include "odr-priv.h"
12
13 int ber_any(ODR o, Odr_any **p)
14 {
15     int res;
16     int left = o->size - (o->bp - o->buf);
17
18     switch (o->direction)
19     {
20         case ODR_DECODE:
21             if ((res = completeBER(o->bp, left)) <= 0)        /* FIX THIS */
22             {
23                 o->error = OPROTO;
24                 return 0;
25             }
26             (*p)->buf = (unsigned char *)odr_malloc(o, res);
27             memcpy((*p)->buf, o->bp, res);
28             (*p)->len = (*p)->size = res;
29             o->bp += res;
30             return 1;
31         case ODR_ENCODE:
32             if (odr_write(o, (*p)->buf, (*p)->len) < 0)
33                 return 0;
34             return 1;
35         default: o->error = OOTHER; return 0;
36     }
37 }
38
39 /*
40  * Return length of BER-package or 0.
41  */
42 int completeBER(const unsigned char *buf, int len)
43 {
44     int res, ll, zclass, tag, cons;
45     const unsigned char *b = buf;
46     
47     if (!len)
48         return 0;
49     if (!buf[0] && !buf[1])
50         return 0;
51     if ((res = ber_dectag(b, &zclass, &tag, &cons)) <= 0)
52         return 0;
53     if (res > len)
54         return 0;
55     b += res;
56     len -= res;
57     if ((res = ber_declen(b, &ll)) <= 0)
58         return 0;
59     if (res > len)
60         return 0;
61     b += res;
62     len -= res;
63     if (ll >= 0)
64         return (len >= ll ? ll + (b-buf) : 0);
65     if (!cons)
66         return 0;    
67     /* constructed - cycle through children */
68     while (len >= 2)
69     {
70         if (*b == 0 && *(b + 1) == 0)
71             break;
72         if (!(res = completeBER(b, len)))
73             return 0;
74         b += res;
75         len -= res;
76     }
77     if (len < 2)
78         return 0;
79     return (b - buf) + 2;
80 }