First kick.
[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.1  1995-02-02 16:21:52  quinn
8  * First kick.
9  *
10  */
11
12 #include <odr.h>
13
14 static int more_chunks(ODR o, unsigned char *base, int len)
15 {
16     if (!len)
17         return 0;
18     if (len < 0) /* indefinite length */
19     {
20         if (*o->bp == 0 && *(o->bp + 1) == 0)
21         {
22             o->bp += 2;
23             o->left -= 2;
24             return 0;
25         }
26         else
27             return 1;
28     }
29     else
30         return o->bp - base < len;
31 }
32
33 int ber_octetstring(ODR o, ODR_OCT *p, int cons)
34 {
35     int res, len;
36     unsigned char *base, *c;
37
38     switch (o->direction)
39     {
40         case ODR_DECODE:
41             if ((res = ber_declen(o->bp, &len)) < 0)
42                 return 0;
43             o->bp += res;
44             o->left -= res;
45             if (cons)       /* fetch component strings */
46             {
47                 base = o->bp;
48                 while (more_chunks(o, base, len))
49                     if (!odr_octetstring(o, &p, 0))
50                         return 0;
51                 return 1;
52             }
53             /* primitive octetstring */
54             if (len < 0)
55                 return 0;
56             if (len == 0)
57                 return 1;
58             if (len > p->size - p->len)
59             {
60                 c = nalloc(o, p->size += len);
61                 if (p->len)
62                     memcpy(c, p->buf, p->len);
63                 p->buf = c;
64             }
65             memcpy(p->buf + p->len, o->bp, len);
66             p->len += len;
67             o->bp += len;
68             o->left -= len;
69             return 1;
70         case ODR_ENCODE:
71             if ((res = ber_enclen(o->bp, p->len, 5, 0)) < 0)
72                 return 0;
73             o->bp += res;
74             o->left -= res;
75             if (p->len == 0)
76                 return 1;
77             if (p->len > o->left)
78                 return 0;
79             memcpy(o->bp, p->buf, p->len);
80             o->bp += p->len;
81             o->left -= p->len;
82             return 1;
83         case ODR_PRINT: return 1;
84         default: return 0;
85     }
86 }