2 * Copyright (C) 1995-2005, Index Data ApS
3 * See the file LICENSE for details.
5 * $Id: prt-ext.c,v 1.6 2005-06-25 15:46:04 adam Exp $
10 * \brief Implements handling of various Z39.50 Externals
13 #include <yaz/proto.h>
15 #define PRT_EXT_DEBUG 0
22 * The table below should be moved to the ODR structure itself and
23 * be an image of the association context: To help
24 * map indirect references when they show up.
26 static Z_ext_typeent type_table[] =
28 {VAL_SUTRS, Z_External_sutrs, (Odr_fun) z_SUTRS},
29 {VAL_EXPLAIN, Z_External_explainRecord, (Odr_fun)z_ExplainRecord},
30 {VAL_RESOURCE1, Z_External_resourceReport1, (Odr_fun)z_ResourceReport1},
31 {VAL_RESOURCE2, Z_External_resourceReport2, (Odr_fun)z_ResourceReport2},
32 {VAL_PROMPT1, Z_External_promptObject1, (Odr_fun)z_PromptObject1 },
33 {VAL_GRS1, Z_External_grs1, (Odr_fun)z_GenericRecord},
34 {VAL_EXTENDED, Z_External_extendedService, (Odr_fun)z_TaskPackage},
35 {VAL_ITEMORDER, Z_External_itemOrder, (Odr_fun)z_IOItemOrder},
36 {VAL_DIAG1, Z_External_diag1, (Odr_fun)z_DiagnosticFormat},
37 {VAL_ESPEC1, Z_External_espec1, (Odr_fun)z_Espec1},
38 {VAL_SUMMARY, Z_External_summary, (Odr_fun)z_BriefBib},
39 {VAL_OPAC, Z_External_OPAC, (Odr_fun)z_OPACRecord},
40 {VAL_SEARCHRES1, Z_External_searchResult1, (Odr_fun)z_SearchInfoReport},
41 {VAL_DBUPDATE, Z_External_update, (Odr_fun)z_IUUpdate},
42 {VAL_DBUPDATE0, Z_External_update0, (Odr_fun)z_IU0Update},
43 {VAL_DBUPDATE1, Z_External_update0, (Odr_fun)z_IU0Update},
44 {VAL_DATETIME, Z_External_dateTime, (Odr_fun)z_DateTime},
45 {VAL_UNIVERSE_REPORT, Z_External_universeReport,(Odr_fun)z_UniverseReport},
46 {VAL_ADMINSERVICE, Z_External_ESAdmin, (Odr_fun)z_Admin},
47 {VAL_USERINFO1, Z_External_userInfo1, (Odr_fun) z_OtherInformation},
48 {VAL_CHARNEG3, Z_External_charSetandLanguageNegotiation, (Odr_fun)
49 z_CharSetandLanguageNegotiation},
50 {VAL_PROMPT1, Z_External_acfPrompt1, (Odr_fun) z_PromptObject1},
51 {VAL_DES1, Z_External_acfDes1, (Odr_fun) z_DES_RN_Object},
52 {VAL_KRB1, Z_External_acfKrb1, (Odr_fun) z_KRBObject},
53 {VAL_MULTISRCH2, Z_External_multisrch2, (Odr_fun) z_MultipleSearchTerms_2},
54 {VAL_CQL, Z_External_CQL, (Odr_fun) z_InternationalString},
58 Z_ext_typeent *z_ext_getentbyref(oid_value val)
62 for (i = type_table; i->dref != VAL_NONE; i++)
69 This routine is the BER codec for the EXTERNAL type.
70 It handles information in single-ASN1-type and octet-aligned
74 [UNIVERSAL 8] IMPLICIT SEQUENCE {
75 direct-reference OBJECT IDENTIFIER OPTIONAL,
76 indirect-reference INTEGER OPTIONAL,
77 data-value-descriptor ObjectDescriptor OPTIONAL,
79 single-ASN1-type [0] ABSTRACT_SYNTAX.&Type,
80 octet-aligned [1] IMPLICIT OCTET STRING,
81 arbitrary [2] IMPLICIT BIT STRING
85 arbitrary BIT STRING not handled yet.
87 int z_External(ODR o, Z_External **p, int opt, const char *name)
92 static Odr_arm arm[] =
94 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_single,
96 {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_External_octet,
97 (Odr_fun)odr_octetstring, 0},
98 {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_External_arbitrary,
99 (Odr_fun)odr_bitstring, 0},
100 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_sutrs,
101 (Odr_fun)z_SUTRS, 0},
102 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_explainRecord,
103 (Odr_fun)z_ExplainRecord, 0},
105 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_resourceReport1,
106 (Odr_fun)z_ResourceReport1, 0},
107 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_resourceReport2,
108 (Odr_fun)z_ResourceReport2, 0},
109 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_promptObject1,
110 (Odr_fun)z_PromptObject1, 0},
111 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_grs1,
112 (Odr_fun)z_GenericRecord, 0},
113 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_extendedService,
114 (Odr_fun)z_TaskPackage, 0},
116 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_itemOrder,
117 (Odr_fun)z_IOItemOrder, 0},
118 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_diag1,
119 (Odr_fun)z_DiagnosticFormat, 0},
120 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_espec1,
121 (Odr_fun)z_Espec1, 0},
122 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_summary,
123 (Odr_fun)z_BriefBib, 0},
124 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_OPAC,
125 (Odr_fun)z_OPACRecord, 0},
127 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_searchResult1,
128 (Odr_fun)z_SearchInfoReport, 0},
129 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_update,
130 (Odr_fun)z_IUUpdate, 0},
131 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_dateTime,
132 (Odr_fun)z_DateTime, 0},
133 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_universeReport,
134 (Odr_fun)z_UniverseReport, 0},
135 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_ESAdmin,
136 (Odr_fun)z_Admin, 0},
138 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_update0,
139 (Odr_fun)z_IU0Update, 0},
140 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_userInfo1,
141 (Odr_fun)z_OtherInformation, 0},
142 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_charSetandLanguageNegotiation,
143 (Odr_fun)z_CharSetandLanguageNegotiation, 0},
144 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_acfPrompt1,
145 (Odr_fun)z_PromptObject1, 0},
146 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_acfDes1,
147 (Odr_fun)z_DES_RN_Object, 0},
149 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_acfKrb1,
150 (Odr_fun)z_KRBObject, 0},
151 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_multisrch2,
152 (Odr_fun)z_MultipleSearchTerms_2, 0},
153 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_CQL,
154 (Odr_fun)z_InternationalString, 0},
155 {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_OCLCUserInfo,
156 (Odr_fun)z_OCLC_UserInformation, 0},
157 {-1, -1, -1, -1, 0, 0}
160 odr_implicit_settag(o, ODR_UNIVERSAL, ODR_EXTERNAL);
161 if (!odr_sequence_begin(o, p, sizeof(**p), name))
162 return opt && odr_ok(o);
163 if (!(odr_oid(o, &(*p)->direct_reference, 1, 0) &&
164 odr_integer(o, &(*p)->indirect_reference, 1, 0) &&
165 odr_graphicstring(o, &(*p)->descriptor, 1, 0)))
168 /* debugging purposes only */
169 if (o->direction == ODR_DECODE)
171 yaz_log(YLOG_LOG, "z_external decode");
172 if ((*p)->direct_reference)
174 yaz_log(YLOG_LOG, "direct reference");
175 if ((oid = oid_getentbyoid((*p)->direct_reference)))
177 yaz_log(YLOG_LOG, "oid %s", oid->desc);
178 if ((type = z_ext_getentbyref(oid->value)))
179 yaz_log(YLOG_LOG, "type");
184 /* Do we know this beast? */
185 if (o->direction == ODR_DECODE && (*p)->direct_reference &&
186 (oid = oid_getentbyoid((*p)->direct_reference)) &&
187 (type = z_ext_getentbyref(oid->value)))
189 int zclass, tag, cons;
190 /* OID is present and we know it */
192 if (!odr_peektag(o, &zclass, &tag, &cons))
193 return opt && odr_ok(o);
195 yaz_log(YLOG_LOG, "odr_peektag OK tag=%d cons=%d zclass=%d what=%d",
196 tag, cons, zclass, type->what);
198 if (zclass == ODR_CONTEXT && tag == 1 && cons == 0)
200 /* we have an OCTET STRING. decode BER contents from it */
201 const unsigned char *o_bp;
202 unsigned char *o_buf;
207 if (!odr_implicit_tag(o, odr_octetstring, &oct,
208 ODR_CONTEXT, 1, 0, "octetaligned"))
211 /* Save our decoding ODR members */
216 /* Set up the OCTET STRING buffer */
217 o->bp = o->buf = oct->buf;
220 /* and decode that */
221 r = (*type->fun)(o, &voidp, 0, 0);
222 (*p)->which = type->what;
223 (*p)->u.single_ASN1_type = (Odr_any*) voidp;
225 /* Restore our decoding ODR member */
230 return r && odr_sequence_end(o);
232 if (zclass == ODR_CONTEXT && tag == 0 && cons == 1)
234 /* It's single ASN.1 type, bias the CHOICE. */
235 odr_choice_bias(o, type->what);
239 odr_choice(o, arm, &(*p)->u, &(*p)->which, name) &&
243 Z_External *z_ext_record(ODR o, int format, const char *buf, int len)
247 thisext = (Z_External *) odr_malloc(o, sizeof(*thisext));
248 thisext->descriptor = 0;
249 thisext->indirect_reference = 0;
251 thisext->direct_reference =
252 yaz_oidval_to_z3950oid (o, CLASS_RECSYN, format);
253 if (!thisext->direct_reference)
256 if (len < 0) /* Structured data */
259 * We cheat on the pointers here. Obviously, the record field
260 * of the backend-fetch structure should have been a union for
261 * correctness, but we're stuck with this for backwards
264 thisext->u.grs1 = (Z_GenericRecord*) buf;
269 thisext->which = Z_External_sutrs;
272 thisext->which = Z_External_grs1;
275 thisext->which = Z_External_explainRecord;
278 thisext->which = Z_External_summary;
281 thisext->which = Z_External_OPAC;
284 thisext->which = Z_External_extendedService;
290 else if (format == VAL_SUTRS) /* SUTRS is a single-ASN.1-type */
292 Odr_oct *sutrs = (Odr_oct *)odr_malloc(o, sizeof(*sutrs));
294 thisext->which = Z_External_sutrs;
295 thisext->u.sutrs = sutrs;
296 sutrs->buf = (unsigned char *)odr_malloc(o, len);
297 sutrs->len = sutrs->size = len;
298 memcpy(sutrs->buf, buf, len);
302 thisext->which = Z_External_octet;
303 if (!(thisext->u.octet_aligned = (Odr_oct *)
304 odr_malloc(o, sizeof(Odr_oct))))
306 if (!(thisext->u.octet_aligned->buf = (unsigned char *)
309 memcpy(thisext->u.octet_aligned->buf, buf, len);
310 thisext->u.octet_aligned->len = thisext->u.octet_aligned->size = len;
318 * indent-tabs-mode: nil
320 * vim: shiftwidth=4 tabstop=8 expandtab