2 * Copyright (C) 1995-2007, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: odr_cons.c,v 1.9 2007-03-19 21:08:13 adam Exp $
11 * \brief Implements ODR constructed codec.
22 void odr_setlenlen(ODR o, int len)
27 int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag,
32 int lenlen = o->op->lenlen;
36 o->op->lenlen = 1; /* reset lenlen */
37 if (o->op->t_class < 0)
39 o->op->t_class = zclass;
42 res = ber_tag(o, xxp, o->op->t_class, o->op->t_tag, &cons, 1, name);
48 /* push the odr_constack */
49 if (o->op->stack_top && o->op->stack_top->next)
52 o->op->stack_top = o->op->stack_top->next;
54 else if (o->op->stack_top && !o->op->stack_top->next)
56 /* must allocate new entry (not first) */
58 struct odr_constack *st;
59 /* check size first */
60 for (st = o->op->stack_top; st; st = st->prev)
63 if (sz >= ODR_MAX_STACK)
65 odr_seterror(o, OSTACK, 30);
68 o->op->stack_top->next = (struct odr_constack *)
69 odr_malloc(o, sizeof(*o->op->stack_top));
70 o->op->stack_top->next->prev = o->op->stack_top;
71 o->op->stack_top->next->next = 0;
73 o->op->stack_top = o->op->stack_top->next;
75 else if (!o->op->stack_top)
78 if (!o->op->stack_first)
80 /* first item must be allocated */
81 o->op->stack_first = (struct odr_constack *)
82 odr_malloc(o, sizeof(*o->op->stack_top));
83 o->op->stack_first->prev = 0;
84 o->op->stack_first->next = 0;
86 o->op->stack_top = o->op->stack_first;
87 assert(o->op->stack_top->prev == 0);
89 o->op->stack_top->lenb = o->bp;
90 o->op->stack_top->len_offset = odr_tell(o);
91 o->op->stack_top->name = name ? name : "?";
92 if (o->direction == ODR_ENCODE)
94 static unsigned char dummy[sizeof(int)+1];
96 o->op->stack_top->lenlen = lenlen;
98 if (odr_write(o, dummy, lenlen) < 0) /* dummy */
104 else if (o->direction == ODR_DECODE)
106 if ((res = ber_declen(o->bp, &o->op->stack_top->len,
109 odr_seterror(o, OOTHER, 31);
113 o->op->stack_top->lenlen = res;
115 if (o->op->stack_top->len > odr_max(o))
117 odr_seterror(o, OOTHER, 32);
122 else if (o->direction == ODR_PRINT)
125 odr_printf(o, "{\n");
130 odr_seterror(o, OOTHER, 33);
134 o->op->stack_top->base = o->bp;
135 o->op->stack_top->base_offset = odr_tell(o);
139 int odr_constructed_more(ODR o)
143 if (ODR_STACK_EMPTY(o))
145 if (o->op->stack_top->len >= 0)
146 return o->bp - o->op->stack_top->base < o->op->stack_top->len;
148 return (!(*o->bp == 0 && *(o->bp + 1) == 0));
151 int odr_constructed_end(ODR o)
158 if (ODR_STACK_EMPTY(o))
160 odr_seterror(o, OOTHER, 34);
163 switch (o->direction)
166 if (o->op->stack_top->len < 0)
168 if (*o->bp++ == 0 && *(o->bp++) == 0)
175 odr_seterror(o, OOTHER, 35);
179 else if (o->bp - o->op->stack_top->base !=
180 o->op->stack_top->len)
182 odr_seterror(o, OCONLEN, 36);
189 odr_seek(o, ODR_S_SET, o->op->stack_top->len_offset);
190 if ((res = ber_enclen(o, pos - o->op->stack_top->base_offset,
191 o->op->stack_top->lenlen, 1)) < 0)
193 odr_seterror(o, OLENOV, 37);
196 odr_seek(o, ODR_S_END, 0);
197 if (res == 0) /* indefinite encoding */
199 if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0)
208 odr_printf(o, "}\n");
211 odr_seterror(o, OOTHER, 38);
218 * indent-tabs-mode: nil
220 * vim: shiftwidth=4 tabstop=8 expandtab