YAZ 5.38.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
10
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 if (o->op->stack_depth >= ODR_MAX_STACK)
55 {
56 odr_seterror(o, OSTACK, 30);
57 return 0;
58 }
59 o->op->stack_top->next = (struct odr_constack *)
60 odr_malloc(o, sizeof(*o->op->stack_top));
61 o->op->stack_top->next->prev = o->op->stack_top;
62 o->op->stack_top->next->next = 0;
63
64 o->op->stack_top = o->op->stack_top->next;
65 }
66 else if (!o->op->stack_top)
67 {
68 /* stack empty */
69 if (!o->op->stack_first)
70 {
71 /* first item must be allocated */
72 o->op->stack_first = (struct odr_constack *)
73 odr_malloc(o, sizeof(*o->op->stack_top));
74 o->op->stack_first->prev = 0;
75 o->op->stack_first->next = 0;
76 }
77 o->op->stack_top = o->op->stack_first;
78 assert(o->op->stack_top->prev == 0);
79 }
80 o->op->stack_depth++;
81 o->op->stack_top->lenb = o->op->bp;
83 o->op->stack_top->name = name ? name : "?";
84 if (o->direction == ODR_ENCODE)
85 {
86 static char dummy[sizeof(int)+1];
87
89
90 if (odr_write(o, dummy, lenlen) < 0) /* dummy */
91 {
93 return 0;
94 }
95 }
96 else if (o->direction == ODR_DECODE)
97 {
98 if ((res = ber_declen(o->op->bp, &o->op->stack_top->len,
99 odr_max(o))) < 0)
100 {
101 odr_seterror(o, OOTHER, 31);
102 ODR_STACK_POP(o);
103 return 0;
104 }
105 o->op->stack_top->lenlen = res;
106 o->op->bp += res;
107 if (o->op->stack_top->len > odr_max(o))
108 {
109 odr_seterror(o, OOTHER, 32);
110 ODR_STACK_POP(o);
111 return 0;
112 }
113 }
114 else if (o->direction == ODR_PRINT)
115 {
116 odr_prname(o, name);
117 odr_printf(o, "{\n");
118 o->op->indent++;
119 }
120 else
121 {
122 odr_seterror(o, OOTHER, 33);
123 ODR_STACK_POP(o);
124 return 0;
125 }
126 o->op->stack_top->base = o->op->bp;
128 return 1;
129}
130
132{
133 if (o->error)
134 return 0;
135 if (ODR_STACK_EMPTY(o))
136 return 0;
137 if (o->op->stack_top->len >= 0)
138 return o->op->bp - o->op->stack_top->base < o->op->stack_top->len;
139 else
140 return (!(*o->op->bp == 0 && *(o->op->bp + 1) == 0));
141}
142
144{
145 int res;
146 int pos;
147
148 if (o->error)
149 return 0;
150 if (ODR_STACK_EMPTY(o))
151 {
152 odr_seterror(o, OOTHER, 34);
153 return 0;
154 }
155 switch (o->direction)
156 {
157 case ODR_DECODE:
158 if (o->op->stack_top->len < 0)
159 {
160 if (*o->op->bp++ == 0 && *(o->op->bp++) == 0)
161 {
162 ODR_STACK_POP(o);
163 return 1;
164 }
165 else
166 {
167 odr_seterror(o, OOTHER, 35);
168 return 0;
169 }
170 }
171 else if (o->op->bp - o->op->stack_top->base !=
172 o->op->stack_top->len)
173 {
174 odr_seterror(o, OCONLEN, 36);
175 return 0;
176 }
177 ODR_STACK_POP(o);
178 return 1;
179 case ODR_ENCODE:
180 pos = odr_tell(o);
182 if ((res = ber_enclen(o, pos - o->op->stack_top->base_offset,
183 o->op->stack_top->lenlen, 1)) < 0)
184 {
185 odr_seterror(o, OLENOV, 37);
186 return 0;
187 }
188 odr_seek(o, ODR_S_END, 0);
189 if (res == 0) /* indefinite encoding */
190 {
191 if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0)
192 return 0;
193 }
194 ODR_STACK_POP(o);
195 return 1;
196 case ODR_PRINT:
197 ODR_STACK_POP(o);
198 o->op->indent--;
199 odr_prname(o, 0);
200 odr_printf(o, "}\n");
201 return 1;
202 default:
203 odr_seterror(o, OOTHER, 38);
204 return 0;
205 }
206}
207/*
208 * Local variables:
209 * c-basic-offset: 4
210 * c-file-style: "Stroustrup"
211 * indent-tabs-mode: nil
212 * End:
213 * vim: shiftwidth=4 tabstop=8 expandtab
214 */
215
int ber_declen(const char *buf, int *len, int max)
Definition ber_len.c:94
int ber_enclen(ODR o, int len, int lenlen, int exact)
Definition ber_len.c:31
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
Internal ODR definitions.
#define odr_tell(o)
Definition odr-priv.h:122
#define odr_putc(o, c)
Definition odr-priv.h:130
#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:119
#define ODR_STACK_POP(x)
Definition odr-priv.h:118
void odr_seterror(ODR o, int error, int id)
Definition odr.c:118
void odr_printf(ODR o, const char *fmt,...)
Definition odr.c:289
#define ODR_DECODE
Definition odr.h:95
#define OSTACK
Definition odr.h:159
struct odr * ODR
Definition odr.h:121
#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:131
int odr_constructed_end(ODR o)
Definition odr_cons.c:143
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
int stack_depth
Definition odr-priv.h:93
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
struct Odr_private * op
Definition odr.h:132
int error
Definition odr.h:128
int direction
Definition odr.h:126