SRW, CQL, 2003
[yaz-moved-to-github.git] / odr / ber_oct.c
1 /*
2  * Copyright (c) 1995-2003, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Id: ber_oct.c,v 1.20 2003-01-06 08:20:27 adam Exp $
7  */
8 #if HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include "odr-priv.h"
13
14 int ber_octetstring(ODR o, Odr_oct *p, int cons)
15 {
16     int res, len;
17     const unsigned char *base;
18     unsigned char *c;
19
20     switch (o->direction)
21     {
22         case ODR_DECODE:
23             if ((res = ber_declen(o->bp, &len)) < 0)
24             {
25                 o->error = OPROTO;
26                 return 0;
27             }
28             o->bp += res;
29             if (cons)       /* fetch component strings */
30             {
31                 base = o->bp;
32                 while (odp_more_chunks(o, base, len))
33                     if (!odr_octetstring(o, &p, 0, 0))
34                         return 0;
35                 return 1;
36             }
37             /* primitive octetstring */
38             if (len < 0)
39             {
40                 o->error = OOTHER;
41                 return 0;
42             }
43             if (len + 1 > p->size - p->len)
44             {
45                 c = (unsigned char *)odr_malloc(o, p->size += len + 1);
46                 if (p->len)
47                     memcpy(c, p->buf, p->len);
48                 p->buf = c;
49             }
50             if (len)
51                 memcpy(p->buf + p->len, o->bp, len);
52             p->len += len;
53             o->bp += len;
54             /* the final null is really not part of the buffer, but */
55             /* it helps somes applications that assumes C strings */
56             if (len)
57                 p->buf[p->len] = '\0';
58             return 1;
59         case ODR_ENCODE:
60             if ((res = ber_enclen(o, p->len, 5, 0)) < 0)
61                 return 0;
62             if (p->len == 0)
63                 return 1;
64             if (odr_write(o, p->buf, p->len) < 0)
65                 return 0;
66             return 1;
67         case ODR_PRINT: return 1;
68         default: o->error = OOTHER; return 0;
69     }
70 }