Added CLOSE
[yaz-moved-to-github.git] / asn / proto.c
1 /*
2  * Copyright (c) 1995, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: proto.c,v $
7  * Revision 1.27  1995-06-07 14:36:22  quinn
8  * Added CLOSE
9  *
10  * Revision 1.26  1995/06/02  09:49:13  quinn
11  * Adding access control
12  *
13  * Revision 1.25  1995/05/25  11:00:08  quinn
14  * *** empty log message ***
15  *
16  * Revision 1.24  1995/05/22  13:58:18  quinn
17  * Fixed an ODR_NULLVAL.
18  *
19  * Revision 1.23  1995/05/22  11:30:18  quinn
20  * Adding Z39.50-1992 stuff to proto.c. Adding zget.c
21  *
22  * Revision 1.22  1995/05/17  08:40:56  quinn
23  * Added delete. Fixed some sequence_begins. Smallish.
24  *
25  * Revision 1.21  1995/05/16  08:50:24  quinn
26  * License, documentation, and memory fixes
27  *
28  * Revision 1.20  1995/05/15  11:55:25  quinn
29  * Smallish.
30  *
31  * Revision 1.19  1995/04/11  11:58:35  quinn
32  * Fixed bug.
33  *
34  * Revision 1.18  1995/04/11  11:52:02  quinn
35  * Fixed possible buf in proto.c
36  *
37  * Revision 1.17  1995/04/10  10:22:22  quinn
38  * Added SCAN.
39  *
40  * Revision 1.16  1995/03/30  10:26:43  quinn
41  * Added Term structure
42  *
43  * Revision 1.15  1995/03/30  09:08:39  quinn
44  * Added Resource control protocol
45  *
46  * Revision 1.14  1995/03/29  08:06:13  quinn
47  * Added a few v3 elements
48  *
49  * Revision 1.13  1995/03/20  11:26:52  quinn
50  * *** empty log message ***
51  *
52  * Revision 1.12  1995/03/20  09:45:09  quinn
53  * Working towards v3
54  *
55  * Revision 1.11  1995/03/17  10:17:25  quinn
56  * Added memory management.
57  *
58  * Revision 1.10  1995/03/15  11:17:40  quinn
59  * Fixed some return-checks from choice.. need better ay to handle those..
60  *
61  * Revision 1.9  1995/03/15  08:37:06  quinn
62  * Fixed protocol bugs.
63  *
64  * Revision 1.8  1995/03/14  16:59:24  quinn
65  * Fixed OPTIONAL flag in attributeelement
66  *
67  * Revision 1.7  1995/03/07  16:29:33  quinn
68  * Added authentication stuff.
69  *
70  * Revision 1.6  1995/03/01  14:46:03  quinn
71  * Fixed protocol bug in 8777query.
72  *
73  * Revision 1.5  1995/02/14  11:54:22  quinn
74  * Fixing include.
75  *
76  * Revision 1.4  1995/02/10  15:54:30  quinn
77  * Small adjustments.
78  *
79  * Revision 1.3  1995/02/09  15:51:39  quinn
80  * Works better now.
81  *
82  * Revision 1.2  1995/02/06  21:26:07  quinn
83  * Repaired this evening's damages..
84  *
85  * Revision 1.1  1995/02/06  16:44:47  quinn
86  * First hack at Z/SR protocol
87  *
88  */
89
90 #include <odr.h>
91
92 #include <proto.h>
93
94 /* ---------------------- GLOBAL DEFS ------------------- */
95
96 int z_ReferenceId(ODR o, Z_ReferenceId **p, int opt)
97 {
98     return odr_implicit(o, odr_octetstring, (Odr_oct**) p, ODR_CONTEXT, 2, opt);
99 }
100
101 int z_DatabaseName(ODR o, Z_DatabaseName **p, int opt)
102 {
103     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 105,
104         opt);
105 }
106
107 int z_ResultSetId(ODR o, char **p, int opt)
108 {
109     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 31,
110         opt);
111 }
112
113 int z_UserInformationField(ODR o, Z_UserInformationField **p, int opt)
114 {
115     return odr_explicit(o, odr_external, (Odr_external **)p, ODR_CONTEXT,
116         11, opt);
117 }
118
119 int z_InfoCategory(ODR o, Z_InfoCategory **p, int opt)
120 {
121     if (!odr_sequence_begin(o, p, sizeof(**p)))
122         return opt && odr_ok(o);
123     return
124         odr_implicit(o, odr_oid, &(*p)->categoryTypeId, ODR_CONTEXT, 1, 1) &&
125         odr_implicit(o, odr_integer, &(*p)->categoryValue, ODR_CONTEXT, 2, 0) &&
126         odr_sequence_end(o);
127 }
128
129 int z_OtherInformationUnit(ODR o, Z_OtherInformationUnit **p, int opt)
130 {
131     static Odr_arm arm[] =
132     {
133         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_OtherInfo_characterInfo,
134             odr_visiblestring},
135         {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_OtherInfo_binaryInfo,
136             odr_octetstring},
137         {ODR_IMPLICIT, ODR_CONTEXT, 4, Z_OtherInfo_externallyDefinedInfo,
138             odr_external},
139         {ODR_IMPLICIT, ODR_CONTEXT, 5, Z_OtherInfo_oid, odr_oid},
140         {-1, -1, -1, -1, 0}
141     };
142
143     if (!odr_sequence_begin(o, p, sizeof(**p)))
144         return opt && odr_ok(o);
145     return
146         odr_implicit(o, z_InfoCategory, &(*p)->category, ODR_CONTEXT, 1, 1) &&
147         odr_choice(o, arm, &(*p)->which, &(*p)->information) &&
148         odr_sequence_end(o);
149 }
150     
151 int z_OtherInformation(ODR o, Z_OtherInformation **p, int opt)
152 {
153     if (o->direction == ODR_ENCODE)
154         *p = odr_malloc(o, sizeof(**p));
155
156     odr_implicit_settag(o, ODR_CONTEXT, 201);
157     if (odr_sequence_of(o, z_OtherInformationUnit, &(*p)->list,
158         &(*p)->num_elements))
159         return 1;
160     *p = 0;
161     return opt && odr_ok(o);
162 }
163
164 int z_StringOrNumeric(ODR o, Z_StringOrNumeric **p, int opt)
165 {
166     static Odr_arm arm[] =
167     {
168         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_StringOrNumeric_string,
169             odr_visiblestring},
170         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_StringOrNumeric_numeric,
171             odr_integer},
172         {-1, -1, -1, -1, 0}
173     };
174
175     if (o->direction == ODR_DECODE)
176         *p = odr_malloc(o, sizeof(**p));
177     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
178         return 1;
179     *p = 0;
180     return opt && odr_ok(o);
181 }
182
183 /*
184  * check tagging!!
185  */
186 int z_Unit(ODR o, Z_Unit **p, int opt)
187 {
188     if (!odr_sequence_begin(o, p, sizeof(**p)))
189         return opt && odr_ok(o);
190     return
191         odr_implicit(o, odr_visiblestring, &(*p)->unitSystem, ODR_CONTEXT,
192             1, 1) &&
193         odr_explicit(o, z_StringOrNumeric, &(*p)->unitType, ODR_CONTEXT,
194             2, 1) &&
195         odr_explicit(o, z_StringOrNumeric, &(*p)->unit, ODR_CONTEXT, 3, 1) &&
196         odr_implicit(o, odr_integer, &(*p)->scaleFactor, ODR_CONTEXT, 4, 1) &&
197         odr_sequence_end(o);
198 }
199
200 int z_IntUnit(ODR o, Z_IntUnit **p, int opt)
201 {
202     if (!odr_sequence_begin(o, p, sizeof(**p)))
203         return opt && odr_ok(o);
204     return
205         odr_implicit(o, odr_integer, &(*p)->value, ODR_CONTEXT, 1, 0) &&
206         odr_implicit(o, z_Unit, &(*p)->unitUsed, ODR_CONTEXT, 2, 0) &&
207         odr_sequence_end(o);
208 }
209
210 /* ---------------------- INITIALIZE SERVICE ------------------- */
211
212 #if 0
213 int z_NSRAuthentication(ODR o, Z_NSRAuthentication **p, int opt)
214 {
215     if (!odr_sequence_begin(o, p, sizeof(**p)))
216         return opt && odr_ok(o);
217     return
218         odr_visiblestring(o, &(*p)->user, 0) &&
219         odr_visiblestring(o, &(*p)->password, 0) &&
220         odr_visiblestring(o, &(*p)->account, 0) &&
221         odr_sequence_end(o);
222 }
223 #endif
224
225 int z_IdPass(ODR o, Z_IdPass **p, int opt)
226 {
227     if (!odr_sequence_begin(o, p, sizeof(**p)))
228         return opt && odr_ok(o);
229     return
230         odr_implicit(o, odr_visiblestring, &(*p)->groupId, ODR_CONTEXT, 0, 1) &&
231         odr_implicit(o, odr_visiblestring, &(*p)->userId, ODR_CONTEXT, 1, 1) &&
232         odr_implicit(o, odr_visiblestring, &(*p)->password, ODR_CONTEXT, 2,
233             1) &&
234         odr_sequence_end(o);
235 }
236
237 int z_StrAuthentication(ODR o, char **p, int opt)
238 {
239     return odr_visiblestring(o, p, opt);
240 }
241
242 int z_IdAuthentication(ODR o, Z_IdAuthentication **p, int opt)
243 {
244     static Odr_arm arm[] =
245     {
246         {-1, -1, -1, Z_IdAuthentication_open, z_StrAuthentication},
247         {-1, -1, -1, Z_IdAuthentication_idPass, z_IdPass},
248         {-1, -1, -1, Z_IdAuthentication_anonymous, odr_null},
249         {-1, -1, -1, Z_IdAuthentication_other, odr_external},
250         {-1, -1, -1, -1, 0}
251     };
252
253     if (o->direction == ODR_DECODE)
254         *p = odr_malloc(o, sizeof(**p));
255
256     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
257         return 1;
258     *p = 0;
259     return opt && odr_ok(o);
260 }
261
262 int z_InitRequest(ODR o, Z_InitRequest **p, int opt)
263 {
264     Z_InitRequest *pp;
265
266     if (!odr_sequence_begin(o, p, sizeof(**p)))
267         return opt && odr_ok(o);
268     pp = *p;
269     return
270         z_ReferenceId(o, &pp->referenceId, 1) &&
271         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
272             3, 0) &&
273         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
274         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
275             5, 0) &&
276         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
277             6, 0) &&
278         odr_explicit(o, z_IdAuthentication, &pp->idAuthentication, ODR_CONTEXT,
279             7, 1) &&
280         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
281             110, 1) &&
282         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
283             111, 1) &&
284         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
285             ODR_CONTEXT, 112, 1) &&
286         z_UserInformationField(o, &pp->userInformationField, 1) &&
287 #ifdef Z_OTHERINFO
288         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
289 #endif
290         odr_sequence_end(o);
291 }
292
293 int z_InitResponse(ODR o, Z_InitResponse **p, int opt)
294 {
295     Z_InitResponse *pp;
296
297     if (!odr_sequence_begin(o, p, sizeof(**p)))
298         return opt && odr_ok(o);
299     pp = *p;
300     return
301         z_ReferenceId(o, &pp->referenceId, 1) &&
302         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
303             3, 0) &&
304         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
305         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
306             5, 0) &&
307         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
308             6, 0) &&
309         odr_implicit(o, odr_bool, &pp->result, ODR_CONTEXT, 12, 0) &&
310         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
311             110, 1) &&
312         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
313             111, 1) &&
314         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
315             ODR_CONTEXT, 112, 1) &&
316         z_UserInformationField(o, &pp->userInformationField, 1) &&
317 #ifdef Z_OTHERINFO
318         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
319 #endif
320         odr_sequence_end(o);
321 }
322
323 /* ------------------ RESOURCE CONTROL ----------------*/
324
325 int z_TriggerResourceControlRequest(ODR o, Z_TriggerResourceControlRequest **p,
326                                     int opt)
327 {
328     if (!odr_sequence_begin(o, p, sizeof(**p)))
329         return opt && odr_ok(o);
330     return
331         z_ReferenceId(o, &(*p)->referenceId, 1) &&
332         odr_implicit(o, odr_integer, &(*p)->requestedAction, ODR_CONTEXT,
333             46, 0) &&
334         odr_implicit(o, odr_oid, &(*p)->prefResourceReportFormat,
335             ODR_CONTEXT, 47, 1) &&
336         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
337             48, 1) &&
338 #ifdef Z_OTHERINFO
339         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
340 #endif
341         odr_sequence_end(o);
342 }
343
344 int z_ResourceControlRequest(ODR o, Z_ResourceControlRequest **p, int opt)
345 {
346     if (!odr_sequence_begin(o, p, sizeof(**p)))
347         return opt && odr_ok(o);
348     return
349         z_ReferenceId(o, &(*p)->referenceId, 1) &&
350         odr_implicit(o, odr_bool, &(*p)->suspendedFlag, ODR_CONTEXT, 39, 1)&&
351         odr_explicit(o, odr_external, &(*p)->resourceReport, ODR_CONTEXT,
352             40, 1) &&
353         odr_implicit(o, odr_integer, &(*p)->partialResultsAvailable,
354             ODR_CONTEXT, 41, 1) &&
355         odr_implicit(o, odr_bool, &(*p)->responseRequired, ODR_CONTEXT,
356             42, 0) &&
357         odr_implicit(o, odr_bool, &(*p)->triggeredRequestFlag,
358             ODR_CONTEXT, 43, 1) &&
359 #ifdef Z_OTHERINFO
360         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
361 #endif
362         odr_sequence_end(o);
363 }
364
365 int z_ResourceControlResponse(ODR o, Z_ResourceControlResponse **p, int opt)
366 {
367     if (!odr_sequence_begin(o, p, sizeof(**p)))
368         return opt && odr_ok(o);
369     return
370         z_ReferenceId(o, &(*p)->referenceId, 1) &&
371         odr_implicit(o, odr_bool, &(*p)->continueFlag, ODR_CONTEXT, 44, 0) &&
372         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
373             45, 1) &&
374 #ifdef Z_OTHERINFO
375         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
376 #endif
377         odr_sequence_end(o);
378 }
379
380 /* ------------------------ SEARCH SERVICE ----------------------- */
381
382 int z_ElementSetName(ODR o, char **p, int opt)
383 {
384     return odr_implicit(o, odr_visiblestring, (char**) p, ODR_CONTEXT, 103,
385         opt);
386 }
387
388 int z_PreferredRecordSyntax(ODR o, Z_PreferredRecordSyntax **p, int opt)
389 {
390     return odr_implicit(o, odr_oid, (Odr_oid**) p, ODR_CONTEXT, 104, opt);
391 }
392
393 int z_DatabaseSpecificUnit(ODR o, Z_DatabaseSpecificUnit **p, int opt)
394 {
395     if (!odr_sequence_begin(o, p, sizeof(**p)))
396         return opt && odr_ok(o);
397     return
398         z_DatabaseName(o, &(*p)->databaseName, 0) &&
399         z_ElementSetName(o, &(*p)->elementSetName, 0) &&
400         odr_sequence_end(o);
401 }
402
403 int z_DatabaseSpecific(ODR o, Z_DatabaseSpecific **p, int opt)
404 {
405     if (o->direction == ODR_DECODE)
406         *p = odr_malloc(o, sizeof(**p));
407     else if (!*p)
408         return opt;
409
410     odr_implicit_settag(o, ODR_CONTEXT, 1);
411     if (odr_sequence_of(o, z_DatabaseSpecificUnit, &(*p)->elements,
412         &(*p)->num_elements))
413         return 1;
414     *p = 0;
415     return 0;
416 }
417
418 int z_ElementSetNames(ODR o, Z_ElementSetNames **p, int opt)
419 {
420     static Odr_arm arm[] =
421     {
422         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_ElementSetNames_generic,
423             z_ElementSetName},
424         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSetNames_databaseSpecific,
425             z_DatabaseSpecific},
426         {-1, -1, -1, -1, 0}
427     };
428
429     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 19))
430         return opt && odr_ok(o);
431
432     if (o->direction == ODR_DECODE)
433         *p = odr_malloc(o, sizeof(**p));
434
435     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
436         odr_constructed_end(o))
437         return 1;
438     *p = 0;
439     return 0;
440 }
441
442 /* ----------------------- RPN QUERY -----------------------*/
443
444 int z_AttributeElement(ODR o, Z_AttributeElement **p, int opt)
445 {
446     if (!odr_sequence_begin(o, p, sizeof(**p)))
447         return opt && odr_ok(o);
448     return
449         odr_implicit(o, odr_integer, &(*p)->attributeType, ODR_CONTEXT,
450             120, 0) &&
451         odr_implicit(o, odr_integer, &(*p)->attributeValue, ODR_CONTEXT,
452             121, 0) &&
453         odr_sequence_end(o);
454 }
455
456 #ifdef Z_V3
457
458 int z_Term(ODR o, Z_Term **p, int opt)
459 {
460     static Odr_arm arm[] =
461     {
462         {ODR_IMPLICIT, ODR_CONTEXT, 45, Z_Term_general, odr_octetstring},
463         {ODR_IMPLICIT, ODR_CONTEXT, 215, Z_Term_numeric, odr_integer},
464         {ODR_IMPLICIT, ODR_CONTEXT, 216, Z_Term_characterString,
465             odr_visiblestring},
466         {ODR_IMPLICIT, ODR_CONTEXT, 217, Z_Term_oid, odr_oid},
467         {ODR_IMPLICIT, ODR_CONTEXT, 218, Z_Term_dateTime, odr_cstring},
468         {ODR_IMPLICIT, ODR_CONTEXT, 219, Z_Term_external, odr_external},
469         /* add intUnit here */
470         {ODR_IMPLICIT, ODR_CONTEXT, 221, Z_Term_null, odr_null},
471         {-1, -1, -1, -1, 0}
472     };
473
474     if (o->direction ==ODR_DECODE)
475         *p = odr_malloc(o, sizeof(**p));
476     else if (!*p)
477         return opt;
478     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
479         return 1;
480     *p = 0;
481     return opt && odr_ok(o);
482 }
483
484 #endif
485
486 int z_AttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
487 {
488     if (!(odr_implicit_settag(o, ODR_CONTEXT, 102) &&
489         odr_sequence_begin(o, p, sizeof(**p))))
490         return opt && odr_ok(o);
491     return
492         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
493         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
494             &(*p)->num_attributes) &&
495         z_Term(o, &(*p)->term, 0) &&
496         odr_sequence_end(o);
497 }
498
499 int z_ProximityOperator(ODR o, Z_ProximityOperator **p, int opt)
500 {
501     static Odr_arm arm[] =
502     {
503         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ProxCode_known, odr_integer},
504         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ProxCode_private, odr_integer},
505         {-1, -1, -1, -1, 0}
506     };
507
508     if (!odr_sequence_begin(o, p, sizeof(**p)))
509         return opt && odr_ok(o);
510     return
511         odr_implicit(o, odr_bool, &(*p)->exclusion, ODR_CONTEXT, 1, 1) &&
512         odr_implicit(o, odr_integer, &(*p)->distance, ODR_CONTEXT, 2, 0) &&
513         odr_implicit(o, odr_bool, &(*p)->ordered, ODR_CONTEXT, 3, 0) &&
514         odr_implicit(o, odr_integer, &(*p)->relationType, ODR_CONTEXT, 4, 0) &&
515         odr_constructed_begin(o, &(*p)->proximityUnitCode, ODR_CONTEXT, 5) &&
516         odr_choice(o, arm, &(*p)->proximityUnitCode, &(*p)->which) &&
517         odr_constructed_end(o) &&
518         odr_sequence_end(o);
519 }
520
521 int z_Operator(ODR o, Z_Operator **p, int opt)
522 {
523     static Odr_arm arm[] =
524     {
525         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_Operator_and, odr_null},
526         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Operator_or, odr_null},
527         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_Operator_and_not, odr_null},
528         {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_Operator_prox, z_ProximityOperator},
529         {-1, -1, -1, -1, 0}
530     };
531
532     if (!*p && o->direction != ODR_DECODE)
533         return opt;
534     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 46))
535         return opt && odr_ok(o);
536     if (o->direction == ODR_DECODE)
537         *p = odr_malloc(o, sizeof(**p));
538     else
539         (*p)->u.and = ODR_NULLVAL;
540
541     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
542         odr_constructed_end(o))
543         return 1;
544     *p = 0;
545     return opt && odr_ok(o);
546 }
547
548 int z_Operand(ODR o, Z_Operand **p, int opt)
549 {
550     static Odr_arm arm[] =
551     {
552         {-1, -1, -1, Z_Operand_APT, z_AttributesPlusTerm},
553         {-1, -1, -1, Z_Operand_resultSetId, z_ResultSetId},
554         {-1, -1, -1, -1, 0}
555     };
556
557     if (o->direction ==ODR_DECODE)
558         *p = odr_malloc(o, sizeof(**p));
559     else if (!*p)
560         return opt;
561     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
562         return 1;
563     *p = 0;
564     return opt && odr_ok(o);
565 }
566
567 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt);
568
569 int z_Complex(ODR o, Z_Complex **p, int opt)
570 {
571     if (!odr_sequence_begin(o, p, sizeof(**p)))
572         return opt && odr_ok(o);
573     return
574         z_RPNStructure(o, &(*p)->s1, 0) &&
575         z_RPNStructure(o, &(*p)->s2, 0) &&
576         z_Operator(o, &(*p)->operator, 0) &&
577         odr_sequence_end(o);
578 }
579
580 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt)
581 {
582     static Odr_arm arm[] = 
583     {
584         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_RPNStructure_simple, z_Operand},
585         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_RPNStructure_complex, z_Complex},
586         {-1 -1, -1, -1, 0}
587     };
588
589     if (o->direction == ODR_DECODE)
590         *p = odr_malloc(o, sizeof(**p));
591     else if (!*p)
592         return opt;
593     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
594         return 1;
595     *p = 0;
596     return opt && odr_ok(o);
597 }
598
599 int z_RPNQuery(ODR o, Z_RPNQuery **p, int opt)
600 {
601     if (!odr_sequence_begin(o, p, sizeof(**p)))
602         return opt && odr_ok(o);
603     return
604         odr_oid(o, &(*p)->attributeSetId, 0) &&
605         z_RPNStructure(o, &(*p)->RPNStructure, 0) &&
606         odr_sequence_end(o);
607 }
608
609 /* -----------------------END RPN QUERY ----------------------- */
610
611 int z_Query(ODR o, Z_Query **p, int opt)
612 {
613     static Odr_arm arm[] = 
614     {
615         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Query_type_1, z_RPNQuery},
616         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Query_type_2, odr_octetstring},
617         {-1, -1, -1, -1, 0}
618     };
619
620     if (o->direction == ODR_DECODE)
621         *p = odr_malloc(o, sizeof(**p));
622     else if (!*p)
623         return opt;
624     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
625         return 1;
626     *p = 0;
627     return opt && odr_ok(o);
628 }
629
630 int z_SearchRequest(ODR o, Z_SearchRequest **p, int opt)
631 {
632     Z_SearchRequest *pp;
633
634     if (!odr_sequence_begin(o, p, sizeof(**p)))
635         return opt && odr_ok(o);
636     pp = *p;
637     return
638         z_ReferenceId(o, &pp->referenceId, 1) &&
639         odr_implicit(o, odr_integer, &pp->smallSetUpperBound, ODR_CONTEXT,
640             13, 0) &&
641         odr_implicit(o, odr_integer, &pp->largeSetLowerBound, ODR_CONTEXT,
642             14, 0) &&
643         odr_implicit(o, odr_integer, &pp->mediumSetPresentNumber, ODR_CONTEXT,
644             15, 0) &&
645         odr_implicit(o, odr_bool, &pp->replaceIndicator, ODR_CONTEXT, 16, 1) &&
646         odr_implicit(o, odr_visiblestring, &pp->resultSetName, ODR_CONTEXT,
647             17, 9) &&
648         odr_implicit_settag(o, ODR_CONTEXT, 18) &&
649         odr_sequence_of(o, z_DatabaseName, &pp->databaseNames,
650             &pp->num_databaseNames) &&
651         odr_explicit(o, z_ElementSetNames, &pp->smallSetElementSetNames,
652             ODR_CONTEXT, 100, 1) &&
653         odr_explicit(o, z_ElementSetNames, &pp->mediumSetElementSetNames,
654             ODR_CONTEXT, 101, 1) &&
655         odr_implicit(o, z_PreferredRecordSyntax, &pp->preferredRecordSyntax,
656             ODR_CONTEXT, 104, 1) &&
657         odr_explicit(o, z_Query, &pp->query, ODR_CONTEXT, 21, 0) &&
658 #ifdef Z_OTHERINFO
659         odr_implicit(o, z_OtherInformation, &(*p)->additionalSearchInfo,
660             ODR_CONTEXT, 203, 1) &&
661         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
662 #endif
663         odr_sequence_end(o);
664 }
665
666 /* ------------------------ RECORD ------------------------- */
667
668 int z_DatabaseRecord(ODR o, Z_DatabaseRecord **p, int opt)
669 {
670     return odr_external(o, (Odr_external **) p, opt);
671 }
672
673 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
674 {
675     if (!odr_sequence_begin(o, p, sizeof(**p)))
676         return opt && odr_ok(o);
677     return
678         odr_oid(o, &(*p)->diagnosticSetId, 1) &&       /* SHOULD NOT BE OPT */
679         odr_integer(o, &(*p)->condition, 0) &&
680         (odr_visiblestring(o, &(*p)->addinfo, 0) ||
681         odr_implicit(o, odr_cstring, &(*p)->addinfo, ODR_CONTEXT, ODR_VISIBLESTRING, 1)) &&
682         odr_sequence_end(o);
683 }
684
685 int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt)
686 {
687     static Odr_arm arm[] =
688     {
689         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_NamePlusRecord_databaseRecord,
690             z_DatabaseRecord},
691         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_NamePlusRecord_surrogateDiagnostic,
692             z_DiagRec},
693         {-1, -1, -1, -1, 0}
694     };
695
696     if (!odr_sequence_begin(o, p, sizeof(**p)))
697         return opt && odr_ok(o);
698     return
699         odr_implicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
700             0, 1) &&
701         odr_constructed_begin(o, &(*p)->u, ODR_CONTEXT, 1) &&
702         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
703         odr_constructed_end(o) &&
704         odr_sequence_end(o);
705 }
706
707 int z_NamePlusRecordList(ODR o, Z_NamePlusRecordList **p, int opt)
708 {
709     if (o->direction == ODR_DECODE)
710         *p = odr_malloc(o, sizeof(**p));
711     if (odr_sequence_of(o, z_NamePlusRecord, &(*p)->records,
712         &(*p)->num_records))
713         return 1;
714     *p = 0;
715     return 0;
716 }
717
718 int z_Records(ODR o, Z_Records **p, int opt)
719 {
720     Odr_arm arm[] = 
721     {
722         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_Records_DBOSD, z_NamePlusRecordList},
723         {ODR_IMPLICIT, ODR_CONTEXT, 130, Z_Records_NSD, z_DiagRec},
724         {-1, -1, -1, -1, 0}
725     };
726
727     if (o->direction == ODR_DECODE)
728         *p = odr_malloc(o, sizeof(**p));
729     else if (!*p)
730         return opt;
731     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
732         return 1;
733     *p = 0;
734     return opt && odr_ok(o);
735 }
736
737 /* ------------------------ ACCESS CTRL SERVICE ----------------------- */
738
739 int z_AccessControlRequest(ODR o, Z_AccessControlRequest **p, int opt)
740 {
741     static Odr_arm arm[] = 
742     {
743         {ODR_IMPLICIT, ODR_CONTEXT, 37, Z_AccessRequest_simpleForm,
744             odr_octetstring},
745         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_AccessRequest_externallyDefined,
746             odr_external},
747         {-1, -1, -1, -1, 0}
748     };
749     if (!odr_sequence_begin(o, p, sizeof(**p)))
750         return opt && odr_ok(o);
751     return
752         z_ReferenceId(o, &(*p)->referenceId, 1) &&
753         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
754 #ifdef Z_OTHERINFO
755         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
756 #endif
757         odr_sequence_end(o);
758 }
759
760 int z_AccessControlResponse(ODR o, Z_AccessControlResponse **p, int opt)
761 {
762     static Odr_arm arm[] = 
763     {
764         {ODR_IMPLICIT, ODR_CONTEXT, 38, Z_AccessResponse_simpleForm,
765             odr_octetstring},
766         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_AccessResponse_externallyDefined,
767             odr_external},
768         {-1, -1, -1, -1, 0}
769     };
770     if (!odr_sequence_begin(o, p, sizeof(**p)))
771         return opt && odr_ok(o);
772     return
773         z_ReferenceId(o, &(*p)->referenceId, 1) &&
774         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
775         odr_explicit(o, z_DiagRec, &(*p)->diagnostic, ODR_CONTEXT, 223, 1) &&
776 #ifdef Z_OTHERINFO
777         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
778 #endif
779         odr_sequence_end(o);
780 }
781
782 /* ------------------------ SCAN SERVICE -------------------- */
783
784 int z_AttributeList(ODR o, Z_AttributeList **p, int opt)
785 {
786     if (o->direction == ODR_DECODE)
787         *p = odr_malloc(o, sizeof(**p));
788     else if (!*p)
789         return opt;
790
791     odr_implicit_settag(o, ODR_CONTEXT, 44);
792     if (odr_sequence_of(o, z_AttributeElement, &(*p)->attributes,
793         &(*p)->num_attributes))
794         return 1;
795     *p = 0;
796     return opt && odr_ok(o);
797 }
798
799 /*
800  * This is a temporary hack. We don't know just *what* old version of the
801  * protocol willow uses, so we'll just patiently wait for them to update
802  */
803 static int willow_scan = 0;
804
805 int z_WillowAttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
806 {
807     if (!*p && o->direction != ODR_DECODE)
808         return opt;
809     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 4))
810     {
811         o->t_class = -1;
812         return opt && odr_ok(o);
813     }
814     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 1))
815         return 0;
816     if (!odr_constructed_begin(o, p, ODR_UNIVERSAL, ODR_SEQUENCE))
817         return 0;
818     if (!odr_implicit_settag(o, ODR_CONTEXT, 44))
819         return 0;
820     if (o->direction == ODR_DECODE)
821         *p = odr_malloc(o, sizeof(**p));
822     if (!odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
823         &(*p)->num_attributes))
824         return 0;
825     if (!odr_sequence_end(o) || !odr_sequence_end(o))
826         return 0;
827     if (!z_Term(o, &(*p)->term, 0))
828         return 0;
829     if (!odr_constructed_end(o))
830         return 0;
831     willow_scan = 1;
832     return 1;
833 }
834
835 int z_AlternativeTerm(ODR o, Z_AlternativeTerm **p, int opt)
836 {
837     if (o->direction == ODR_DECODE)
838         *p = odr_malloc(o, sizeof(**p));
839     else if (!*p)
840     {
841         o->t_class = -1;
842         return opt && odr_ok(o);
843     }
844
845     if (odr_sequence_of(o, z_AttributesPlusTerm, &(*p)->terms,
846         &(*p)->num_terms))
847         return 1;
848     *p = 0;
849     return opt && !o->error;
850 }
851
852 int z_OccurrenceByAttributes(ODR o, Z_OccurrenceByAttributes **p, int opt)
853 {
854     if (!odr_sequence_begin(o, p, sizeof(**p)))
855         return opt && odr_ok(o);
856     return
857         odr_explicit(o, z_AttributeList, &(*p)->attributes, ODR_CONTEXT, 1, 1)&&
858         odr_explicit(o, odr_integer, &(*p)->global, ODR_CONTEXT, 2, 1) &&
859         odr_sequence_end(o);
860 }
861
862 int z_TermInfo(ODR o, Z_TermInfo **p, int opt)
863 {
864     if (!odr_sequence_begin(o, p, sizeof(**p)))
865         return opt && odr_ok(o);
866     return
867         (willow_scan ? 
868             odr_implicit(o, z_Term, &(*p)->term, ODR_CONTEXT, 1, 0) :
869             z_Term(o, &(*p)->term, 0)) &&
870         z_AttributeList(o, &(*p)->suggestedAttributes, 1) &&
871         odr_implicit(o, z_AlternativeTerm, &(*p)->alternativeTerm,
872             ODR_CONTEXT, 4, 1) &&
873         odr_implicit(o, odr_integer, &(*p)->globalOccurrences, ODR_CONTEXT,
874             2, 1) &&
875         odr_implicit(o, z_OccurrenceByAttributes, &(*p)->byAttributes,
876             ODR_CONTEXT, 3, 1) &&
877         odr_sequence_end(o);
878 }
879
880 int z_Entry(ODR o, Z_Entry **p, int opt)
881 {
882     static Odr_arm arm[] =
883     {
884         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Entry_termInfo, z_TermInfo},
885         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Entry_surrogateDiagnostic,
886             z_DiagRec},
887         {-1, -1, -1, -1, 0}
888     };
889
890     if (o->direction == ODR_DECODE)
891         *p = odr_malloc(o, sizeof(**p));
892
893     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
894         return 1;
895     *p = 0;
896     return opt && odr_ok(o);
897 }
898
899 int z_Entries(ODR o, Z_Entries **p, int opt)
900 {
901     if (o->direction == ODR_DECODE)
902         *p = odr_malloc(o, sizeof(**p));
903     else if (!*p)
904         return opt;
905
906     if (odr_sequence_of(o, z_Entry, &(*p)->entries,
907         &(*p)->num_entries))
908         return 1;
909     *p = 0;
910     return 0;
911 }
912
913 int z_DiagRecs(ODR o, Z_DiagRecs **p, int opt)
914 {
915     if (o->direction == ODR_DECODE)
916         *p = odr_malloc(o, sizeof(**p));
917     else if (!*p)
918         return opt;
919
920         if (odr_sequence_of(o, z_DiagRec, &(*p)->diagRecs,
921         &(*p)->num_diagRecs))
922         return 1;
923     *p = 0;
924     return 0;
925 }
926
927 int z_ListEntries(ODR o, Z_ListEntries **p, int opt)
928 {
929     static Odr_arm arm[] =
930     {
931         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ListEntries_entries, z_Entries},
932         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_ListEntries_nonSurrogateDiagnostics,
933             z_DiagRecs},
934         {-1, -1, -1, -1, 0}
935     };
936
937     if (o->direction == ODR_DECODE)
938         *p = odr_malloc(o, sizeof(**p));
939
940     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
941         return 1;
942     *p = 0;
943     return opt && odr_ok(o);
944 }
945
946 int z_ScanRequest(ODR o, Z_ScanRequest **p, int opt)
947 {
948     if (!odr_sequence_begin(o, p, sizeof(**p)))
949         return opt && odr_ok(o);
950     willow_scan = 0;
951     return
952         z_ReferenceId(o, &(*p)->referenceId, 1) &&
953         odr_implicit_settag(o, ODR_CONTEXT, 3) &&
954         odr_sequence_of(o, z_DatabaseName, &(*p)->databaseNames,
955             &(*p)->num_databaseNames) &&
956         odr_oid(o, &(*p)->attributeSet, 1) &&
957         (z_AttributesPlusTerm(o, &(*p)->termListAndStartPoint, 1) ?
958             ((*p)->termListAndStartPoint ? 1 : 
959         z_WillowAttributesPlusTerm(o, &(*p)->termListAndStartPoint, 0)) : 0) &&
960         odr_implicit(o, odr_integer, &(*p)->stepSize, ODR_CONTEXT, 5, 1) &&
961         odr_implicit(o, odr_integer, &(*p)->numberOfTermsRequested,
962             ODR_CONTEXT, 6, 0) &&
963         odr_implicit(o, odr_integer, &(*p)->preferredPositionInResponse,
964             ODR_CONTEXT, 7, 1) &&
965         odr_sequence_end(o);
966 }
967
968 int z_ScanResponse(ODR o, Z_ScanResponse **p, int opt)
969 {
970     if (!odr_sequence_begin(o, p, sizeof(**p)))
971         return opt && odr_ok(o);
972     return
973         z_ReferenceId(o, &(*p)->referenceId, 1) &&
974         odr_implicit(o, odr_integer, &(*p)->stepSize, ODR_CONTEXT, 3, 1) &&
975         odr_implicit(o, odr_integer, &(*p)->scanStatus, ODR_CONTEXT, 4, 0) &&
976         odr_implicit(o, odr_integer, &(*p)->numberOfEntriesReturned,
977             ODR_CONTEXT, 5, 0) &&
978         odr_implicit(o, odr_integer, &(*p)->positionOfTerm, ODR_CONTEXT, 6, 1)&&
979         odr_explicit(o, z_ListEntries, &(*p)->entries, ODR_CONTEXT, 7, 1) &&
980         odr_implicit(o, odr_oid, &(*p)->attributeSet, ODR_CONTEXT, 8, 1) &&
981         odr_sequence_end(o);
982 }
983
984 /* ------------------------ SEARCHRESPONSE ----------------*/
985
986 int z_NumberOfRecordsReturned(ODR o, int **p, int opt)
987 {
988     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 24, opt);
989 }
990
991 int z_NextResultSetPosition(ODR o, int **p, int opt)
992 {
993     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 25, opt);
994 }
995
996 int z_PresentStatus(ODR o, int **p, int opt)
997 {
998     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 27, opt);
999 }
1000
1001 int z_SearchResponse(ODR o, Z_SearchResponse **p, int opt)
1002 {
1003     Z_SearchResponse *pp;
1004
1005     if (!odr_sequence_begin(o, p, sizeof(**p)))
1006         return opt && odr_ok(o);
1007     pp = *p;
1008     return
1009         z_ReferenceId(o, &pp->referenceId, 1) &&
1010         odr_implicit(o, odr_integer, &pp->resultCount, ODR_CONTEXT, 23, 0) &&
1011         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
1012         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
1013         odr_implicit(o, odr_bool, &pp->searchStatus, ODR_CONTEXT, 22, 0) &&
1014         odr_implicit(o, odr_integer, &pp->resultSetStatus, ODR_CONTEXT, 26, 1) &&
1015         z_PresentStatus(o, &pp->presentStatus, 1) &&
1016         z_Records(o, &pp->records, 1) &&
1017 #ifdef Z_OTHERINFO
1018         odr_implicit(o, z_OtherInformation, &(*p)->additionalSearchInfo,
1019             ODR_CONTEXT, 203, 1) &&
1020         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1021 #endif
1022         odr_sequence_end(o);
1023 }
1024
1025 /* --------------------- PRESENT SERVICE ---------------------- */
1026
1027 int z_PresentRequest(ODR o, Z_PresentRequest **p, int opt)
1028 {
1029     Z_PresentRequest *pp;
1030
1031     if (!odr_sequence_begin(o, p, sizeof(**p)))
1032         return opt && odr_ok(o);
1033     pp = *p;
1034     return
1035         z_ReferenceId(o, &pp->referenceId, 1) &&
1036         z_ResultSetId(o, &pp->resultSetId, 0) &&
1037         odr_implicit(o, odr_integer, &pp->resultSetStartPoint, ODR_CONTEXT,
1038             30, 0) &&
1039         odr_implicit(o, odr_integer, &pp->numberOfRecordsRequested, ODR_CONTEXT,
1040             29, 0) &&
1041         z_ElementSetNames(o, &pp->elementSetNames, 1) &&
1042         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
1043         odr_sequence_end(o);
1044 }
1045
1046 int z_PresentResponse(ODR o, Z_PresentResponse **p, int opt)
1047 {
1048     Z_PresentResponse *pp;
1049
1050     if (!odr_sequence_begin(o, p, sizeof(**p)))
1051         return opt && odr_ok(o);
1052     pp = *p;
1053     return
1054         z_ReferenceId(o, &pp->referenceId, 1) &&
1055         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
1056         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
1057         z_PresentStatus(o, &pp->presentStatus, 0) &&
1058         z_Records(o, &pp->records, 1) &&
1059         odr_sequence_end(o);
1060 }
1061
1062 /* ----------------------DELETE -------------------------- */
1063
1064 int z_DeleteSetStatus(ODR o, int **p, int opt)
1065 {
1066     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 33, opt);
1067 }
1068
1069 int z_ListStatus(ODR o, Z_ListStatus **p, int opt)
1070 {
1071     if (!odr_sequence_begin(o, p, sizeof(**p)))
1072         return opt && odr_ok(o);
1073     return
1074         z_ResultSetId(o, &(*p)->id, 0) &&
1075         z_DeleteSetStatus(o, &(*p)->status, 0) &&
1076         odr_sequence_end(o);
1077 }
1078
1079 int z_DeleteResultSetRequest(ODR o, Z_DeleteResultSetRequest **p, int opt)
1080 {
1081     if (!odr_sequence_begin(o, p, sizeof(**p)))
1082         return opt && odr_ok(o);
1083     return
1084         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1085         odr_implicit(o, odr_integer, &(*p)->deleteFunction, ODR_CONTEXT, 32,
1086             0) &&
1087         (odr_sequence_of(o, z_ListStatus, &(*p)->resultSetList,
1088             &(*p)->num_ids) || odr_ok(o)) &&
1089 #ifdef Z_OTHERINFO
1090         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1091 #endif
1092         odr_sequence_end(o);
1093 }
1094
1095 int z_DeleteResultSetResponse(ODR o, Z_DeleteResultSetResponse **p, int opt)
1096 {
1097     if (!odr_sequence_begin(o, p, sizeof(**p)))
1098         return opt && odr_ok(o);
1099     return
1100         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1101         odr_implicit(o, z_DeleteSetStatus, &(*p)->deleteOperationStatus,
1102             ODR_CONTEXT, 0, 1) &&
1103         odr_implicit_settag(o, ODR_CONTEXT, 1) &&
1104         (odr_sequence_of(o, z_ListStatus, &(*p)->deleteListStatuses,
1105             &(*p)->num_statuses) || odr_ok(o)) &&
1106         odr_implicit(o, odr_integer, &(*p)->numberNotDeleted, ODR_CONTEXT,
1107             34, 1) &&
1108         odr_implicit_settag(o, ODR_CONTEXT, 35) &&
1109         (odr_sequence_of(o, z_ListStatus, &(*p)->bulkStatuses,
1110             &(*p)->num_bulkStatuses) || odr_ok(o)) &&
1111         odr_implicit(o, odr_visiblestring, &(*p)->deleteMessage, ODR_CONTEXT,
1112             36, 1) &&
1113 #ifdef Z_OTHERINFO
1114         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1115 #endif
1116         odr_sequence_end(o);
1117 }
1118
1119 /* ------------------------ CLOSE SERVICE ---------------- */
1120
1121 int z_Close(ODR o, Z_Close **p, int opt)
1122 {
1123     if (!odr_sequence_begin(o, p, sizeof(**p)))
1124         return opt && odr_ok(o);
1125     return
1126         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1127         odr_implicit(o, odr_integer, &(*p)->closeReason, ODR_CONTEXT, 211, 0) &&
1128         odr_implicit(o, odr_visiblestring, &(*p)->diagnosticInformation,
1129             ODR_CONTEXT, 3, 1) &&
1130         odr_implicit(o, odr_oid, &(*p)->resourceReportFormat, ODR_CONTEXT,
1131             4, 1) &&
1132         odr_implicit(o, odr_external, &(*p)->resourceReport, ODR_CONTEXT,
1133             5, 1) &&
1134 #ifdef Z_OTHERINFO
1135         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1136 #endif
1137         odr_sequence_end(o);
1138 }
1139
1140 /* ------------------------ APDU ------------------------- */
1141
1142 int z_APDU(ODR o, Z_APDU **p, int opt)
1143 {
1144     static Odr_arm arm[] =
1145     {
1146         {ODR_IMPLICIT, ODR_CONTEXT, 20, Z_APDU_initRequest, z_InitRequest},
1147         {ODR_IMPLICIT, ODR_CONTEXT, 21, Z_APDU_initResponse, z_InitResponse},
1148         {ODR_IMPLICIT, ODR_CONTEXT, 22, Z_APDU_searchRequest, z_SearchRequest},
1149         {ODR_IMPLICIT, ODR_CONTEXT, 23, Z_APDU_searchResponse,
1150             z_SearchResponse},
1151         {ODR_IMPLICIT, ODR_CONTEXT, 24, Z_APDU_presentRequest,
1152             z_PresentRequest},
1153         {ODR_IMPLICIT, ODR_CONTEXT, 25, Z_APDU_presentResponse,
1154             z_PresentResponse},
1155         {ODR_IMPLICIT, ODR_CONTEXT, 26, Z_APDU_deleteResultSetRequest,
1156             z_DeleteResultSetRequest},
1157         {ODR_IMPLICIT, ODR_CONTEXT, 27, Z_APDU_deleteResultSetResponse,
1158             z_DeleteResultSetResponse},
1159         {ODR_IMPLICIT, ODR_CONTEXT, 30, Z_APDU_resourceControlRequest,
1160             z_ResourceControlRequest},
1161         {ODR_IMPLICIT, ODR_CONTEXT, 31, Z_APDU_resourceControlResponse,
1162             z_ResourceControlResponse},
1163         {ODR_IMPLICIT, ODR_CONTEXT, 32, Z_APDU_triggerResourceControlRequest,
1164             z_TriggerResourceControlRequest},
1165         {ODR_IMPLICIT, ODR_CONTEXT, 35, Z_APDU_scanRequest, z_ScanRequest},
1166         {ODR_IMPLICIT, ODR_CONTEXT, 36, Z_APDU_scanResponse, z_ScanResponse},
1167         {ODR_IMPLICIT, ODR_CONTEXT, 48, Z_APDU_close, z_Close},
1168
1169         {-1, -1, -1, -1, 0}
1170     };
1171
1172     if (o->direction == ODR_DECODE)
1173         *p = odr_malloc(o, sizeof(**p));
1174     if (!odr_choice(o, arm, &(*p)->u, &(*p)->which))
1175     {
1176         if (o->direction == ODR_DECODE)
1177             *p = 0;
1178         return opt && odr_ok(o);
1179     }
1180     return 1;
1181 }