Add odr_setprint_noclose
[yaz-moved-to-github.git] / src / odr.c
index e370929..9cbac0d 100644 (file)
--- a/src/odr.c
+++ b/src/odr.c
@@ -1,9 +1,6 @@
-/*
- * Copyright (C) 1995-2005, Index Data ApS
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
- *
- * $Id: odr.c,v 1.11 2005-01-15 19:47:14 adam Exp $
- *
  */
 
 /**
 #include <config.h>
 #endif
 
+#include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 
 #include <yaz/xmalloc.h>
 #include <yaz/log.h>
+#include <yaz/snprintf.h>
 #include "odr-priv.h"
 
-static int log_level=0;
-static int log_level_initialized=0;
+static int log_level = 0;
+static int log_level_initialized = 0;
 
 Odr_null *ODR_NULLVAL = (Odr_null *) "NULL";  /* the presence of a null value */
 
-Odr_null *odr_nullval (void)
+Odr_null *odr_nullval(void)
 {
     return ODR_NULLVAL;
 }
@@ -58,13 +57,22 @@ char *odr_errmsg(int n)
 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)
@@ -86,7 +94,25 @@ const char *odr_getelement(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)
@@ -106,34 +132,25 @@ void odr_setelement(ODR o, const char *element)
 }
 
 void odr_FILE_write(ODR o, void *handle, int type,
-                   const char *buf, int len)
+                    const char *buf, int len)
 {
     int i;
-#if 0
-    if (type  == ODR_OCTETSTRING)
-    {
-       const char **stack_names = odr_get_element_path(o);
-       for (i = 0; stack_names[i]; i++)
-           fprintf((FILE*) handle, "[%s]", stack_names[i]);
-       fputs("\n", (FILE*) handle);
-    }
-#endif
-    for (i = 0; i<len; i++)
+    for (i = 0; i < len; i++)
     {
-       unsigned c = ((const unsigned char *) buf)[i];
-       if (i == 2000 && len > 3100)
-       {
-           fputs(" ..... ", (FILE*) handle);
-               i = len - 1000;
-       }
-       if (strchr("\r\n\f\t", c) || (c >= ' ' && c <= 126))
-           putc(c, (FILE*) handle);
-       else
-       {
-           char x[5];
-           sprintf(x, "\\X%02X", c);
-           fputs(x, (FILE*) handle);
-       }
+        unsigned c = ((const unsigned char *) buf)[i];
+        if (i == 20000 && len > 31000)
+        {
+            fputs(" ..... ", (FILE*) handle);
+                i = len - 1000;
+        }
+        if (strchr("\r\n\f\t", c) || (c >= ' ' && c <= 126))
+            putc(c, (FILE*) handle);
+        else
+        {
+            char x[5];
+            sprintf(x, "\\X%02X", c);
+            fputs(x, (FILE*) handle);
+        }
     }
 }
 
@@ -141,7 +158,7 @@ void odr_FILE_close(void *handle)
 {
     FILE *f = (FILE *) handle;
     if (f && f != stderr && f != stdout)
-       fclose(f);
+        fclose(f);
 }
 
 void odr_setprint(ODR o, FILE *file)
@@ -149,13 +166,18 @@ void odr_setprint(ODR o, FILE *file)
     odr_set_stream(o, file, odr_FILE_write, odr_FILE_close);
 }
 
+void odr_setprint_noclose(ODR o, FILE *file)
+{
+    odr_set_stream(o, file, odr_FILE_write, 0);
+}
+
 void odr_set_stream(ODR o, void *handle,
-                   void (*stream_write)(ODR o, 
-                                        void *handle, int type,
-                                        const char *buf, int len),
-                   void (*stream_close)(void *handle))
+                    void (*stream_write)(ODR o,
+                                         void *handle, int type,
+                                         const char *buf, int len),
+                    void (*stream_close)(void *handle))
 {
-    o->print = (FILE*) handle;
+    o->op->print = (FILE*) handle;
     o->op->stream_write = stream_write;
     o->op->stream_close = stream_close;
 }
@@ -167,7 +189,7 @@ int odr_set_charset(ODR o, const char *to, const char *from)
     o->op->iconv_handle = 0;
     if (to && from)
     {
-        o->op->iconv_handle = yaz_iconv_open (to, from);
+        o->op->iconv_handle = yaz_iconv_open(to, from);
         if (o->op->iconv_handle == 0)
             return -1;
     }
@@ -180,24 +202,24 @@ ODR odr_createmem(int direction)
     ODR o;
     if (!log_level_initialized)
     {
-        log_level=yaz_log_module_level("odr");
-        log_level_initialized=1;
+        log_level = yaz_log_module_level("odr");
+        log_level_initialized = 1;
     }
 
-    if (!(o = (ODR)xmalloc(sizeof(*o))))
+    if (!(o = (ODR) xmalloc(sizeof(*o))))
         return 0;
+    o->op = (struct Odr_private *) xmalloc(sizeof(*o->op));
     o->direction = direction;
-    o->buf = 0;
-    o->size = o->pos = o->top = 0;
-    o->can_grow = 1;
+    o->op->buf = 0;
+    o->op->size = o->op->pos = o->op->top = 0;
+    o->op->can_grow = 1;
     o->mem = nmem_create();
-    o->enable_bias = 1;
-    o->op = (struct Odr_private *) xmalloc (sizeof(*o->op));
+    o->op->enable_bias = 1;
     o->op->odr_ber_tag.lclass = -1;
     o->op->iconv_handle = 0;
-    odr_setprint(o, stderr);
+    odr_setprint_noclose(o, stderr);
     odr_reset(o);
-    yaz_log (log_level, "odr_createmem dir=%d o=%p", direction, o);
+    yaz_log(log_level, "odr_createmem dir=%d o=%p", direction, o);
     return o;
 }
 
@@ -205,57 +227,64 @@ void odr_reset(ODR o)
 {
     if (!log_level_initialized)
     {
-        log_level=yaz_log_module_level("odr");
-        log_level_initialized=1;
+        log_level = yaz_log_module_level("odr");
+        log_level_initialized = 1;
     }
 
     odr_seterror(o, ONONE, 0);
-    o->bp = o->buf;
+    o->op->bp = o->op->buf;
     odr_seek(o, ODR_S_SET, 0);
-    o->top = 0;
-    o->t_class = -1;
-    o->t_tag = -1;
-    o->indent = 0;
-    o->op->stackp = -1;
+    o->op->top = 0;
+    o->op->t_class = -1;
+    o->op->t_tag = -1;
+    o->op->indent = 0;
+    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;
+    o->op->choice_bias = -1;
+    o->op->lenlen = 1;
     if (o->op->iconv_handle != 0)
         yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
-    yaz_log (log_level, "odr_reset o=%p", o);
+    yaz_log(log_level, "odr_reset o=%p", o);
 }
-    
+
 void odr_destroy(ODR o)
 {
     nmem_destroy(o->mem);
-    if (o->buf && o->can_grow)
-       xfree(o->buf);
+    if (o->op->buf && o->op->can_grow)
+       xfree(o->op->buf);
     if (o->op->stream_close)
-       o->op->stream_close(o->print);
+        o->op->stream_close(o->op->print);
     if (o->op->iconv_handle != 0)
-        yaz_iconv_close (o->op->iconv_handle);
+        yaz_iconv_close(o->op->iconv_handle);
     xfree(o->op);
     xfree(o);
-    yaz_log (log_level, "odr_destroy o=%p", o);
+    yaz_log(log_level, "odr_destroy o=%p", o);
 }
 
 void odr_setbuf(ODR o, char *buf, int len, int can_grow)
 {
     odr_seterror(o, ONONE, 0);
-    o->bp = (unsigned char *) buf;
-
-    o->buf = (unsigned char *) buf;
-    o->can_grow = can_grow;
-    o->top = o->pos = 0;
-    o->size = len;
+    o->op->bp = buf;
+    o->op->buf = buf;
+    o->op->can_grow = can_grow;
+    o->op->top = o->op->pos = 0;
+    o->op->size = len;
 }
 
 char *odr_getbuf(ODR o, int *len, int *size)
 {
-    *len = o->top;
+    *len = o->op->top;
     if (size)
-        *size = o->size;
-    return (char*) o->buf;
+        *size = o->op->size;
+    return o->op->buf;
+}
+
+int odr_offset(ODR o)
+{
+    return o->op->bp - o->op->buf;
 }
 
 void odr_printf(ODR o, const char *fmt, ...)
@@ -264,15 +293,16 @@ void odr_printf(ODR o, const char *fmt, ...)
     char buf[4096];
 
     va_start(ap, fmt);
-#ifdef WIN32
-    _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
-#else
-#if HAVE_VSNPRINTF
-    vsnprintf(buf, sizeof(buf), fmt, ap);
-#else
-    vsprintf(buf, fmt, ap);
-#endif
-#endif
-    o->op->stream_write(o, o->print, ODR_VISIBLESTRING, buf, strlen(buf));
+    yaz_vsnprintf(buf, sizeof(buf), fmt, ap);
+    o->op->stream_write(o, o->op->print, ODR_VISIBLESTRING, buf, strlen(buf));
     va_end(ap);
 }
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+