Initial revision
[yaz-moved-to-github.git] / odr / ber_oid.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: ber_oid.c,v $
7  * Revision 1.1  1995-02-03 17:04:36  quinn
8  * Initial revision
9  *
10  */
11
12 #include <odr.h>
13
14 int ber_oid(ODR o, Odr_oid *p)
15 {
16     int len;
17     unsigned char *lenp;
18     int pos, n, res, id;
19     unsigned char octs[8];
20
21     switch (o->direction)
22     {
23         case ODR_DECODE:
24             if ((res = ber_declen(o->bp, &len)) < 1)
25                 return 0;
26             if (len < 0)
27                 return 0;
28             o->bp += res;
29             o->left -= res;
30             if (len == 0)
31             {
32                 *p = -1;
33                 return 1;
34             }
35             p[0] = *o->bp / 40;
36             if (p[0] > 2)
37                 p[0] = 2;
38             p[1] = *o->bp - p[0] * 40;
39             o->bp++;
40             o->left--;
41             pos = 2;
42             len--;
43             while (len)
44             {
45                 p[pos] = 0;
46                 do
47                 {
48                     if (!len)
49                         return 0;
50                     p[pos] <<= 7;
51                     p[pos] |= *o->bp & 0X7F;
52                     len--;
53                     o->left--;
54                 }
55                 while (*(o->bp++) & 0X80);
56                 pos++;
57             }
58             p[pos] = -1;
59             return 1;
60         case ODR_ENCODE:
61             /* we'll allow ourselves the quiet luxury of only doing encodings
62                shorter than 127 */
63             lenp = o->bp;
64             o->bp++;
65             o->left--;
66             if (p[0] < 0 && p[1] <= 0)
67                 return 0;
68             p[1] = p[0] * 40 + p[1];
69             for (pos = 1; p[pos] >= 0; pos++)
70             {
71                 id = p[pos];
72                 n = 0;
73                 do
74                 {
75                     octs[n++] = id &= 0X7F;
76                     id >>= 7;
77                 }
78                 while (id);
79                 if (n > o->left)
80                     return 0;
81                 o->left -= n;
82                 while (n--)
83                     *(o->bp++) = octs[n] | ((n > 0) << 7);
84             }
85             if (ber_enclen(lenp, (o->bp - lenp) - 1, 1, 1) != 1)
86                 return 0;
87             return 1;
88         default: return 0;
89     }
90 }