for ODR constructed stack.
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: ber_bool.c,v 1.4 2005-06-25 15:46:03 adam Exp $
+ * $Id: ber_bool.c,v 1.5 2005-08-11 14:21:55 adam Exp $
*/
/**
return 0;
if (odr_putc(o, *val) < 0)
return 0;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[val=%d]\n", *val);
-#endif
return 1;
case ODR_DECODE:
if ((res = ber_declen(o->bp, &len, odr_max(o))) < 0)
}
*val = *o->bp;
o->bp++;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[val=%d]\n", *val);
-#endif
return 1;
case ODR_PRINT:
return 1;
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: ber_int.c,v 1.5 2005-06-25 15:46:03 adam Exp $
+ * $Id: ber_int.c,v 1.6 2005-08-11 14:21:55 adam Exp $
*/
/**
return -1;
if (odr_write(o, (unsigned char*) tmp.c + a, len) < 0)
return -1;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[val=%d]", val);
-#endif
return 0;
}
*val = ntohl(tmp.i);
b += len;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[val=%d]", *val);
-#endif
return b - buf;
}
/*
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: ber_len.c,v 1.4 2005-06-25 15:46:03 adam Exp $
+ * $Id: ber_len.c,v 1.5 2005-08-11 14:21:55 adam Exp $
*/
/**
int n = 0;
int lenpos, end;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[len=%d]", len);
-#endif
if (len < 0) /* Indefinite */
{
if (odr_putc(o, 0x80) < 0)
return 0;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[indefinite]");
-#endif
return 0;
}
if (len <= 127 && (lenlen == 1 || !exact)) /* definite short form */
if (*b == 0X80) /* Indefinite */
{
*len = -1;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[len=%d]", *len);
-#endif
return 1;
}
if (!(*b & 0X80)) /* Definite short form */
{
*len = (int) *b;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[len=%d]", *len);
-#endif
return 1;
}
if (*b == 0XFF) /* reserved value */
}
if (*len < 0)
return -2;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[len=%d]", *len);
-#endif
return (b - buf);
}
/*
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: ber_null.c,v 1.4 2005-06-25 15:46:03 adam Exp $
+ * $Id: ber_null.c,v 1.5 2005-08-11 14:21:55 adam Exp $
*/
/**
case ODR_ENCODE:
if (odr_putc(o, 0X00) < 0)
return 0;
-#ifdef ODR_DEBUG
- fprintf(stderr, "[NULL]\n");
-#endif
return 1;
case ODR_DECODE:
if (odr_max(o) < 1)
odr_seterror(o, OPROTO, 12);
return 0;
}
-#ifdef ODR_DEBUG
- fprintf(stderr, "[NULL]\n");
-#endif
return 1;
case ODR_PRINT:
return 1;
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: ber_tag.c,v 1.5 2005-06-25 15:46:03 adam Exp $
+ * $Id: ber_tag.c,v 1.6 2005-08-11 14:21:55 adam Exp $
*/
/**
#include <stdio.h>
#include "odr-priv.h"
-/* ber_tag
+/**
+ * \brief Encode/decode BER tags
+ *
* On encoding:
+ * \verbatim
* if p: write tag. return 1 (success) or -1 (error).
* if !p: return 0.
+ * \endverbatim
* On decoding:
+ * \verbatim
* if tag && zclass match up, advance pointer and return 1. set cons.
* else leave pointer unchanged. Return 0.
- *
- * Should perhaps be odr_tag?
+ * \endverbatim
*/
int ber_tag(ODR o, void *p, int zclass, int tag, int *constructed, int opt,
const char *name)
if (o->direction == ODR_DECODE)
*pp = 0;
o->t_class = -1;
- if (o->op->stackp < 0)
+ if (ODR_STACK_EMPTY(o))
{
odr_seek(o, ODR_S_SET, 0);
o->top = 0;
}
if ((rd = ber_enctag(o, zclass, tag, *constructed)) < 0)
return -1;
-#ifdef ODR_DEBUG
- fprintf(stderr, "\n[class=%d,tag=%d,cons=%d,stackp=%d]", zclass, tag,
- *constructed, o->op->stackp);
-#endif
return 1;
-
case ODR_DECODE:
- if (o->op->stackp > -1 && !odr_constructed_more(o))
+ if (ODR_STACK_NOT_EMPTY(o) && !odr_constructed_more(o))
{
if (!opt)
{
odr_setelement(o, name);
return 0;
}
-#ifdef ODR_DEBUG
- fprintf(stderr,
- "\n[class=%d,tag=%d,cons=%d,stackp=%d]",
- odr_ber_tag->lclass, odr_ber_tag->ltag,
- odr_ber_tag->lcons, o->op->stackp);
-#endif
}
if (zclass == odr_ber_tag->lclass && tag == odr_ber_tag->ltag)
{
}
}
-/* ber_enctag
- * BER-encode a zclass/tag/constructed package (identifier octets). Return
- * number of bytes encoded, or -1 if out of bounds.
+/**
+ * \brief BER-encode a zclass/tag/constructed package (identifier octets).
+ *
+ * Return number of bytes encoded, or -1 if out of bounds.
*/
int ber_enctag(ODR o, int zclass, int tag, int constructed)
{
}
}
-/* ber_dectag
- * Decode BER identifier octets. Return number of bytes read or -1 for error.
+/**
+ * \brief Decodes BER identifier octets.
+ *
+ * Returns number of bytes read or -1 for error.
*/
int ber_dectag(const unsigned char *b, int *zclass, int *tag,
int *constructed, int max)
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*
- * $Id: odr-priv.h,v 1.6 2005-06-25 15:46:04 adam Exp $
+ * $Id: odr-priv.h,v 1.7 2005-08-11 14:21:55 adam Exp $
*/
/**
#include <yaz/odr.h>
#include <yaz/yaz-util.h>
-struct Odr_ber_tag { /* used to be statics in ber_tag... */
+/** \brief Utility structure used by ber_tag */
+struct Odr_ber_tag {
int lclass;
int ltag;
int br;
#define odr_max(o) ((o)->size - ((o)->bp - (o)->buf))
#define odr_offset(o) ((o)->bp - (o)->buf)
-typedef struct odr_constack
+/**
+ * \brief stack for BER constructed items
+ *
+ * data structure for con stack.. a little peculiar. Since we can't
+ * deallocate memory we reuse stack items (popped items gets reused)
+ *
+ *\verbatim
+ * +---+ +---+ +---+ +---+
+ * NULL -|p n|-----|p n|-----|p n|-----|p n|-- NULL
+ * +---+ +---+ +---+ +---+
+ * | |
+ * stack_first stack_top reused item
+ *\endverbatim
+ */
+struct odr_constack
{
- const unsigned char *base; /* starting point of data */
+ const unsigned char *base; /** starting point of data */
int base_offset;
- int len; /* length of data, if known, else -1
+ int len; /** length of data, if known, else -1
(decoding only) */
- const unsigned char *lenb; /* where to encode length */
+ const unsigned char *lenb; /** where to encode length */
int len_offset;
- int lenlen; /* length of length-field */
-} odr_constack;
+ int lenlen; /** length of length-field */
+ const char *name; /** name of stack entry */
+
+ struct odr_constack *prev; /** pointer back in stack */
+ struct odr_constack *next; /** pointer forward */
+};
+
+#define ODR_MAX_STACK 10000
+/**
+ * \brief ODR private data
+ */
struct Odr_private {
- /* stack for constructed types */
-#define ODR_MAX_STACK 50
- int stackp; /* top of stack (-1 == initial state) */
- odr_constack stack[ODR_MAX_STACK];
- const char *stack_names[1 + ODR_MAX_STACK];
+ /* stack for constructed types (we above) */
+ struct odr_constack *stack_first; /** first member of allocated stack */
+ struct odr_constack *stack_top; /** top of stack */
+
+
+ const char **tmp_names_buf; /** array returned by odr_get_element_path */
+ int tmp_names_sz; /** size of tmp_names_buf */
+
+ struct Odr_ber_tag odr_ber_tag; /** used by ber_tag */
- struct Odr_ber_tag odr_ber_tag;
yaz_iconv_t iconv_handle;
int error_id;
char element[80];
void (*stream_close)(void *handle);
};
+#define ODR_STACK_POP(x) (x)->op->stack_top = (x)->op->stack_top->prev
+#define ODR_STACK_EMPTY(x) (!(x)->op->stack_top)
+#define ODR_STACK_NOT_EMPTY(x) ((x)->op->stack_top)
+
/* Private macro.
* write a single character at the current position - grow buffer if
* necessary.
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: odr.c,v 1.12 2005-06-25 15:46:04 adam Exp $
+ * $Id: odr.c,v 1.13 2005-08-11 14:21:55 adam Exp $
*
*/
#include <config.h>
#endif
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
void odr_perror(ODR o, const char *message)
{
const char *e = odr_getelement(o);
+ const char **element_path = odr_get_element_path(o);
int err, x;
err = odr_geterrorx(o, &x);
fprintf(stderr, "%s: %s (code %d:%d)", message, odr_errlist[err], err, x);
if (e && *e)
- fprintf (stderr, " element %s", e);
+ fprintf(stderr, " element %s", e);
+
fprintf(stderr, "\n");
+ if (element_path)
+ {
+ fprintf(stderr, "Element path:");
+ while (*element_path)
+ fprintf(stderr, " %s", *element_path++);
+ fprintf(stderr, "\n");
+ }
}
int odr_geterror(ODR o)
const char **odr_get_element_path(ODR o)
{
- return o->op->stack_names;
+ int cur_sz = 0;
+ struct odr_constack *st;
+
+ for (st = o->op->stack_top; st; st = st->prev)
+ cur_sz++;
+ if (o->op->tmp_names_sz < cur_sz + 1)
+ {
+ o->op->tmp_names_sz = 2 * cur_sz + 5;
+ o->op->tmp_names_buf = (const char **)
+ odr_malloc(o, o->op->tmp_names_sz * sizeof(char*));
+ }
+ o->op->tmp_names_buf[cur_sz] = 0;
+ for (st = o->op->stack_top; st; st = st->prev)
+ {
+ cur_sz--;
+ o->op->tmp_names_buf[cur_sz] = st->name;
+ }
+ assert(cur_sz == 0);
+ return o->op->tmp_names_buf;
}
void odr_seterror(ODR o, int error, int id)
o->t_class = -1;
o->t_tag = -1;
o->indent = 0;
- o->op->stackp = -1;
+ o->op->stack_first = 0;
+ o->op->stack_top = 0;
+ o->op->tmp_names_sz = 0;
+ o->op->tmp_names_buf = 0;
nmem_reset(o->mem);
o->choice_bias = -1;
o->lenlen = 1;
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: odr_choice.c,v 1.5 2005-06-25 15:46:04 adam Exp $
+ * $Id: odr_choice.c,v 1.6 2005-08-11 14:21:55 adam Exp $
*/
/**
{
if (o->direction == ODR_DECODE && cl < 0)
{
- if (o->op->stackp > -1 && !odr_constructed_more(o))
+ if (o->op->stack_top && !odr_constructed_more(o))
return 0;
if (ber_dectag(o->bp, &cl, &tg, &cn, odr_max(o)) <= 0)
return 0;
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: odr_cons.c,v 1.6 2005-06-25 15:46:04 adam Exp $
+ * $Id: odr_cons.c,v 1.7 2005-08-11 14:21:55 adam Exp $
*
*/
#include <config.h>
#endif
+#include <assert.h>
+
#include "odr-priv.h"
void odr_setlenlen(ODR o, int len)
o->lenlen = len;
}
-int odr_constructed_begin(ODR o, void *p, int zclass, int tag,
+int odr_constructed_begin(ODR o, void *xxp, int zclass, int tag,
const char *name)
{
int res;
o->t_class = zclass;
o->t_tag = tag;
}
- if ((res = ber_tag(o, p, o->t_class, o->t_tag, &cons, 1, name)) < 0)
+ if ((res = ber_tag(o, xxp, o->t_class, o->t_tag, &cons, 1, name)) < 0)
return 0;
if (!res || !cons)
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->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];
- o->op->stack[o->op->stackp].lenlen = lenlen;
+ o->op->stack_top->lenlen = lenlen;
if (odr_write(o, dummy, lenlen) < 0) /* dummy */
{
- o->op->stack_names[o->op->stackp] = 0;
- --(o->op->stackp);
+ 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->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);
+ ODR_STACK_POP(o);
return 0;
}
- o->op->stack[o->op->stackp].lenlen = res;
+ o->op->stack_top->lenlen = res;
o->bp += res;
- if (o->op->stack[o->op->stackp].len > odr_max(o))
+ 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);
+ ODR_STACK_POP(o);
return 0;
}
}
else
{
odr_seterror(o, OOTHER, 33);
- o->op->stack_names[o->op->stackp] = 0;
- --(o->op->stackp);
+ 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->bp;
+ o->op->stack_top->base_offset = odr_tell(o);
return 1;
}
{
if (o->error)
return 0;
- if (o->op->stackp < 0)
+ if (ODR_STACK_EMPTY(o))
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;
+ if (o->op->stack_top->len >= 0)
+ return o->bp - o->op->stack_top->base < o->op->stack_top->len;
else
return (!(*o->bp == 0 && *(o->bp + 1) == 0));
}
if (o->error)
return 0;
- if (o->op->stackp < 0)
+ if (ODR_STACK_EMPTY(o))
{
odr_seterror(o, OOTHER, 34);
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)
{
- o->op->stackp--;
- return 1;
+ ODR_STACK_POP(o);
+ return 1;
}
else
{
return 0;
}
}
- else if (o->bp - o->op->stack[o->op->stackp].base !=
- o->op->stack[o->op->stackp].len)
+ else if (o->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;
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--;
+ ODR_STACK_POP(o);
o->indent--;
odr_prname(o, 0);
odr_printf(o, "}\n");
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: odr_mem.c,v 1.5 2005-06-25 15:46:04 adam Exp $
+ * $Id: odr_mem.c,v 1.6 2005-08-11 14:21:55 adam Exp $
*/
/**
* \file odr_mem.c
else if (!b->size && !(b->buf = (unsigned char *)
xmalloc(b->size = togrow)))
abort();
-#ifdef ODR_DEBUG
- fprintf(stderr, "New size for encode_buffer: %d\n", b->size);
-#endif
return 0;
}
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: odr_seq.c,v 1.4 2005-06-25 15:46:04 adam Exp $
+ * $Id: odr_seq.c,v 1.5 2005-08-11 14:21:55 adam Exp $
*/
/**
* \file odr_seq.c
}
break;
case ODR_ENCODE: case ODR_PRINT:
-#ifdef ODR_DEBUG
- fprintf(stderr, "[seqof: num=%d]", *num);
-#endif
for (i = 0; i < *num; i++)
{
-#ifdef ODR_DEBUG
- fprintf(stderr, "[seqof: elem #%d]", i);
-#endif
if (!(*type)(o, *pp + i, 0, 0))
return 0;
}
* Copyright (C) 1995-2005, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: odr_tag.c,v 1.4 2005-06-25 15:46:04 adam Exp $
+ * $Id: odr_tag.c,v 1.5 2005-08-11 14:21:55 adam Exp $
*/
/**
* \file odr_tag.c
odr_seterror(o, OOTHER, 48);
return 0;
}
- if (o->op->stackp > -1 && !odr_constructed_more(o))
+ if (ODR_STACK_NOT_EMPTY(o) && !odr_constructed_more(o))
return 0;
if (ber_dectag(o->bp, zclass, tag, cons, odr_max(o)) <= 0)
{