Reworked odr_set_stream a bit, so that write handler now takes a
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 13 Aug 2004 07:30:05 +0000 (07:30 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 13 Aug 2004 07:30:05 +0000 (07:30 +0000)
buffer and a length + ODR handle. Also implement odr_get_element_path
that returns current path of elements.

NEWS
doc/odr.xml
include/yaz/odr.h
src/odr-priv.h
src/odr.c
src/odr_cons.c
src/odr_oct.c
src/odr_oid.c

diff --git a/NEWS b/NEWS
index eecd347..034d803 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,12 +1,16 @@
 Possible compatibility problems with earlier versions marked with '*'.
 
-Fixed bug in CCL parser where truncation char was not removed when
-truncation=both was in effect.
+Added odr_get_element_path which current element path for an ODR stream.
+This utility may be useful in error handling or user-defined ODR_PRINT
+stream.
 
-Added odr_set_stream which is is a more generic to odr_setprint.
-odr_set_stream takes a stream handle, pointer to puts function and
-pointer to close function. The close function - if non-NULL - will be
-called during odr_destroy.
+Added ODR_PRINT utility odr_set_stream which is is a more generic
+alternative to odr_setprint. odr_set_stream takes a stream handle, pointer
+to a write function and pointer to close function. The close function - if
+non-NULL - will be called during odr_destroy.
+
+Fixed bug in CCL parser where truncation char was not removed from
+right side when truncation=both was in effect.
 
 Fixed CQL parser to use unsigned chars (occurred on MS .NET).
 
index 4f6ea57..2a5fd7d 100644 (file)
@@ -1,4 +1,4 @@
-<!-- $Id: odr.xml,v 1.13 2004-08-11 12:47:35 adam Exp $ -->
+<!-- $Id: odr.xml,v 1.14 2004-08-13 07:30:06 adam Exp $ -->
  <chapter id="odr"><title>The ODR Module</title>
   
   <sect1 id="odr.introduction"><title>Introduction</title>
@@ -369,16 +369,42 @@ void do_nothing_useful(int value)
      another file), by using the more generic mechanism:
      <synopsis>
       void odr_set_stream(ODR o, void *handle,
-                         void (*stream_puts)(void *handle, const char *strz),
+                         void (*stream_write)(ODR o, void *handle, int type,
+                                              const char *buf, int len),
                          void (*stream_close)(void *handle));
      </synopsis>
      Here the user provides an opaque handle and two handlers,
-     <replaceable>stream_puts</replaceable> for printing,
+     <replaceable>stream_write</replaceable> for writing,
      and <replaceable>stream_close</replaceable> which is supposed
      to close/free resources associated with handle. 
      The <replaceable>stream_close</replaceable> handler is optional and
      if NULL for the function is provided, it will not be invoked.
+     The <replaceable>stream_write</replaceable> takes the ODR handle
+     as parameter, the user defined handle, a type 
+     <literal>ODR_OCTETSTRING</literal>, <literal>ODR_VISIBLESTRING</literal>
+     which indicates the type of contents is being written.
     </para>
+    <para>
+     Another utility useful for diagnostics (error handling) or as
+     part of the printing facilities is:
+     <synopsis>
+      const char **odr_get_element_path(ODR o);
+     </synopsis>
+     which returns a list of current elements that ODR deals with at the 
+     moment. For the returned array, say <literal>ar</literal>, 
+     <literal>ar[0]</literal> is the top level element,
+     <literal>ar[n]</literal> is the last. The last element has the
+     property that <literal>ar[n+1] == NULL</literal>.
+    </para>
+    <example>
+     <title>Element Path for record</title>
+     <para>
+      For a database record part of a PresentResponse the
+      array returned by <function>odr_get_element</function>
+      is <literal>presentResponse</literal>, <literal>databaseOrSurDiagnostics</literal>, <literal>?</literal>, <literal>record</literal>, <literal>?</literal>, <literal>databaseRecord</literal> . The question mark appears due to 
+      unnamed constructions.
+     </para>
+     </example>
    </sect2>
    <sect2><title>Diagnostics</title>
 
index 3dd1478..9c4f658 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995-2003, Index Data.
+ * Copyright (c) 1995-2004, Index Data.
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation, in whole or in part, for any purpose, is hereby granted,
@@ -23,7 +23,7 @@
  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  * OF THIS SOFTWARE.
  *
- * $Id: odr.h,v 1.15 2004-08-11 12:15:38 adam Exp $
+ * $Id: odr.h,v 1.16 2004-08-13 07:30:06 adam Exp $
  */
 
 #ifndef ODR_H
@@ -106,17 +106,6 @@ typedef struct odr_bitmask
 
 typedef int Odr_oid;   /* terminate by -1 */
 
-typedef struct odr_constack
-{
-    const unsigned char *base;   /* starting point of data */
-    int base_offset;
-    int len;                     /* length of data, if known, else -1
-                                        (decoding only) */
-    const unsigned char *lenb;   /* where to encode length */
-    int len_offset;
-    int lenlen;                  /* length of length-field */
-} odr_constack;
-
 #define ODR_S_SET     0
 #define ODR_S_CUR     1
 #define ODR_S_END     2
@@ -186,7 +175,7 @@ YAZ_EXPORT int odr_geterror(ODR o);
 YAZ_EXPORT int odr_geterrorx(ODR o, int *x);
 YAZ_EXPORT void odr_seterror(ODR o, int errorno, int errorid);
 YAZ_EXPORT void odr_setelement(ODR o, const char *addinfo);
-YAZ_EXPORT char *odr_getelement(ODR o);
+YAZ_EXPORT const char *odr_getelement(ODR o);
 YAZ_EXPORT void odr_perror(ODR o, const char *message);
 YAZ_EXPORT void odr_setprint(ODR o, FILE *file);
 YAZ_EXPORT ODR odr_createmem(int direction);
@@ -328,12 +317,17 @@ YAZ_EXPORT int odr_generalizedtime(ODR o, char **p, int opt,
 YAZ_EXPORT int odr_set_charset(ODR o, const char *to, const char *from);
 
 YAZ_EXPORT void odr_set_stream(ODR o,  void *handle,
-                              void (*stream_puts)(void *handle,
-                                                  const char *strz),
+                              void (*stream_write)(ODR o, 
+                                                   void *handle,
+                                                   int type,
+                                                   const char *buf,
+                                                   int len),
                               void (*stream_close)(void *handle));
 
 YAZ_EXPORT void odr_printf(ODR o, const char *fmt, ...);
 
+YAZ_EXPORT const char **odr_get_element_path(ODR o);
+
 YAZ_END_CDECL
 
 #include <yaz/xmalloc.h>
index ce69d09..0d22c09 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995-2003, Index Data.
+ * Copyright (c) 1995-2004, Index Data.
  *
  * Permission to use, copy, modify, distribute, and sell this software and
  * its documentation, in whole or in part, for any purpose, is hereby granted,
@@ -23,7 +23,7 @@
  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  * OF THIS SOFTWARE.
  *
- * $Id: odr-priv.h,v 1.2 2004-08-11 12:15:38 adam Exp $
+ * $Id: odr-priv.h,v 1.3 2004-08-13 07:30:06 adam Exp $
  */
 
 #ifndef ODR_PRIV_H
@@ -43,17 +43,30 @@ struct Odr_ber_tag {      /* used to be statics in ber_tag... */
 #define odr_max(o) ((o)->size - ((o)->bp - (o)->buf))
 #define odr_offset(o) ((o)->bp - (o)->buf)
 
+typedef struct odr_constack
+{
+    const unsigned char *base;   /* starting point of data */
+    int base_offset;
+    int len;                     /* length of data, if known, else -1
+                                        (decoding only) */
+    const unsigned char *lenb;   /* where to encode length */
+    int len_offset;
+    int lenlen;                  /* length of length-field */
+} odr_constack;
+
 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];
 
     struct Odr_ber_tag odr_ber_tag;
     yaz_iconv_t iconv_handle;
     int error_id;
     char element[80];
-    void (*stream_puts)(void *handle, const char *strz);
+    void (*stream_write)(ODR o, void *handle, int type,
+                        const char *buf, int len);
     void (*stream_close)(void *handle);
 };
 
index 7a0dab1..54ff613 100644 (file)
--- a/src/odr.c
+++ b/src/odr.c
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2004, Index Data
  * See the file LICENSE for details.
  *
- * $Id: odr.c,v 1.2 2004-08-11 12:15:38 adam Exp $
+ * $Id: odr.c,v 1.3 2004-08-13 07:30:06 adam Exp $
  *
  */
 #if HAVE_CONFIG_H
@@ -69,11 +69,16 @@ int odr_geterrorx(ODR o, int *x)
     return o->error;
 }
 
-char *odr_getelement(ODR o)
+const char *odr_getelement(ODR o)
 {
     return o->op->element;
 }
 
+const char **odr_get_element_path(ODR o)
+{
+    return o->op->stack_names;
+}
+
 void odr_seterror(ODR o, int error, int id)
 {
     o->error = error;
@@ -90,9 +95,36 @@ void odr_setelement(ODR o, const char *element)
     }
 }
 
-void odr_FILE_puts(void *handle, const char *strz)
+void odr_FILE_write(ODR o, void *handle, int type,
+                   const char *buf, int len)
 {
-    fputs(strz, (FILE*) handle);
+    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++)
+    {
+       if (i == 2000 && len > 3100)
+       {
+           fputs(" ..... ", (FILE*) handle);
+               i = len - 1000;
+       }
+       unsigned c = ((const unsigned char *) buf)[i];
+       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);
+       }
+    }
 }
 
 void odr_FILE_close(void *handle)
@@ -104,15 +136,17 @@ void odr_FILE_close(void *handle)
 
 void odr_setprint(ODR o, FILE *file)
 {
-    odr_set_stream(o, file, odr_FILE_puts, odr_FILE_close);
+    odr_set_stream(o, file, odr_FILE_write, odr_FILE_close);
 }
 
 void odr_set_stream(ODR o, void *handle,
-                   void (*stream_puts)(void *handle, const char *strz),
+                   void (*stream_write)(ODR o, 
+                                        void *handle, int type,
+                                        const char *buf, int len),
                    void (*stream_close)(void *handle))
 {
     o->print = handle;
-    o->op->stream_puts = stream_puts;
+    o->op->stream_write = stream_write;
     o->op->stream_close = stream_close;
 }
 
@@ -218,6 +252,6 @@ void odr_printf(ODR o, const char *fmt, ...)
     vsprintf(buf, fmt, ap);
 #endif
 #endif
-    o->op->stream_puts(o->print, buf);
+    o->op->stream_write(o, o->print, ODR_VISIBLESTRING, buf, strlen(buf));
     va_end(ap);
 }
index 48c327f..9740221 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1995-2003, Index Data
+ * Copyright (c) 1995-2004, Index Data
  * See the file LICENSE for details.
  *
- * $Id: odr_cons.c,v 1.2 2004-08-11 12:15:38 adam Exp $
+ * $Id: odr_cons.c,v 1.3 2004-08-13 07:30:06 adam Exp $
  *
  */
 #if HAVE_CONFIG_H
@@ -43,6 +43,8 @@ int odr_constructed_begin(ODR o, void *p, int zclass, int tag,
     }
     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
@@ -54,6 +56,7 @@ int odr_constructed_begin(ODR o, void *p, int zclass, int tag,
 
        if (odr_write(o, dummy, lenlen) < 0)  /* dummy */
         {
+           o->op->stack_names[o->op->stackp] = 0;
             --(o->op->stackp);
            return 0;
         }
@@ -64,6 +67,7 @@ int odr_constructed_begin(ODR o, void *p, int zclass, int tag,
                               odr_max(o))) < 0)
         {
             odr_seterror(o, OOTHER, 31);
+           o->op->stack_names[o->op->stackp] = 0;
             --(o->op->stackp);
            return 0;
         }
@@ -72,6 +76,7 @@ int odr_constructed_begin(ODR o, void *p, int zclass, int tag,
         if (o->op->stack[o->op->stackp].len > odr_max(o))
         {
             odr_seterror(o, OOTHER, 32);
+           o->op->stack_names[o->op->stackp] = 0;
             --(o->op->stackp);
            return 0;
         }
@@ -85,6 +90,7 @@ int odr_constructed_begin(ODR o, void *p, int zclass, int tag,
     else
     {
         odr_seterror(o, OOTHER, 33);
+       o->op->stack_names[o->op->stackp] = 0;
         --(o->op->stackp);
        return 0;
     }
@@ -117,6 +123,7 @@ int odr_constructed_end(ODR o)
         odr_seterror(o, OOTHER, 34);
        return 0;
     }
+    o->op->stack_names[o->op->stackp] = 0;
     switch (o->direction)
     {
     case ODR_DECODE:
index 27cd9b0..a4369fe 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * Copyright (c) 1995-2003, Index Data
+ * Copyright (c) 1995-2004, Index Data
  * See the file LICENSE for details.
- * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: odr_oct.c,v 1.2 2004-08-11 12:15:38 adam Exp $
+ * $Id: odr_oct.c,v 1.3 2004-08-13 07:30:06 adam Exp $
  */
 #if HAVE_CONFIG_H
 #include <config.h>
@@ -35,16 +34,10 @@ int odr_octetstring(ODR o, Odr_oct **p, int opt, const char *name)
     {
         int i;
        odr_prname(o, name);
-       odr_printf(o, "OCTETSTRING(len=%d)", (*p)->len);
-        for (i = 0; i<(*p)->len; i++)
-        {
-           if (i < 5 || i > ((*p)->len - 4))
-            {
-                odr_printf(o, " %02X", (*p)->buf[i]);
-            }
-            else if (i == 5)
-                odr_printf(o, " .. ");
-        }
+       odr_printf(o, "OCTETSTRING(len=%d) ", (*p)->len);
+
+       o->op->stream_write(o, o->print, ODR_OCTETSTRING,
+                           (*p)->buf, (*p)->len);
         odr_printf(o, "\n");
        return 1;
     }
index 056395c..95d4447 100644 (file)
@@ -1,9 +1,8 @@
 /*
- * Copyright (c) 1995-2003, Index Data
+ * Copyright (c) 1995-2004, Index Data
  * See the file LICENSE for details.
- * Sebastian Hammer, Adam Dickmeiss
  *
- * $Id: odr_oid.c,v 1.2 2004-08-11 12:15:38 adam Exp $
+ * $Id: odr_oid.c,v 1.3 2004-08-13 07:30:06 adam Exp $
  */
 #if HAVE_CONFIG_H
 #include <config.h>