X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fodr_cons.c;h=7bf368adb254edf90674bce749f7fd81a5a82d0b;hp=dce204def8d3bb2d0cef904704d5fc9916710eb5;hb=5c1eb188e9cf6f0dd2e435a1f81938f258515edb;hpb=05c274ef315384faafcc5900c17468f0ea2474e6 diff --git a/src/odr_cons.c b/src/odr_cons.c index dce204d..7bf368a 100644 --- a/src/odr_cons.c +++ b/src/odr_cons.c @@ -1,9 +1,6 @@ -/* - * Copyright (c) 1995-2004, Index Data +/* This file is part of the YAZ toolkit. + * Copyright (C) Index Data * See the file LICENSE for details. - * - * $Id: odr_cons.c,v 1.4 2004-10-15 00:19:00 adam Exp $ - * */ /** @@ -15,106 +12,137 @@ #include #endif +#include + #include "odr-priv.h" void odr_setlenlen(ODR o, int len) { - o->lenlen = len; + o->op->lenlen = len; } -int odr_constructed_begin(ODR o, void *p, int zclass, int tag, - const char *name) +int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag, + const char *name) { int res; int cons = 1; - int lenlen = o->lenlen; + int lenlen = o->op->lenlen; if (o->error) - return 0; - o->lenlen = 1; /* reset lenlen */ - if (o->t_class < 0) + return 0; + o->op->lenlen = 1; /* reset lenlen */ + if (o->op->t_class < 0) { - o->t_class = zclass; - o->t_tag = tag; + o->op->t_class = zclass; + o->op->t_tag = tag; } - if ((res = ber_tag(o, p, o->t_class, o->t_tag, &cons, 1, name)) < 0) - return 0; + res = ber_tag(o, xxp, o->op->t_class, o->op->t_tag, &cons, 1, name); + if (res < 0) + return 0; if (!res || !cons) - return 0; + return 0; - if (o->op->stackp == ODR_MAX_STACK - 1) + /* push the odr_constack */ + if (o->op->stack_top && o->op->stack_top->next) { - odr_seterror(o, OSTACK, 30); - return 0; + /* reuse old entry */ + o->op->stack_top = o->op->stack_top->next; } - o->op->stack[++(o->op->stackp)].lenb = o->bp; - o->op->stack[o->op->stackp].len_offset = odr_tell(o); - o->op->stack_names[o->op->stackp] = name ? name : "?"; - o->op->stack_names[o->op->stackp + 1] = 0; -#ifdef ODR_DEBUG - fprintf(stderr, "[cons_begin(%d)]", o->op->stackp); -#endif + else if (o->op->stack_top && !o->op->stack_top->next) + { + /* must allocate new entry (not first) */ + int sz = 0; + struct odr_constack *st; + /* check size first */ + for (st = o->op->stack_top; st; st = st->prev) + sz++; + + if (sz >= ODR_MAX_STACK) + { + odr_seterror(o, OSTACK, 30); + return 0; + } + o->op->stack_top->next = (struct odr_constack *) + odr_malloc(o, sizeof(*o->op->stack_top)); + o->op->stack_top->next->prev = o->op->stack_top; + o->op->stack_top->next->next = 0; + + o->op->stack_top = o->op->stack_top->next; + } + else if (!o->op->stack_top) + { + /* stack empty */ + if (!o->op->stack_first) + { + /* first item must be allocated */ + o->op->stack_first = (struct odr_constack *) + odr_malloc(o, sizeof(*o->op->stack_top)); + o->op->stack_first->prev = 0; + o->op->stack_first->next = 0; + } + o->op->stack_top = o->op->stack_first; + assert(o->op->stack_top->prev == 0); + } + o->op->stack_top->lenb = o->op->bp; + o->op->stack_top->len_offset = odr_tell(o); + o->op->stack_top->name = name ? name : "?"; if (o->direction == ODR_ENCODE) { - static unsigned char dummy[sizeof(int)+1]; + static char dummy[sizeof(int)+1]; - o->op->stack[o->op->stackp].lenlen = lenlen; + o->op->stack_top->lenlen = lenlen; - if (odr_write(o, dummy, lenlen) < 0) /* dummy */ + if (odr_write(o, dummy, lenlen) < 0) /* dummy */ { - o->op->stack_names[o->op->stackp] = 0; - --(o->op->stackp); - return 0; + ODR_STACK_POP(o); + return 0; } } else if (o->direction == ODR_DECODE) { - if ((res = ber_declen(o->bp, &o->op->stack[o->op->stackp].len, + if ((res = ber_declen(o->op->bp, &o->op->stack_top->len, odr_max(o))) < 0) { odr_seterror(o, OOTHER, 31); - o->op->stack_names[o->op->stackp] = 0; - --(o->op->stackp); - return 0; + ODR_STACK_POP(o); + return 0; } - o->op->stack[o->op->stackp].lenlen = res; - o->bp += res; - if (o->op->stack[o->op->stackp].len > odr_max(o)) + o->op->stack_top->lenlen = res; + o->op->bp += res; + if (o->op->stack_top->len > odr_max(o)) { odr_seterror(o, OOTHER, 32); - o->op->stack_names[o->op->stackp] = 0; - --(o->op->stackp); - return 0; + ODR_STACK_POP(o); + return 0; } } else if (o->direction == ODR_PRINT) { - odr_prname(o, name); - odr_printf(o, "{\n"); - o->indent++; + odr_prname(o, name); + odr_printf(o, "{\n"); + o->op->indent++; } else { odr_seterror(o, OOTHER, 33); - o->op->stack_names[o->op->stackp] = 0; - --(o->op->stackp); - return 0; + ODR_STACK_POP(o); + return 0; } - o->op->stack[o->op->stackp].base = o->bp; - o->op->stack[o->op->stackp].base_offset = odr_tell(o); + o->op->stack_top->base = o->op->bp; + o->op->stack_top->base_offset = odr_tell(o); return 1; } int odr_constructed_more(ODR o) { if (o->error) - return 0; - if (o->op->stackp < 0) - return 0; - if (o->op->stack[o->op->stackp].len >= 0) - return o->bp - o->op->stack[o->op->stackp].base < o->op->stack[o->op->stackp].len; + return 0; + if (ODR_STACK_EMPTY(o)) + return 0; + if (o->op->stack_top->len >= 0) + return o->op->bp - o->op->stack_top->base < o->op->stack_top->len; else - return (!(*o->bp == 0 && *(o->bp + 1) == 0)); + return (!(*o->op->bp == 0 && *(o->op->bp + 1) == 0)); } int odr_constructed_end(ODR o) @@ -123,22 +151,21 @@ int odr_constructed_end(ODR o) int pos; if (o->error) - return 0; - if (o->op->stackp < 0) + return 0; + if (ODR_STACK_EMPTY(o)) { odr_seterror(o, OOTHER, 34); - return 0; + return 0; } - o->op->stack_names[o->op->stackp] = 0; switch (o->direction) { case ODR_DECODE: - if (o->op->stack[o->op->stackp].len < 0) + if (o->op->stack_top->len < 0) { - if (*o->bp++ == 0 && *(o->bp++) == 0) + if (*o->op->bp++ == 0 && *(o->op->bp++) == 0) { - o->op->stackp--; - return 1; + ODR_STACK_POP(o); + return 1; } else { @@ -146,19 +173,19 @@ int odr_constructed_end(ODR o) return 0; } } - else if (o->bp - o->op->stack[o->op->stackp].base != - o->op->stack[o->op->stackp].len) + else if (o->op->bp - o->op->stack_top->base != + o->op->stack_top->len) { odr_seterror(o, OCONLEN, 36); return 0; } - o->op->stackp--; + ODR_STACK_POP(o); return 1; case ODR_ENCODE: pos = odr_tell(o); - odr_seek(o, ODR_S_SET, o->op->stack[o->op->stackp].len_offset); - if ((res = ber_enclen(o, pos - o->op->stack[o->op->stackp].base_offset, - o->op->stack[o->op->stackp].lenlen, 1)) < 0) + odr_seek(o, ODR_S_SET, o->op->stack_top->len_offset); + if ((res = ber_enclen(o, pos - o->op->stack_top->base_offset, + o->op->stack_top->lenlen, 1)) < 0) { odr_seterror(o, OLENOV, 37); return 0; @@ -166,23 +193,14 @@ int odr_constructed_end(ODR o) odr_seek(o, ODR_S_END, 0); if (res == 0) /* indefinite encoding */ { -#ifdef ODR_DEBUG - fprintf(stderr, "[cons_end(%d): indefinite]", o->op->stackp); -#endif if (odr_putc(o, 0) < 0 || odr_putc(o, 0) < 0) return 0; } -#ifdef ODR_DEBUG - else - { - fprintf(stderr, "[cons_end(%d): definite]", o->op->stackp); - } -#endif - o->op->stackp--; + ODR_STACK_POP(o); return 1; case ODR_PRINT: - o->op->stackp--; - o->indent--; + ODR_STACK_POP(o); + o->op->indent--; odr_prname(o, 0); odr_printf(o, "}\n"); return 1; @@ -191,3 +209,12 @@ int odr_constructed_end(ODR o) return 0; } } +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ +