9b5a2fd3e939df27eb517f97d5e881b3f3950bdd
[yaz-moved-to-github.git] / odr / ber_oct.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: ber_oct.c,v $
7  * Revision 1.2  1995-02-02 20:38:50  quinn
8  * Updates.
9  *
10  * Revision 1.1  1995/02/02  16:21:52  quinn
11  * First kick.
12  *
13  */
14
15 #include <odr.h>
16
17 int ber_octetstring(ODR o, ODR_OCT *p, int cons)
18 {
19     int res, len;
20     unsigned char *base, *c;
21
22     switch (o->direction)
23     {
24         case ODR_DECODE:
25             if ((res = ber_declen(o->bp, &len)) < 0)
26                 return 0;
27             o->bp += res;
28             o->left -= 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))
34                         return 0;
35                 return 1;
36             }
37             /* primitive octetstring */
38             if (len < 0)
39                 return 0;
40             if (len == 0)
41                 return 1;
42             if (len > p->size - p->len)
43             {
44                 c = nalloc(o, p->size += len + 1);
45                 if (p->len)
46                     memcpy(c, p->buf, p->len);
47                 p->buf = c;
48             }
49             memcpy(p->buf + p->len, o->bp, len);
50             p->len += len;
51             o->bp += len;
52             o->left -= len;
53             return 1;
54         case ODR_ENCODE:
55             if ((res = ber_enclen(o->bp, p->len, 5, 0)) < 0)
56                 return 0;
57             o->bp += res;
58             o->left -= res;
59             if (p->len == 0)
60                 return 1;
61             if (p->len > o->left)
62                 return 0;
63             memcpy(o->bp, p->buf, p->len);
64             o->bp += p->len;
65             o->left -= p->len;
66             return 1;
67         case ODR_PRINT: return 1;
68         default: return 0;
69     }
70 }