More type casts. Modify CQL tree - bool is C++ reserved name.
[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.22 2003-02-14 18:49:23 adam Exp $
6  */
7 #if HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10 #include <ctype.h>
11
12 #include "odr-priv.h"
13
14 int ber_any(ODR o, Odr_any **p)
15 {
16     int res;
17     int left = o->size - (o->bp - o->buf);
18
19     switch (o->direction)
20     {
21         case ODR_DECODE:
22             if ((res = completeBER(o->bp, left)) <= 0)        /* FIX THIS */
23             {
24                 o->error = OPROTO;
25                 return 0;
26             }
27             (*p)->buf = (unsigned char *)odr_malloc(o, res);
28             memcpy((*p)->buf, o->bp, res);
29             (*p)->len = (*p)->size = res;
30             o->bp += res;
31             return 1;
32         case ODR_ENCODE:
33             if (odr_write(o, (*p)->buf, (*p)->len) < 0)
34                 return 0;
35             return 1;
36         default: o->error = OOTHER; return 0;
37     }
38 }
39
40 /*
41  * Return length of BER-package or 0.
42  */
43 int completeBER(const unsigned char *buf, int len)
44 {
45     int res, ll, zclass, tag, cons;
46     const unsigned char *b = buf;
47     
48     if (!len)
49         return 0;
50     if (!buf[0] && !buf[1])
51         return 0;
52     if (len > 5 && buf[0] >= 0x20 && buf[0] < 0x7f
53                 && buf[1] >= 0x20 && buf[1] < 0x7f
54                 && buf[2] >= 0x20 && buf[2] < 0x7f)
55     {
56         /* deal with HTTP request/response */
57         int i = 2, content_len = 0;
58
59         while (i <= len-4)
60         {
61             if (buf[i] == '\r' && buf[i+1] == '\n')
62             {
63                 i += 2;
64                 if (buf[i] == '\r' && buf[i+1] == '\n')
65                 {
66                     /* i += 2 seems not to work with GCC -O2 .. 
67                        so i+2 is used instead .. */
68                     if (len >= (i+2)+ content_len)
69                         return (i+2)+ content_len;
70                     break;
71                 }
72                 if (i < len-18)
73                 {
74                     if (!memcmp(buf+i, "Content-Length:", 15))
75                     {
76                         i+= 15;
77                         if (buf[i] == ' ')
78                             i++;
79                         content_len = 0;
80                         while (i <= len-4 && isdigit(buf[i]))
81                             content_len = content_len*10 + (buf[i++] - '0');
82                         if (content_len < 0) /* prevent negative offsets */
83                             content_len = 0;
84                     }
85                 }
86             }
87             else
88                 i++;
89         }
90         return 0;
91     }
92     /* BER from now on .. */
93     if ((res = ber_dectag(b, &zclass, &tag, &cons)) <= 0)
94         return 0;
95     if (res > len)
96         return 0;
97     b += res;
98     len -= res;
99     if ((res = ber_declen(b, &ll)) <= 0)
100         return 0;
101     if (res > len)
102         return 0;
103     b += res;
104     len -= res;
105     if (ll >= 0)
106         return (len >= ll ? ll + (b-buf) : 0);
107     if (!cons)
108         return 0;    
109     /* constructed - cycle through children */
110     while (len >= 2)
111     {
112         if (*b == 0 && *(b + 1) == 0)
113             break;
114         if (!(res = completeBER(b, len)))
115             return 0;
116         b += res;
117         len -= res;
118     }
119     if (len < 2)
120         return 0;
121     return (b - buf) + 2;
122 }