YAZ  5.23.1
ber_tag.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 <stdio.h>
18 #include "odr-priv.h"
19 
34 int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt,
35  const char *name)
36 {
37  struct Odr_ber_tag *odr_ber_tag = &o->op->odr_ber_tag;
38  int rd;
39  char **pp = (char **)p;
40 
41  if (o->direction == ODR_DECODE)
42  *pp = 0;
43  o->op->t_class = -1;
44  if (ODR_STACK_EMPTY(o))
45  {
46  odr_seek(o, ODR_S_SET, 0);
47  o->op->top = 0;
48  o->op->bp = o->op->buf;
49  odr_ber_tag->lclass = -1;
50  }
51  switch (o->direction)
52  {
53  case ODR_ENCODE:
54  if (!*pp)
55  {
56  if (!opt)
57  {
58  odr_seterror(o, OREQUIRED, 24);
59  odr_setelement (o, name);
60  }
61  return 0;
62  }
63  if ((rd = ber_enctag(o, zclass, tag, *constructed)) < 0)
64  return -1;
65  return 1;
66  case ODR_DECODE:
68  {
69  if (!opt)
70  {
71  odr_seterror(o, OREQUIRED, 25);
72  odr_setelement(o, name);
73  }
74  return 0;
75  }
76  if (odr_ber_tag->lclass < 0)
77  {
78  if ((odr_ber_tag->br =
79  ber_dectag(o->op->bp, &odr_ber_tag->lclass,
80  &odr_ber_tag->ltag, &odr_ber_tag->lcons,
81  odr_max(o))) <= 0)
82  {
83  odr_seterror(o, OPROTO, 26);
84  odr_setelement(o, name);
85  return 0;
86  }
87  }
88  if (zclass == odr_ber_tag->lclass && tag == odr_ber_tag->ltag)
89  {
90  o->op->bp += odr_ber_tag->br;
91  *constructed = odr_ber_tag->lcons;
92  odr_ber_tag->lclass = -1;
93  return 1;
94  }
95  else
96  {
97  if (!opt)
98  {
99  odr_seterror(o, OREQUIRED, 27);
100  odr_setelement(o, name);
101  }
102  return 0;
103  }
104  case ODR_PRINT:
105  if (!*pp && !opt)
106  {
107  odr_seterror(o,OREQUIRED, 28);
108  odr_setelement(o, name);
109  }
110  return *pp != 0;
111  default:
112  odr_seterror(o, OOTHER, 29);
113  odr_setelement(o, name);
114  return 0;
115  }
116 }
117 
123 int ber_enctag(ODR o, int zclass, int tag, int constructed)
124 {
125  int cons = (constructed ? 1 : 0), n = 0;
126  unsigned char octs[sizeof(int)], b;
127 
128  b = (zclass << 6) & 0XC0;
129  b |= (cons << 5) & 0X20;
130  if (tag <= 30)
131  {
132  b |= tag & 0X1F;
133  if (odr_putc(o, b) < 0)
134  return -1;
135  return 1;
136  }
137  else
138  {
139  b |= 0X1F;
140  if (odr_putc(o, b) < 0)
141  return -1;
142  do
143  {
144  octs[n++] = tag & 0X7F;
145  tag >>= 7;
146  }
147  while (tag);
148  while (n--)
149  {
150  unsigned char oo;
151 
152  oo = octs[n] | ((n > 0) << 7);
153  if (odr_putc(o, oo) < 0)
154  return -1;
155  }
156  return 0;
157  }
158 }
159 
165 int ber_dectag(const char *cp, int *zclass, int *tag,
166  int *constructed, int max)
167 {
168  const unsigned char *b = (const unsigned char *) cp;
169  int l = 1;
170 
171  if (l > max)
172  return -1;
173 
174  *zclass = *b >> 6;
175  *constructed = (*b >> 5) & 0X01;
176  if ((*tag = *b & 0x1F) <= 30)
177  return 1;
178  *tag = 0;
179  do
180  {
181  if (l >= max)
182  return -1;
183  *tag <<= 7;
184  *tag |= b[l] & 0X7F;
185  }
186  while (b[l++] & 0X80);
187  return l;
188 }
189 /*
190  * Local variables:
191  * c-basic-offset: 4
192  * c-file-style: "Stroustrup"
193  * indent-tabs-mode: nil
194  * End:
195  * vim: shiftwidth=4 tabstop=8 expandtab
196  */
197 
void odr_seterror(ODR o, int error, int id)
Definition: odr.c:118
int t_class
Definition: odr-priv.h:107
#define ODR_STACK_EMPTY(x)
Definition: odr-priv.h:118
#define ODR_PRINT
Definition: odr.h:97
int lcons
Definition: odr-priv.h:44
#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
char * name
Definition: initopt.c:18
struct Odr_ber_tag odr_ber_tag
Definition: odr-priv.h:97
#define odr_putc(o, c)
Definition: odr-priv.h:129
int ber_enctag(ODR o, int zclass, int tag, int constructed)
BER-encode a zclass/tag/constructed package (identifier octets).
Definition: ber_tag.c:123
int ltag
Definition: odr-priv.h:42
int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt, const char *name)
Encode/decode BER tags.
Definition: ber_tag.c:34
void odr_setelement(ODR o, const char *element)
Definition: odr.c:125
#define ODR_S_SET
Definition: odr.h:117
Internal ODR definitions.
int direction
Definition: odr.h:126
#define OPROTO
Definition: odr.h:157
int odr_constructed_more(ODR o)
Definition: odr_cons.c:136
#define odr_max(o)
Definition: odr-priv.h:47
Utility structure used by ber_tag.
Definition: odr-priv.h:40
struct Odr_private * op
Definition: odr.h:132
#define ODR_STACK_NOT_EMPTY(x)
Definition: odr-priv.h:119
const char * bp
Definition: odr-priv.h:85
Definition: odr.h:124
#define OREQUIRED
Definition: odr.h:154
int ber_dectag(const char *cp, int *zclass, int *tag, int *constructed, int max)
Decodes BER identifier octets.
Definition: ber_tag.c:165
int opt
Definition: initopt.c:19
int lclass
Definition: odr-priv.h:41
char * buf
Definition: odr-priv.h:84
#define ODR_DECODE
Definition: odr.h:95