X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fprt-ext.c;h=b076241604862d11d62748e96de69a386b786482;hb=60a702f390f7e2addfdab79f2328db3ba2897c8b;hp=e3b0c5b4cdea1c702431302e6ee8ba87ab29162d;hpb=c6e47cbbff56f39f6d81b079ebaeac41d793d4d9;p=yaz-moved-to-github.git diff --git a/src/prt-ext.c b/src/prt-ext.c index e3b0c5b..b076241 100644 --- a/src/prt-ext.c +++ b/src/prt-ext.c @@ -1,12 +1,23 @@ /* - * Copyright (c) 1995-2003, Index Data. + * Copyright (C) 1995-2005, Index Data ApS * See the file LICENSE for details. * - * $Id: prt-ext.c,v 1.1 2003-10-27 12:21:35 adam Exp $ + * $Id: prt-ext.c,v 1.5 2005-01-27 09:08:42 adam Exp $ + */ + +/** + * \file prt-ext.c + * \brief Implements handling of various Z39.50 Externals */ #include +#define PRT_EXT_DEBUG 0 + +#if PRT_EXT_DEBUG +#include +#endif + /* * The table below should be moved to the ODR structure itself and * be an image of the association context: To help @@ -41,7 +52,6 @@ static Z_ext_typeent type_table[] = {VAL_KRB1, Z_External_acfKrb1, (Odr_fun) z_KRBObject}, {VAL_MULTISRCH2, Z_External_multisrch2, (Odr_fun) z_MultipleSearchTerms_2}, {VAL_CQL, Z_External_CQL, (Odr_fun) z_InternationalString}, - {VAL_OCLCUI, Z_External_OCLCUserInfo, (Odr_fun) z_OCLC_UserInformation}, {VAL_NONE, 0, 0} }; @@ -55,6 +65,25 @@ Z_ext_typeent *z_ext_getentbyref(oid_value val) return 0; } +/** + This routine is the BER codec for the EXTERNAL type. + It handles information in single-ASN1-type and octet-aligned + for known structures. + +
+    [UNIVERSAL 8] IMPLICIT SEQUENCE {
+    direct-reference      OBJECT IDENTIFIER OPTIONAL,
+    indirect-reference    INTEGER OPTIONAL,
+    data-value-descriptor ObjectDescriptor OPTIONAL,
+    encoding              CHOICE {
+      single-ASN1-type   [0] ABSTRACT_SYNTAX.&Type,
+      octet-aligned      [1] IMPLICIT OCTET STRING,
+      arbitrary          [2] IMPLICIT BIT STRING 
+      }
+    }
+  
+ arbitrary BIT STRING not handled yet. +*/ int z_External(ODR o, Z_External **p, int opt, const char *name) { oident *oid; @@ -127,7 +156,7 @@ int z_External(ODR o, Z_External **p, int opt, const char *name) (Odr_fun)z_OCLC_UserInformation, 0}, {-1, -1, -1, -1, 0, 0} }; - + odr_implicit_settag(o, ODR_UNIVERSAL, ODR_EXTERNAL); if (!odr_sequence_begin(o, p, sizeof(**p), name)) return opt && odr_ok(o); @@ -135,22 +164,76 @@ int z_External(ODR o, Z_External **p, int opt, const char *name) odr_integer(o, &(*p)->indirect_reference, 1, 0) && odr_graphicstring(o, &(*p)->descriptor, 1, 0))) return 0; - /* - * Do we know this beast? - */ +#if PRT_EXT_DEBUG + /* debugging purposes only */ + if (o->direction == ODR_DECODE) + { + yaz_log(YLOG_LOG, "z_external decode"); + if ((*p)->direct_reference) + { + yaz_log(YLOG_LOG, "direct reference"); + if ((oid = oid_getentbyoid((*p)->direct_reference))) + { + yaz_log(YLOG_LOG, "oid %s", oid->desc); + if ((type = z_ext_getentbyref(oid->value))) + yaz_log(YLOG_LOG, "type"); + } + } + } +#endif + /* Do we know this beast? */ if (o->direction == ODR_DECODE && (*p)->direct_reference && (oid = oid_getentbyoid((*p)->direct_reference)) && (type = z_ext_getentbyref(oid->value))) { int zclass, tag, cons; - - /* - * We know it. If it's represented as an ASN.1 type, bias the CHOICE. - */ + /* OID is present and we know it */ + if (!odr_peektag(o, &zclass, &tag, &cons)) return opt && odr_ok(o); +#if PRT_EXT_DEBUG + yaz_log(YLOG_LOG, "odr_peektag OK tag=%d cons=%d zclass=%d what=%d", + tag, cons, zclass, type->what); +#endif + if (zclass == ODR_CONTEXT && tag == 1 && cons == 0) + { + /* we have an OCTET STRING. decode BER contents from it */ + const unsigned char *o_bp; + unsigned char *o_buf; + int o_size; + char *voidp = 0; + Odr_oct *oct; + int r; + if (!odr_implicit_tag(o, odr_octetstring, &oct, + ODR_CONTEXT, 1, 0, "octetaligned")) + return 0; + + /* Save our decoding ODR members */ + o_bp = o->bp; + o_buf = o->buf; + o_size = o->size; + + /* Set up the OCTET STRING buffer */ + o->bp = o->buf = oct->buf; + o->size = oct->len; + + /* and decode that */ + r = (*type->fun)(o, &voidp, 0, 0); + (*p)->which = type->what; + (*p)->u.single_ASN1_type = (Odr_any*) voidp; + + /* Restore our decoding ODR member */ + o->bp = o_bp; + o->buf = o_buf; + o->size = o_size; + + return r && odr_sequence_end(o); + } if (zclass == ODR_CONTEXT && tag == 0 && cons == 1) + { + /* It's single ASN.1 type, bias the CHOICE. */ odr_choice_bias(o, type->what); + } } return odr_choice(o, arm, &(*p)->u, &(*p)->which, name) && @@ -172,7 +255,6 @@ Z_External *z_ext_record(ODR o, int format, const char *buf, int len) if (len < 0) /* Structured data */ { - /* * We cheat on the pointers here. Obviously, the record field * of the backend-fetch structure should have been a union for