YAZ  5.23.1
ber_oid.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 
13 #if HAVE_CONFIG_H
14 #include <config.h>
15 #endif
16 
17 #include "odr-priv.h"
18 
19 int ber_oidc(ODR o, Odr_oid *p, int max_oid_size)
20 {
21  int len, lenp, end;
22  int pos, n, res, id;
23  unsigned char octs[8];
24 
25  switch (o->direction)
26  {
27  case ODR_DECODE:
28  if ((res = ber_declen(o->op->bp, &len, odr_max(o))) < 1)
29  {
30  odr_seterror(o, OPROTO, 18);
31  return 0;
32  }
33  if (len < 0)
34  {
35  odr_seterror(o, OPROTO, 19);
36  return 0;
37  }
38  o->op->bp += res;
39  if (len > odr_max(o))
40  {
41  odr_seterror(o, OPROTO, 20);
42  return 0;
43  }
44  pos = 0;
45  while (len)
46  {
47  int id = 0;
48  do
49  {
50  if (!len)
51  {
52  odr_seterror(o, OPROTO, 21);
53  return 0;
54  }
55  id <<= 7;
56  id |= *o->op->bp & 0X7F;
57  len--;
58  }
59  while (*(o->op->bp++) & 0X80);
60 
61  if (id < 0)
62  {
63  odr_seterror(o, ODATA, 23);
64  return 0;
65  }
66  if (pos > 0)
67  p[pos++] = id;
68  else
69  {
70  p[0] = id / 40;
71  if (p[0] > 2)
72  p[0] = 2;
73  p[1] = id - p[0] * 40;
74  pos = 2;
75  }
76  if (pos >= max_oid_size)
77  {
78  odr_seterror(o, OPROTO, 55);
79  return 0;
80  }
81  }
82  if (pos < 2 || p[0] < 0 || p[1] < 0)
83  {
84  odr_seterror(o, ODATA, 23);
85  return 0;
86  }
87  p[pos] = -1;
88  return 1;
89  case ODR_ENCODE:
90  /* we'll allow ourselves the quiet luxury of only doing encodings
91  shorter than 127 */
92  lenp = odr_tell(o);
93  if (odr_putc(o, 0) < 0) /* dummy */
94  return 0;
95  if (p[0] < 0 || p[1] < 0)
96  {
97  odr_seterror(o, ODATA, 23);
98  return 0;
99  }
100  for (pos = 1; p[pos] != -1; pos++)
101  {
102  n = 0;
103  if (pos == 1)
104  id = p[0]*40 + p[1];
105  else
106  id = p[pos];
107  do
108  {
109  octs[n++] = id & 0X7F;
110  id >>= 7;
111  }
112  while (id);
113  while (n--)
114  {
115  unsigned char p;
116 
117  p = octs[n] | ((n > 0) << 7);
118  if (odr_putc(o, p) < 0)
119  return 0;
120  }
121  }
122  end = odr_tell(o);
123  odr_seek(o, ODR_S_SET, lenp);
124  if (ber_enclen(o, (end - lenp) - 1, 1, 1) != 1)
125  {
126  odr_seterror(o, OOTHER, 52);
127  return 0;
128  }
129  odr_seek(o, ODR_S_END, 0);
130  return 1;
131  default:
132  odr_seterror(o, OOTHER, 22);
133  return 0;
134  }
135 }
136 /*
137  * Local variables:
138  * c-basic-offset: 4
139  * c-file-style: "Stroustrup"
140  * indent-tabs-mode: nil
141  * End:
142  * vim: shiftwidth=4 tabstop=8 expandtab
143  */
144 
void odr_seterror(ODR o, int error, int id)
Definition: odr.c:118
int ber_declen(const char *buf, int *len, int max)
Definition: ber_len.c:93
#define OOTHER
Definition: odr.h:156
#define ODR_ENCODE
Definition: odr.h:96
int odr_seek(ODR o, int whence, int offset)
Definition: odr_mem.c:117
#define odr_putc(o, c)
Definition: odr-priv.h:129
short Odr_oid
Definition: oid_util.h:42
#define ODATA
Definition: odr.h:158
#define ODR_S_SET
Definition: odr.h:117
Internal ODR definitions.
int direction
Definition: odr.h:126
#define OPROTO
Definition: odr.h:157
#define odr_max(o)
Definition: odr-priv.h:47
int ber_oidc(ODR o, Odr_oid *p, int max_oid_size)
Definition: ber_oid.c:19
struct Odr_private * op
Definition: odr.h:132
#define ODR_S_END
Definition: odr.h:119
int ber_enclen(ODR o, int len, int lenlen, int exact)
Definition: ber_len.c:30
const char * bp
Definition: odr-priv.h:85
Definition: odr.h:124
#define odr_tell(o)
Definition: odr-priv.h:121
#define ODR_DECODE
Definition: odr.h:95