db584143a9963c81147117b351b3f06d2f0c14ed
[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.4  1995-04-18 08:15:13  quinn
8  * Added dynamic memory allocation on encoding (whew). Code is now somewhat
9  * neater. We'll make the same change for decoding one day.
10  *
11  * Revision 1.3  1995/03/08  12:12:04  quinn
12  * Added better error checking.
13  *
14  * Revision 1.2  1995/02/03  17:04:31  quinn
15  * *** empty log message ***
16  *
17  * Revision 1.1  1995/02/02  20:38:49  quinn
18  * Updates.
19  *
20  *
21  */
22
23 #include <odr.h>
24
25 int ber_bitstring(ODR o, Odr_bitmask *p, int cons)
26 {
27     int res, len;
28     unsigned char *base;
29
30     switch (o->direction)
31     {
32         case ODR_DECODE:
33             if ((res = ber_declen(o->bp, &len)) < 0)
34             {
35                 o->error = OPROTO;
36                 return 0;
37             }
38             o->bp += res;
39             o->left -= res;
40             if (cons)       /* fetch component strings */
41             {
42                 base = o->bp;
43                 while (odp_more_chunks(o, base, len))
44                     if (!odr_bitstring(o, &p, 0))
45                         return 0;
46                 return 1;
47             }
48             /* primitive bitstring */
49             if (len < 0)
50             {
51                 o->error = OOTHER;
52                 return 0;
53             }
54             if (len == 0)
55                 return 1;
56             if (len - 1 > ODR_BITMASK_SIZE)
57             {
58                 o->error = OOTHER;
59                 return 0;
60             }
61             o->bp++;      /* silently ignore the unused-bits field */
62             o->left--;
63             len--;
64             memcpy(p->bits + p->top + 1, o->bp, len);
65             p->top += len;
66             o->bp += len;
67             o->left -= len;
68             return 1;
69         case ODR_ENCODE:
70             if ((res = ber_enclen(o, p->top + 2, 5, 0)) < 0)
71                 return 0;
72             if (odr_putc(o, 0) < 0)    /* no unused bits here */
73                 return 0;
74             if (p->top < 0)
75                 return 1;
76             if (odr_write(o, p->bits, p->top + 1) < 0)
77                 return 0;
78             return 1;
79         case ODR_PRINT: return 1;
80         default: o->error = OOTHER; return 0;
81     }
82 }