Better ODR diagnostics for missing elements which includes additional
[yaz-moved-to-github.git] / odr / odr.c
index 15c6e67..a29f720 100644 (file)
--- a/odr/odr.c
+++ b/odr/odr.c
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1995-2002, Index Data
+ * Copyright (c) 1995-2003, Index Data
  * See the file LICENSE for details.
  *
- * $Id: odr.c,v 1.35 2002-07-25 12:51:08 adam Exp $
+ * $Id: odr.c,v 1.43 2003-05-20 19:55:29 adam Exp $
  *
  */
 #if HAVE_CONFIG_H
@@ -35,7 +35,8 @@ char *odr_errlist[] =
     "Malformed data",
     "Stack overflow",
     "Length of constructed type different from sum of members",
-    "Overflow writing definite length of constructed type"
+    "Overflow writing definite length of constructed type",
+    "Bad HTTP Request"
 };
 
 char *odr_errmsg(int n)
@@ -45,7 +46,8 @@ char *odr_errmsg(int n)
 
 void odr_perror(ODR o, char *message)
 {
-    fprintf(stderr, "%s: %s\n", message, odr_errlist[o->error]);
+    fprintf(stderr, "%s: %s: %s\n", message, odr_errlist[o->error],
+            odr_getaddinfo(o));
 }
 
 int odr_geterror(ODR o)
@@ -53,6 +55,34 @@ int odr_geterror(ODR o)
     return o->error;
 }
 
+int odr_geterrorx(ODR o, int *x)
+{
+    if (x)
+        *x = o->op->error_id;
+    return o->error;
+}
+
+char *odr_getaddinfo(ODR o)
+{
+    return o->op->addinfo;
+}
+
+void odr_seterror(ODR o, int error, int id)
+{
+    o->error = error;
+    o->op->error_id = id;
+    o->op->addinfo[0] = '\0';
+}
+
+void odr_setaddinfo(ODR o, const char *addinfo)
+{
+    if (addinfo)
+    {
+        strncpy(o->op->addinfo, addinfo, sizeof(o->op->addinfo)-1);
+        o->op->addinfo[sizeof(o->op->addinfo)-1] = '\0';
+    }
+}
+
 void odr_setprint(ODR o, FILE *file)
 {
     o->print = file;
@@ -60,17 +90,16 @@ void odr_setprint(ODR o, FILE *file)
 
 int odr_set_charset(ODR o, const char *to, const char *from)
 {
-#if HAVE_ICONV_H
-    if (o->op->iconv_handle != (iconv_t)(-1))
-        iconv_close (o->op->iconv_handle);
-
-    o->op->iconv_handle = iconv_open (to, from);
-    if (o->op->iconv_handle == (iconv_t)(-1))
-        return -1;
+    if (o->op->iconv_handle)
+        yaz_iconv_close (o->op->iconv_handle);
+    o->op->iconv_handle = 0;
+    if (to && from)
+    {
+        o->op->iconv_handle = yaz_iconv_open (to, from);
+        if (o->op->iconv_handle == 0)
+            return -1;
+    }
     return 0;
-#else
-    return -1;
-#endif
 }
 
 #include <yaz/log.h>
@@ -88,11 +117,9 @@ ODR odr_createmem(int direction)
     r->can_grow = 1;
     r->mem = nmem_create();
     r->enable_bias = 1;
-    r->op = xmalloc (sizeof(*r->op));
+    r->op = (struct Odr_private *) xmalloc (sizeof(*r->op));
     r->op->odr_ber_tag.lclass = -1;
-#if HAVE_ICONV_H
-    r->op->iconv_handle = (iconv_t)(-1);
-#endif
+    r->op->iconv_handle = 0;
     odr_reset(r);
     yaz_log (LOG_DEBUG, "odr_createmem dir=%d o=%p", direction, r);
     return r;
@@ -100,7 +127,7 @@ ODR odr_createmem(int direction)
 
 void odr_reset(ODR o)
 {
-    o->error = ONONE;
+    odr_seterror(o, ONONE, 0);
     o->bp = o->buf;
     odr_seek(o, ODR_S_SET, 0);
     o->top = 0;
@@ -111,10 +138,8 @@ void odr_reset(ODR o)
     nmem_reset(o->mem);
     o->choice_bias = -1;
     o->lenlen = 1;
-#if HAVE_ICONV_H
-    if (o->op->iconv_handle != (iconv_t)(-1))
-        iconv(o->op->iconv_handle, 0, 0, 0, 0);
-#endif
+    if (o->op->iconv_handle != 0)
+        yaz_iconv(o->op->iconv_handle, 0, 0, 0, 0);
     yaz_log (LOG_DEBUG, "odr_reset o=%p", o);
 }
     
@@ -125,10 +150,8 @@ void odr_destroy(ODR o)
        xfree(o->buf);
     if (o->print && o->print != stderr)
         fclose(o->print);
-#if HAVE_ICONV_H
-    if (o->op->iconv_handle != (iconv_t)(-1))
-        iconv_close (o->op->iconv_handle);
-#endif
+    if (o->op->iconv_handle != 0)
+        yaz_iconv_close (o->op->iconv_handle);
     xfree(o->op);
     xfree(o);
     yaz_log (LOG_DEBUG, "odr_destroy o=%p", o);
@@ -151,3 +174,4 @@ char *odr_getbuf(ODR o, int *len, int *size)
         *size = o->size;
     return (char*) o->buf;
 }
+