YAZ 5.35.1
odr_cons.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
11#if HAVE_CONFIG_H
12#include <config.h>
13#endif
14
15#include <assert.h>
16
17#include "odr-priv.h"
18
19void odr_setlenlen(ODR o, int len)
20{
21 o->op->lenlen = len;
22}
23
24int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag,
25 const char *name)
26{
27 int res;
28 int cons = 1;
29 int lenlen = o->op->lenlen;
30
31 if (o->error)
32 return 0;
33 o->op->lenlen = 1; /* reset lenlen */
34 if (o->op->t_class < 0)
35 {
36 o->op->t_class = zclass;
37 o->op->t_tag = tag;
38 }
39 res = ber_tag(o, xxp, o->op->t_class, o->op->t_tag, &cons, 1, name);
40 if (res < 0)
41 return 0;
42 if (!res || !cons)
43 return 0;
44
45 /* push the odr_constack */
46 if (o->op->stack_top && o->op->stack_top->next)
47 {
48 /* reuse old entry */
49 o->op->stack_top = o->op->stack_top->next;
50 }
51 else if (o->op->stack_top && !o->op->stack_top->next)
52 {
53 /* must allocate new entry (not first) */
54 int sz = 0;
55 struct odr_constack *st;
56 /* check size first */
57 for (st = o->op->stack_top; st; st = st->prev)
58 sz++;
59
60 if (sz >= ODR_MAX_STACK)
61 {
62 odr_seterror(o, OSTACK, 30);
63 return 0;
64 }
65 o->op->stack_top->next = (struct odr_constack *)
66 odr_malloc(o, sizeof(*o->op->stack_top));
67 o->op->stack_top->next->prev = o->op->stack_top;
68 o->op->stack_top->next->next = 0;
69
70 o->op->stack_top = o->op->stack_top->next;
71 }
72 else if (!o->op->stack_top)
73 {
74 /* stack empty */
75 if (!o->op->stack_first)
76 {
77 /* first item must be allocated */
78 o->op->stack_first = (struct odr_constack *)
79 odr_malloc(o, sizeof(*o->op->stack_top));
80 o->op->stack_first->prev = 0;
81 o->op->stack_first->next = 0;
82 }
83 o->op->stack_top = o->op->stack_first;
84 assert(o->op->stack_top->prev == 0);
85 }
86 o->op->stack_top->lenb = o->op->bp;
88 o->op->stack_top->name = name ? name : "?";
89 if (o->direction == ODR_ENCODE)
90 {
91 static char dummy[sizeof(int)+1];
92
94
95 if (odr_write(o, dummy, lenlen) < 0) /* dummy */
96 {
98 return 0;
99 }
100 }
101 else if (o->direction == ODR_DECODE)
102 {
103 if ((res = ber_declen(o->op->bp, &o->op->stack_top->len,
104 odr_max(o))) < 0)
105 {
106 odr_seterror(o, OOTHER, 31);
107 ODR_STACK_POP(o);
108 return 0;
109 }
110 o->op->stack_top->lenlen = res;
111 o->op->bp += res;
112 if (o->op->stack_top->len > odr_max(o))
113 {
114 odr_seterror(o, OOTHER, 32);
115 ODR_STACK_POP(o);
116 return 0;
117 }
118 }
119 else if (o->direction == ODR_PRINT)
120 {
121 odr_prname(o, name);
122 odr_printf(o, "{\n");
123 o->op->indent++;
124 }
125 else
126 {
127 odr_seterror(o, OOTHER, 33);
128 ODR_STACK_POP(o);
129 return 0;
130 }
131 o->op->stack_top->base = o->op->bp;
133 return 1;
134}
135
137{
138 if (o->error)
139 return 0;
140 if (ODR_STACK_EMPTY(o))
141 return 0;
142 if (o->op->stack_top->len >= 0)
143 return o->op->bp - o->op->stack_top->base < o->op->stack_top->len;
144 else
145 return (!(*o->op->bp == 0 && *(o->op->bp + 1) == 0));
146}
147
149{
150 int res;
151 int pos;
152
153 if (o->error)
154 return 0;
155 if (ODR_STACK_EMPTY(o))
156 {
157 odr_seterror(o, OOTHER, 34);
158 return 0;
159 }
160 switch (o->direction)
161 {
162 case ODR_DECODE:
163 if (o->op->stack_top->len < 0)
164 {
165 if (*o->op->bp++ == 0 && *(o->op->bp++) == 0)
166 {
167 ODR_STACK_POP(o);
168 return 1;
169 }
170 else
171 {
172 odr_seterror(o, OOTHER, 35);
173 return 0;
174 }
175 }
176 else if (o->op->bp - o->op->stack_top->base !=
177 o->op->stack_top->len)
178 {
179 odr_seterror(o, OCONLEN, 36);
180 return 0;
181 }
182 ODR_STACK_POP(o);
183 return 1;
184 case ODR_ENCODE:
185 pos = odr_tell(o);
187 if ((res = ber_enclen(o, pos - o->op->stack_top->base_offset,
188 o->op->stack_top->lenlen, 1)) < 0)
189 {
190 odr_seterror(o, OLENOV, 37);
191 return 0;
192 }
193 odr_seek(o, ODR_S_END, 0);
194 if (res == 0) /* indefinite encoding */
195 {
196 if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0)
197 return 0;
198 }
199 ODR_STACK_POP(o);
200 return 1;
201 case ODR_PRINT:
202 ODR_STACK_POP(o);
203 o->op->indent--;
204 odr_prname(o, 0);
205 odr_printf(o, "}\n");
206 return 1;
207 default:
208 odr_seterror(o, OOTHER, 38);
209 return 0;
210 }
211}
212/*
213 * Local variables:
214 * c-basic-offset: 4
215 * c-file-style: "Stroustrup"
216 * indent-tabs-mode: nil
217 * End:
218 * vim: shiftwidth=4 tabstop=8 expandtab
219 */
220
int ber_declen(const char *buf, int *len, int max)
Definition ber_len.c:93
int ber_enclen(ODR o, int len, int lenlen, int exact)
Definition ber_len.c:30
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
char * name
Definition initopt.c:18
Internal ODR definitions.
#define odr_tell(o)
Definition odr-priv.h:121
#define odr_putc(o, c)
Definition odr-priv.h:129
#define ODR_MAX_STACK
Definition odr-priv.h:78
#define odr_max(o)
Definition odr-priv.h:47
#define ODR_STACK_EMPTY(x)
Definition odr-priv.h:118
#define ODR_STACK_POP(x)
Definition odr-priv.h:117
void odr_seterror(ODR o, int error, int id)
Definition odr.c:118
void odr_printf(ODR o, const char *fmt,...)
Definition odr.c:290
#define ODR_DECODE
Definition odr.h:95
#define OSTACK
Definition odr.h:159
#define ODR_PRINT
Definition odr.h:97
#define OCONLEN
Definition odr.h:160
#define OOTHER
Definition odr.h:156
#define ODR_S_SET
Definition odr.h:117
#define OLENOV
Definition odr.h:161
#define ODR_S_END
Definition odr.h:119
#define ODR_ENCODE
Definition odr.h:96
int odr_constructed_more(ODR o)
Definition odr_cons.c:136
int odr_constructed_end(ODR o)
Definition odr_cons.c:148
void odr_setlenlen(ODR o, int len)
Definition odr_cons.c:19
int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag, const char *name)
Definition odr_cons.c:24
void * odr_malloc(ODR o, size_t size)
Definition odr_mem.c:31
int odr_seek(ODR o, int whence, int offset)
Definition odr_mem.c:117
int odr_write(ODR o, const char *buf, int bytes)
Definition odr_mem.c:98
void odr_prname(ODR o, const char *name)
Definition odr_util.c:18
struct odr_constack * stack_top
Definition odr-priv.h:92
const char * bp
Definition odr-priv.h:85
struct odr_constack * stack_first
Definition odr-priv.h:91
stack for BER constructed items
Definition odr-priv.h:64
int len_offset
Definition odr-priv.h:70
const char * lenb
Definition odr-priv.h:69
struct odr_constack * prev
Definition odr-priv.h:74
const char * name
Definition odr-priv.h:72
int base_offset
Definition odr-priv.h:66
struct odr_constack * next
Definition odr-priv.h:75
const char * base
Definition odr-priv.h:65
Definition odr.h:125
struct Odr_private * op
Definition odr.h:132
int error
Definition odr.h:128
int direction
Definition odr.h:126