New Facet helpers
authorDennis Schafroth <dennis@indexdata.com>
Thu, 15 Jul 2010 12:33:46 +0000 (14:33 +0200)
committerDennis Schafroth <dennis@indexdata.com>
Thu, 15 Jul 2010 12:33:46 +0000 (14:33 +0200)
Use for extraction of values from the ASN.1 structures in C.

include/yaz/Makefile.am
include/yaz/facet.h [new file with mode: 0644]
src/Makefile.am
src/facet.c [new file with mode: 0644]

index 1ee66ac..f4e6548 100644 (file)
@@ -5,7 +5,7 @@ noinst_HEADERS = icu_I18N.h
 
 pkginclude_HEADERS= backend.h ccl.h ccl_xml.h cql.h rpn2cql.h comstack.h \
  diagbib1.h diagsrw.h diagsru_update.h sortspec.h log.h logrpn.h marcdisp.h \
- nmem.h nmem_xml.h odr.h errno.h \
+ nmem.h nmem_xml.h odr.h errno.h facet.h \
  options.h otherinfo.h pquery.h prt-ext.h querytowrbuf.h \
  readconf.h record_conv.h retrieval.h statserv.h \
  tcpip.h test.h timing.h unix.h tpath.h wrbuf.h xmalloc.h \
diff --git a/include/yaz/facet.h b/include/yaz/facet.h
new file mode 100644 (file)
index 0000000..687ce54
--- /dev/null
@@ -0,0 +1,51 @@
+
+#ifndef YAZ_FACET_H
+#define YAZ_FACET_H
+
+#include <yaz/yconfig.h>
+#include <yaz/z-core.h>
+#include <yaz/log.h>
+
+YAZ_BEGIN_CDECL
+
+
+/*
+ * Helper function for extracting facet values from the ASN structures.
+ *
+ */
+
+/* A helper structure to extract all the attribute stuff
+   from one Z_AttributesList. The pointers will all be to
+   the Z-structures, or to constants, so there is no need to
+   worry about freeing them */
+struct attrvalues {
+    int  errcode;   /* set in case of errors */
+    char *errstring; /* opt */
+    const char *useattr; /* @attr 1, from a string attr */
+                   /* or number converted to a string */
+                   /* defaults to 'any' */
+    char useattrbuff[30]; /* for converting numbers to strings */
+    char *relation; /* @attr 2, defaults to '=' */
+    int limit; /* for facet attributes */
+};
+
+
+/* Use attribute, @attr1, can be numeric or string */
+YAZ_EXPORT
+void useattr ( Z_AttributeElement *ae, struct attrvalues *av );
+
+YAZ_EXPORT
+void relationattr ( Z_AttributeElement *ae, struct attrvalues *av );
+
+YAZ_EXPORT
+void limitattr ( Z_AttributeElement *ae, struct attrvalues *av );
+
+YAZ_EXPORT
+void limitattr ( Z_AttributeElement *ae, struct attrvalues *av );
+
+YAZ_EXPORT
+void facetattrs( Z_AttributeList *attributes, struct attrvalues *av );
+
+
+
+#endif
index 2e5cec2..e79d237 100644 (file)
@@ -77,7 +77,7 @@ libyaz_la_SOURCES=version.c options.c log.c \
   wrbuf.c oid_db.c errno.c \
   nmemsdup.c xmalloc.c readconf.c tpath.c nmem.c matchstr.c atoin.c \
   siconv.c iconv-p.h utf8.c ucs4.c iso5428.c advancegreek.c \
-  odr_bool.c ber_bool.c ber_len.c ber_tag.c odr_util.c \
+  odr_bool.c ber_bool.c ber_len.c ber_tag.c odr_util.c facet.c \
   odr_null.c ber_null.c odr_int.c ber_int.c odr_tag.c odr_cons.c \
   odr_seq.c odr_oct.c ber_oct.c odr_bit.c ber_bit.c odr_oid.c \
   ber_oid.c odr_use.c odr_choice.c odr_any.c ber_any.c odr.c odr_mem.c \
diff --git a/src/facet.c b/src/facet.c
new file mode 100644 (file)
index 0000000..7baee6b
--- /dev/null
@@ -0,0 +1,120 @@
+
+
+#include <yaz/facet.h>
+#include <yaz/diagbib1.h>
+
+/* Little helper to extract a string attribute */
+/* Gets the first string, there is usually only one */
+/* in case of errors, returns null */
+const char *stringattr( Z_ComplexAttribute *c ) {
+    int i;
+     Z_StringOrNumeric *son;
+    for ( i = 0; i < c->num_list; i++ ) {
+        son = c->list[i];
+        if ( son->which == Z_StringOrNumeric_string )
+            return son->u.string;
+    }
+    return 0;
+}
+
+/* Use attribute, @attr1, can be numeric or string */
+void useattr ( Z_AttributeElement *ae,
+                       struct attrvalues *av )
+{
+    const char *s;
+    if ( ae->which == Z_AttributeValue_complex ) {
+        s = stringattr( ae->value.complex );
+        if (s) {
+            if (!av->useattr)
+                av->useattr = s;
+            else { /* already seen one, can't have duplicates */
+                av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI;
+                av->errstring = "multiple use attributes";
+            }
+        } else { /* complex that did not return a string */
+            av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI;
+            av->errstring = "non-string complex attribute";
+        }
+    } else { /* numeric - could translate 4 to 'title' etc */
+        sprintf(av->useattrbuff, ODR_INT_PRINTF, *ae->value.numeric );
+        av->useattr = av->useattrbuff;
+    }
+} /* useattr */
+
+
+/* TODO rename to sortorder attr */
+void relationattr ( Z_AttributeElement *ae,
+                           struct attrvalues *av )
+{
+    if ( ae->which == Z_AttributeValue_numeric ) {
+        if ( *ae->value.numeric == 0 )
+            av->relation = "desc";
+        else if ( *ae->value.numeric == 1 )
+                av->relation = "asc";
+            else
+        if ( *ae->value.numeric == 3 ) {
+            av->relation = "unknown/unordered";
+        } else {
+            av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
+            sprintf(av->useattrbuff, ODR_INT_PRINTF,
+                        *ae-> attributeType);
+            av->errstring = av->useattrbuff;
+        }
+    } else {
+        av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
+        av->errstring = "non-numeric relation attribute";
+    }
+} /* relationattr */
+
+void limitattr ( Z_AttributeElement *ae,
+                        struct attrvalues *av )
+{
+  /* TODO - check numeric first, then value! */
+    if ( ae->which == Z_AttributeValue_numeric ) {
+        av->limit = *ae->value.numeric;
+    } else {
+        av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE;
+        av->errstring = "non-numeric limit attribute";
+    }
+} /* relationattr */
+
+/* Get the index to be searched from the attributes.
+   @attr 1
+     can be either "string", or some well-known value like
+     4 for title
+   Returns a null and sets errors in rr,
+   emtpy string if no attr found,
+   or the string itself - always a pointer to the Z-structs,
+   so no need to free that string!
+*/
+
+void facetattrs( Z_AttributeList *attributes,
+                          struct attrvalues *av )
+{
+    int i;
+    Z_AttributeElement *ae;
+    for ( i=0; i < attributes->num_attributes; i++ ) {
+        ae = attributes->attributes[i];
+        /* ignoring the attributeSet here */
+        if ( *ae->attributeType == 1 ) { /* use attribute */
+            useattr(ae, av);
+        } else if ( *ae->attributeType == 2 ) { /* sortorder */
+            relationattr(ae, av);
+        } else if ( *ae->attributeType == 3 ) { /* limit */
+            limitattr(ae, av);
+        } else { /* unknown attribute */
+            av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE;
+            sprintf(av->useattrbuff, ODR_INT_PRINTF,
+                        *ae-> attributeType);
+            av->errstring = av->useattrbuff;
+            yaz_log(YLOG_DEBUG,"Unsupported attribute type %s",
+                av->useattrbuff);
+            /* would like to give a better message, but the standard */
+            /* tells me to return the attribute type */
+        }
+        if ( av->errcode )
+            return; /* no need to dig deeper, return on first error */
+    }
+    return;
+} /* facetattrs */
+