Check for config.h (currently not generated).
[yaz-moved-to-github.git] / odr / ber_oid.c
1 /*
2  * Copyright (c) 1995-2000, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: ber_oid.c,v $
7  * Revision 1.12  2000-02-29 13:44:55  adam
8  * Check for config.h (currently not generated).
9  *
10  * Revision 1.11  2000/01/31 13:15:21  adam
11  * Removed uses of assert(3). Cleanup of ODR. CCL parser update so
12  * that some characters are not surrounded by spaces in resulting term.
13  * ILL-code updates.
14  *
15  * Revision 1.10  1999/11/30 13:47:11  adam
16  * Improved installation. Moved header files to include/yaz.
17  *
18  * Revision 1.9  1995/09/29 17:12:19  quinn
19  * Smallish
20  *
21  * Revision 1.8  1995/09/27  15:02:56  quinn
22  * Modified function heads & prototypes.
23  *
24  * Revision 1.7  1995/05/16  08:50:47  quinn
25  * License, documentation, and memory fixes
26  *
27  * Revision 1.6  1995/04/18  08:15:18  quinn
28  * Added dynamic memory allocation on encoding (whew). Code is now somewhat
29  * neater. We'll make the same change for decoding one day.
30  *
31  * Revision 1.5  1995/03/20  12:18:22  quinn
32  * Fixed bug in ber_oid
33  *
34  * Revision 1.4  1995/03/08  12:12:11  quinn
35  * Added better error checking.
36  *
37  * Revision 1.3  1995/03/01  08:40:56  quinn
38  * Smallish changes.
39  *
40  * Revision 1.2  1995/02/14  20:39:55  quinn
41  * Fixed bugs in completeBER and (serious one in) ber_oid.
42  *
43  * Revision 1.1  1995/02/03  17:04:36  quinn
44  * Initial revision
45  *
46  */
47 #if HAVE_CONFIG_H
48 #include <config.h>
49 #endif
50
51 #include <yaz/odr.h>
52
53 int ber_oidc(ODR o, Odr_oid *p)
54 {
55     int len, lenp, end;
56     int pos, n, res, id;
57     unsigned char octs[8];
58
59     switch (o->direction)
60     {
61         case ODR_DECODE:
62             if ((res = ber_declen(o->bp, &len)) < 1)
63             {
64                 o->error = OPROTO;
65                 return 0;
66             }
67             if (len < 0)
68             {
69                 o->error = OPROTO;
70                 return 0;
71             }
72             o->bp += res;
73             if (len == 0)
74             {
75                 *p = -1;
76                 return 1;
77             }
78             p[0] = *o->bp / 40;
79             if (p[0] > 2)
80                 p[0] = 2;
81             p[1] = *o->bp - p[0] * 40;
82             o->bp++;
83             pos = 2;
84             len--;
85             while (len)
86             {
87                 p[pos] = 0;
88                 do
89                 {
90                     if (!len)
91                     {
92                         o->error = OPROTO;
93                         return 0;
94                     }
95                     p[pos] <<= 7;
96                     p[pos] |= *o->bp & 0X7F;
97                     len--;
98                 }
99                 while (*(o->bp++) & 0X80);
100                 pos++;
101             }
102             p[pos] = -1;
103             return 1;
104         case ODR_ENCODE:
105             /* we'll allow ourselves the quiet luxury of only doing encodings
106                shorter than 127 */
107             lenp = odr_tell(o);
108             if (odr_putc(o, 0) < 0)   /* dummy */
109                 return 0;
110             if (p[0] < 0 && p[1] <= 0)
111             {
112                 o->error = ODATA;
113                 return 0;
114             }
115             for (pos = 1; p[pos] >= 0; pos++)
116             {
117                 id = pos > 1 ? p[pos] : p[0] * 40 + p[1];
118                 n = 0;
119                 do
120                 {
121                     octs[n++] = id & 0X7F;
122                     id >>= 7;
123                 }
124                 while (id);
125                 while (n--)
126                 {
127                     unsigned char p;
128
129                     p = octs[n] | ((n > 0) << 7);
130                     if (odr_putc(o, p) < 0)
131                         return 0;
132                 }
133             }
134             end = odr_tell(o);
135             odr_seek(o, ODR_S_SET, lenp);
136             if (ber_enclen(o, (end - lenp) - 1, 1, 1) != 1)
137             {
138                 o->error = OOTHER;
139                 return 0;
140             }
141             odr_seek(o, ODR_S_END, 0);
142             return 1;
143         default: o->error = OOTHER; return 0;
144     }
145 }