*** empty log message ***
[yaz-moved-to-github.git] / odr / ber_bit.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: ber_bit.c,v $
7  * Revision 1.2  1995-02-03 17:04:31  quinn
8  * *** empty log message ***
9  *
10  * Revision 1.1  1995/02/02  20:38:49  quinn
11  * Updates.
12  *
13  *
14  */
15
16 #include <odr.h>
17
18 int ber_bitstring(ODR o, Odr_bitmask *p, int cons)
19 {
20     int res, len;
21     unsigned char *base;
22
23     switch (o->direction)
24     {
25         case ODR_DECODE:
26             if ((res = ber_declen(o->bp, &len)) < 0)
27                 return 0;
28             o->bp += res;
29             o->left -= res;
30             if (cons)       /* fetch component strings */
31             {
32                 base = o->bp;
33                 while (odp_more_chunks(o, base, len))
34                     if (!odr_bitstring(o, &p, 0))
35                         return 0;
36                 return 1;
37             }
38             /* primitive bitstring */
39             if (len < 0)
40                 return 0;
41             if (len == 0)
42                 return 1;
43             if (len - 1 > ODR_BITMASK_SIZE)
44                 return 0;
45             o->bp++;      /* silently ignore the unused-bits field */
46             o->left--;
47             len--;
48             memcpy(p->bits + p->top + 1, o->bp, len);
49             p->top += len;
50             o->bp += len;
51             o->left -= len;
52             return 1;
53         case ODR_ENCODE:
54             if ((res = ber_enclen(o->bp, p->top + 2, 5, 0)) < 0)
55                 return 0;
56             o->bp += res;
57             o->left -= res;
58             if (p->top + 2 > o->left)
59                 return 0;
60             *(o->bp++) = 0;    /* no unused bits here */
61             o->left--;
62             if (p->top < 0)
63                 return 1;
64             memcpy(o->bp, p->bits, p->top + 1);
65             o->bp += p->top + 1;
66             o->left -= p->top +1;
67             return 1;
68         case ODR_PRINT: return 1;
69         default: return 0;
70     }
71 }