*** empty log message ***
[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.46  1996-04-10 11:39:42  quinn
8  * Fixed bug in UserInfo
9  *
10  * Revision 1.45  1996/02/23  10:00:25  quinn
11  * Fixes to SCAN
12  *
13  * Revision 1.44  1996/02/20  12:51:41  quinn
14  * Completed SCAN. Fixed problems with EXTERNAL.
15  *
16  * Revision 1.43  1996/02/10  12:22:49  quinn
17  * Work on SCAN
18  *
19  * Revision 1.42  1996/01/22  09:46:31  quinn
20  * Added Sort PDU. Moved StringList to main protocol file.
21  *
22  * Revision 1.41  1996/01/10  15:21:24  quinn
23  * Added links to access control PDUs
24  *
25  * Revision 1.40  1996/01/02  11:46:40  quinn
26  * Changed 'operator' to 'roperator' to avoid C++ conflict.
27  *
28  * Revision 1.39  1995/09/29  17:11:53  quinn
29  * Smallish
30  *
31  * Revision 1.38  1995/09/27  15:02:40  quinn
32  * Modified function heads & prototypes.
33  *
34  * Revision 1.37  1995/08/21  09:10:15  quinn
35  * Smallish fixes to suppport new formats.
36  *
37  * Revision 1.36  1995/08/15  11:59:39  quinn
38  * Updated External
39  *
40  * Revision 1.35  1995/08/10  08:53:59  quinn
41  * Added Explain
42  *
43  * Revision 1.34  1995/06/19  17:01:48  quinn
44  * This should bring us in sync with the version distributed as 1.0b
45  *
46  * Revision 1.33  1995/06/19  13:39:56  quinn
47  * *** empty log message ***
48  *
49  * Revision 1.32  1995/06/19  12:37:28  quinn
50  * Fixed a bug in the compspec.
51  *
52  * Revision 1.31  1995/06/16  13:15:56  quinn
53  * Fixed Defaultdiagformat.
54  *
55  * Revision 1.30  1995/06/15  15:42:01  quinn
56  * Fixed some v3 bugs
57  *
58  * Revision 1.29  1995/06/15  07:44:49  quinn
59  * Moving to v3.
60  *
61  * Revision 1.28  1995/06/14  15:26:35  quinn
62  * *** empty log message ***
63  *
64  * Revision 1.27  1995/06/07  14:36:22  quinn
65  * Added CLOSE
66  *
67  * Revision 1.26  1995/06/02  09:49:13  quinn
68  * Adding access control
69  *
70  * Revision 1.25  1995/05/25  11:00:08  quinn
71  * *** empty log message ***
72  *
73  * Revision 1.24  1995/05/22  13:58:18  quinn
74  * Fixed an ODR_NULLVAL.
75  *
76  * Revision 1.23  1995/05/22  11:30:18  quinn
77  * Adding Z39.50-1992 stuff to proto.c. Adding zget.c
78  *
79  * Revision 1.22  1995/05/17  08:40:56  quinn
80  * Added delete. Fixed some sequence_begins. Smallish.
81  *
82  * Revision 1.21  1995/05/16  08:50:24  quinn
83  * License, documentation, and memory fixes
84  *
85  * Revision 1.20  1995/05/15  11:55:25  quinn
86  * Smallish.
87  *
88  * Revision 1.19  1995/04/11  11:58:35  quinn
89  * Fixed bug.
90  *
91  * Revision 1.18  1995/04/11  11:52:02  quinn
92  * Fixed possible buf in proto.c
93  *
94  * Revision 1.17  1995/04/10  10:22:22  quinn
95  * Added SCAN.
96  *
97  * Revision 1.16  1995/03/30  10:26:43  quinn
98  * Added Term structure
99  *
100  * Revision 1.15  1995/03/30  09:08:39  quinn
101  * Added Resource control protocol
102  *
103  * Revision 1.14  1995/03/29  08:06:13  quinn
104  * Added a few v3 elements
105  *
106  * Revision 1.13  1995/03/20  11:26:52  quinn
107  * *** empty log message ***
108  *
109  * Revision 1.12  1995/03/20  09:45:09  quinn
110  * Working towards v3
111  *
112  * Revision 1.11  1995/03/17  10:17:25  quinn
113  * Added memory management.
114  *
115  * Revision 1.10  1995/03/15  11:17:40  quinn
116  * Fixed some return-checks from choice.. need better ay to handle those..
117  *
118  * Revision 1.9  1995/03/15  08:37:06  quinn
119  * Fixed protocol bugs.
120  *
121  * Revision 1.8  1995/03/14  16:59:24  quinn
122  * Fixed OPTIONAL flag in attributeelement
123  *
124  * Revision 1.7  1995/03/07  16:29:33  quinn
125  * Added authentication stuff.
126  *
127  * Revision 1.6  1995/03/01  14:46:03  quinn
128  * Fixed protocol bug in 8777query.
129  *
130  * Revision 1.5  1995/02/14  11:54:22  quinn
131  * Fixing include.
132  *
133  * Revision 1.4  1995/02/10  15:54:30  quinn
134  * Small adjustments.
135  *
136  * Revision 1.3  1995/02/09  15:51:39  quinn
137  * Works better now.
138  *
139  * Revision 1.2  1995/02/06  21:26:07  quinn
140  * Repaired this evening's damages..
141  *
142  * Revision 1.1  1995/02/06  16:44:47  quinn
143  * First hack at Z/SR protocol
144  *
145  */
146
147 #include <odr.h>
148
149 #include <proto.h>
150
151 /* ---------------------- GLOBAL DEFS ------------------- */
152
153 /*
154  * We'll use a general octetstring here, since string operations are
155  * clumsy on long strings.
156  */
157 int z_SUTRS(ODR o, Odr_oct **p, int opt)
158 {
159     return odr_implicit(o, odr_octetstring, p, ODR_UNIVERSAL,
160         ODR_GENERALSTRING, opt);
161 }
162
163 int z_ReferenceId(ODR o, Z_ReferenceId **p, int opt)
164 {
165     return odr_implicit(o, odr_octetstring, (Odr_oct**) p, ODR_CONTEXT, 2, opt);
166 }
167
168 int z_DatabaseName(ODR o, Z_DatabaseName **p, int opt)
169 {
170     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 105,
171         opt);
172 }
173
174 int z_ResultSetId(ODR o, char **p, int opt)
175 {
176     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 31,
177         opt);
178 }
179
180 int z_ElementSetName(ODR o, char **p, int opt)
181 {
182     return odr_implicit(o, odr_visiblestring, p, ODR_CONTEXT, 103, opt);
183 }
184
185 int z_UserInformationField(ODR o, Z_External **p, int opt)
186 {
187     return odr_explicit(o, z_External, (Z_External **)p, ODR_CONTEXT,
188         11, opt);
189 }
190
191 int z_InternationalString(ODR o, char **p, int opt)
192 {
193     return odr_generalstring(o, p, opt);
194 }
195
196 int z_InfoCategory(ODR o, Z_InfoCategory **p, int opt)
197 {
198     if (!odr_sequence_begin(o, p, sizeof(**p)))
199         return opt && odr_ok(o);
200     return
201         odr_implicit(o, odr_oid, &(*p)->categoryTypeId, ODR_CONTEXT, 1, 1) &&
202         odr_implicit(o, odr_integer, &(*p)->categoryValue, ODR_CONTEXT, 2, 0) &&
203         odr_sequence_end(o);
204 }
205
206 int z_OtherInformationUnit(ODR o, Z_OtherInformationUnit **p, int opt)
207 {
208     static Odr_arm arm[] =
209     {
210         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_OtherInfo_characterInfo,
211             odr_visiblestring},
212         {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_OtherInfo_binaryInfo,
213             odr_octetstring},
214         {ODR_IMPLICIT, ODR_CONTEXT, 4, Z_OtherInfo_externallyDefinedInfo,
215             z_External},
216         {ODR_IMPLICIT, ODR_CONTEXT, 5, Z_OtherInfo_oid, odr_oid},
217         {-1, -1, -1, -1, 0}
218     };
219
220     if (!odr_sequence_begin(o, p, sizeof(**p)))
221         return opt && odr_ok(o);
222     return
223         odr_implicit(o, z_InfoCategory, &(*p)->category, ODR_CONTEXT, 1, 1) &&
224         odr_choice(o, arm, &(*p)->information, &(*p)->which) &&
225         odr_sequence_end(o);
226 }
227     
228 int z_OtherInformation(ODR o, Z_OtherInformation **p, int opt)
229 {
230     if (o->direction == ODR_DECODE)
231         *p = odr_malloc(o, sizeof(**p));
232     else if (!*p)
233         return opt;
234     odr_implicit_settag(o, ODR_CONTEXT, 201);
235     if (odr_sequence_of(o, z_OtherInformationUnit, &(*p)->list,
236         &(*p)->num_elements))
237         return 1;
238     *p = 0;
239     return opt && odr_ok(o);
240 }
241
242 int z_StringOrNumeric(ODR o, Z_StringOrNumeric **p, int opt)
243 {
244     static Odr_arm arm[] =
245     {
246         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_StringOrNumeric_string,
247             odr_visiblestring},
248         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_StringOrNumeric_numeric,
249             odr_integer},
250         {-1, -1, -1, -1, 0}
251     };
252
253     if (o->direction == ODR_DECODE)
254         *p = odr_malloc(o, sizeof(**p));
255     else if (!*p)
256         return opt;
257     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
258         return 1;
259     *p = 0;
260     return opt && odr_ok(o);
261 }
262
263 /*
264  * check tagging!!
265  */
266 int z_Unit(ODR o, Z_Unit **p, int opt)
267 {
268     if (!odr_sequence_begin(o, p, sizeof(**p)))
269         return opt && odr_ok(o);
270     return
271         odr_implicit(o, odr_visiblestring, &(*p)->unitSystem, ODR_CONTEXT,
272             1, 1) &&
273         odr_explicit(o, z_StringOrNumeric, &(*p)->unitType, ODR_CONTEXT,
274             2, 1) &&
275         odr_explicit(o, z_StringOrNumeric, &(*p)->unit, ODR_CONTEXT, 3, 1) &&
276         odr_implicit(o, odr_integer, &(*p)->scaleFactor, ODR_CONTEXT, 4, 1) &&
277         odr_sequence_end(o);
278 }
279
280 int z_IntUnit(ODR o, Z_IntUnit **p, int opt)
281 {
282     if (!odr_sequence_begin(o, p, sizeof(**p)))
283         return opt && odr_ok(o);
284     return
285         odr_implicit(o, odr_integer, &(*p)->value, ODR_CONTEXT, 1, 0) &&
286         odr_implicit(o, z_Unit, &(*p)->unitUsed, ODR_CONTEXT, 2, 0) &&
287         odr_sequence_end(o);
288 }
289
290 int z_StringList(ODR o, Z_StringList **p, int opt)
291 {
292     if (o->direction == ODR_DECODE)
293         *p = odr_malloc(o, sizeof(**p));
294     else if (!*p)
295         return opt;
296     if (odr_sequence_of(o, z_InternationalString, &(*p)->strings,
297         &(*p)->num_strings))
298         return 1;
299     *p = 0;
300     return opt && odr_ok(o);
301 }
302
303 /* ---------------------- INITIALIZE SERVICE ------------------- */
304
305 #if 0
306 int z_NSRAuthentication(ODR o, Z_NSRAuthentication **p, int opt)
307 {
308     if (!odr_sequence_begin(o, p, sizeof(**p)))
309         return opt && odr_ok(o);
310     return
311         odr_visiblestring(o, &(*p)->user, 0) &&
312         odr_visiblestring(o, &(*p)->password, 0) &&
313         odr_visiblestring(o, &(*p)->account, 0) &&
314         odr_sequence_end(o);
315 }
316 #endif
317
318 int z_IdPass(ODR o, Z_IdPass **p, int opt)
319 {
320     if (!odr_sequence_begin(o, p, sizeof(**p)))
321         return opt && odr_ok(o);
322     return
323         odr_implicit(o, odr_visiblestring, &(*p)->groupId, ODR_CONTEXT, 0, 1) &&
324         odr_implicit(o, odr_visiblestring, &(*p)->userId, ODR_CONTEXT, 1, 1) &&
325         odr_implicit(o, odr_visiblestring, &(*p)->password, ODR_CONTEXT, 2,
326             1) &&
327         odr_sequence_end(o);
328 }
329
330 int z_StrAuthentication(ODR o, char **p, int opt)
331 {
332     return odr_visiblestring(o, p, opt);
333 }
334
335 int z_IdAuthentication(ODR o, Z_IdAuthentication **p, int opt)
336 {
337     static Odr_arm arm[] =
338     {
339         {-1, -1, -1, Z_IdAuthentication_open, z_StrAuthentication},
340         {-1, -1, -1, Z_IdAuthentication_idPass, z_IdPass},
341         {-1, -1, -1, Z_IdAuthentication_anonymous, odr_null},
342         {-1, -1, -1, Z_IdAuthentication_other, z_External},
343         {-1, -1, -1, -1, 0}
344     };
345
346     if (o->direction == ODR_DECODE)
347         *p = odr_malloc(o, sizeof(**p));
348     else if (!*p)
349         return opt;
350
351     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
352         return 1;
353     *p = 0;
354     return opt && odr_ok(o);
355 }
356
357 int z_InitRequest(ODR o, Z_InitRequest **p, int opt)
358 {
359     Z_InitRequest *pp;
360
361     if (!odr_sequence_begin(o, p, sizeof(**p)))
362         return opt && odr_ok(o);
363     pp = *p;
364     return
365         z_ReferenceId(o, &pp->referenceId, 1) &&
366         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
367             3, 0) &&
368         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
369         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
370             5, 0) &&
371         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
372             6, 0) &&
373         odr_explicit(o, z_IdAuthentication, &pp->idAuthentication, ODR_CONTEXT,
374             7, 1) &&
375         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
376             110, 1) &&
377         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
378             111, 1) &&
379         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
380             ODR_CONTEXT, 112, 1) &&
381         z_UserInformationField(o, &pp->userInformationField, 1) &&
382 #ifdef Z_95
383         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
384 #endif
385         odr_sequence_end(o);
386 }
387
388 int z_InitResponse(ODR o, Z_InitResponse **p, int opt)
389 {
390     Z_InitResponse *pp;
391
392     if (!odr_sequence_begin(o, p, sizeof(**p)))
393         return opt && odr_ok(o);
394     pp = *p;
395     return
396         z_ReferenceId(o, &pp->referenceId, 1) &&
397         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
398             3, 0) &&
399         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
400         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
401             5, 0) &&
402         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
403             6, 0) &&
404         odr_implicit(o, odr_bool, &pp->result, ODR_CONTEXT, 12, 0) &&
405         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
406             110, 1) &&
407         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
408             111, 1) &&
409         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
410             ODR_CONTEXT, 112, 1) &&
411         z_UserInformationField(o, &pp->userInformationField, 1) &&
412 #ifdef Z_95
413         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
414 #endif
415         odr_sequence_end(o);
416 }
417
418 /* ------------------ RESOURCE CONTROL ----------------*/
419
420 int z_TriggerResourceControlRequest(ODR o, Z_TriggerResourceControlRequest **p,
421                                     int opt)
422 {
423     if (!odr_sequence_begin(o, p, sizeof(**p)))
424         return opt && odr_ok(o);
425     return
426         z_ReferenceId(o, &(*p)->referenceId, 1) &&
427         odr_implicit(o, odr_integer, &(*p)->requestedAction, ODR_CONTEXT,
428             46, 0) &&
429         odr_implicit(o, odr_oid, &(*p)->prefResourceReportFormat,
430             ODR_CONTEXT, 47, 1) &&
431         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
432             48, 1) &&
433 #ifdef Z_95
434         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
435 #endif
436         odr_sequence_end(o);
437 }
438
439 int z_ResourceControlRequest(ODR o, Z_ResourceControlRequest **p, int opt)
440 {
441     if (!odr_sequence_begin(o, p, sizeof(**p)))
442         return opt && odr_ok(o);
443     return
444         z_ReferenceId(o, &(*p)->referenceId, 1) &&
445         odr_implicit(o, odr_bool, &(*p)->suspendedFlag, ODR_CONTEXT, 39, 1)&&
446         odr_explicit(o, z_External, &(*p)->resourceReport, ODR_CONTEXT,
447             40, 1) &&
448         odr_implicit(o, odr_integer, &(*p)->partialResultsAvailable,
449             ODR_CONTEXT, 41, 1) &&
450         odr_implicit(o, odr_bool, &(*p)->responseRequired, ODR_CONTEXT,
451             42, 0) &&
452         odr_implicit(o, odr_bool, &(*p)->triggeredRequestFlag,
453             ODR_CONTEXT, 43, 1) &&
454 #ifdef Z_95
455         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
456 #endif
457         odr_sequence_end(o);
458 }
459
460 int z_ResourceControlResponse(ODR o, Z_ResourceControlResponse **p, int opt)
461 {
462     if (!odr_sequence_begin(o, p, sizeof(**p)))
463         return opt && odr_ok(o);
464     return
465         z_ReferenceId(o, &(*p)->referenceId, 1) &&
466         odr_implicit(o, odr_bool, &(*p)->continueFlag, ODR_CONTEXT, 44, 0) &&
467         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
468             45, 1) &&
469 #ifdef Z_95
470         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
471 #endif
472         odr_sequence_end(o);
473 }
474
475 /* ------------------------ SEARCH SERVICE ----------------------- */
476
477 int z_DatabaseSpecificUnit(ODR o, Z_DatabaseSpecificUnit **p, int opt)
478 {
479     if (!odr_sequence_begin(o, p, sizeof(**p)))
480         return opt && odr_ok(o);
481     return
482         z_DatabaseName(o, &(*p)->databaseName, 0) &&
483         z_ElementSetName(o, &(*p)->elementSetName, 0) &&
484         odr_sequence_end(o);
485 }
486
487 int z_DatabaseSpecific(ODR o, Z_DatabaseSpecific **p, int opt)
488 {
489     if (o->direction == ODR_DECODE)
490         *p = odr_malloc(o, sizeof(**p));
491     else if (!*p)
492         return opt;
493
494     odr_implicit_settag(o, ODR_CONTEXT, 1);
495     if (odr_sequence_of(o, z_DatabaseSpecificUnit, &(*p)->elements,
496         &(*p)->num_elements))
497         return 1;
498     *p = 0;
499     return 0;
500 }
501
502 int z_ElementSetNames(ODR o, Z_ElementSetNames **p, int opt)
503 {
504     static Odr_arm arm[] =
505     {
506         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_ElementSetNames_generic,
507             z_ElementSetName},
508         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSetNames_databaseSpecific,
509             z_DatabaseSpecific},
510         {-1, -1, -1, -1, 0}
511     };
512
513     if (o->direction == ODR_DECODE)
514         *p = odr_malloc(o, sizeof(**p));
515     else if (!*p)
516         return opt && odr_ok(o);
517
518     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
519         return 1;
520     *p = 0;
521     return 0;
522 }
523
524 /* ----------------------- RPN QUERY -----------------------*/
525
526 int z_ComplexAttribute(ODR o, Z_ComplexAttribute **p, int opt)
527 {
528     if (!odr_sequence_begin(o, p, sizeof(**p)))
529         return opt && odr_ok(o);
530     return
531         odr_implicit_settag(o, ODR_CONTEXT, 1) &&
532         odr_sequence_of(o, z_StringOrNumeric, &(*p)->list,
533             &(*p)->num_list) &&
534         odr_implicit_settag(o, ODR_CONTEXT, 2) &&
535         (odr_sequence_of(o, odr_integer, &(*p)->semanticAction,
536             &(*p)->num_semanticAction) || odr_ok(o)) &&
537         odr_sequence_end(o);
538 }
539
540 int z_AttributeElement(ODR o, Z_AttributeElement **p, int opt)
541 {
542 #ifdef Z_95
543     static Odr_arm arm[] =
544     {
545         {ODR_IMPLICIT, ODR_CONTEXT, 121, Z_AttributeValue_numeric,
546             odr_integer},
547         {ODR_IMPLICIT, ODR_CONTEXT, 224, Z_AttributeValue_complex,
548             z_ComplexAttribute},
549         {-1, -1, -1, -1, 0}
550     };
551 #endif
552
553     if (!odr_sequence_begin(o, p, sizeof(**p)))
554         return opt && odr_ok(o);
555     return
556 #ifdef Z_95
557         odr_implicit(o, odr_oid, &(*p)->attributeSet, ODR_CONTEXT, 1, 1) &&
558 #endif
559         odr_implicit(o, odr_integer, &(*p)->attributeType, ODR_CONTEXT,
560             120, 0) &&
561 #ifdef Z_95
562         odr_choice(o, arm, &(*p)->value, &(*p)->which) &&
563 #else
564         odr_implicit(o, odr_integer, &(*p)->attributeValue, ODR_CONTEXT,
565             121, 0) &&
566 #endif
567         odr_sequence_end(o);
568 }
569
570 int z_Term(ODR o, Z_Term **p, int opt)
571 {
572     static Odr_arm arm[] =
573     {
574         {ODR_IMPLICIT, ODR_CONTEXT, 45, Z_Term_general, odr_octetstring},
575         {ODR_IMPLICIT, ODR_CONTEXT, 215, Z_Term_numeric, odr_integer},
576         {ODR_IMPLICIT, ODR_CONTEXT, 216, Z_Term_characterString,
577             odr_visiblestring},
578         {ODR_IMPLICIT, ODR_CONTEXT, 217, Z_Term_oid, odr_oid},
579         {ODR_IMPLICIT, ODR_CONTEXT, 218, Z_Term_dateTime, odr_cstring},
580         {ODR_IMPLICIT, ODR_CONTEXT, 219, Z_Term_external, z_External},
581         /* add intUnit here */
582         {ODR_IMPLICIT, ODR_CONTEXT, 221, Z_Term_null, odr_null},
583         {-1, -1, -1, -1, 0}
584     };
585
586     if (o->direction ==ODR_DECODE)
587         *p = odr_malloc(o, sizeof(**p));
588     else if (!*p)
589         return opt;
590     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
591         return 1;
592     *p = 0;
593     return opt && odr_ok(o);
594 }
595
596 int z_AttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
597 {
598     if (!(odr_implicit_settag(o, ODR_CONTEXT, 102) &&
599         odr_sequence_begin(o, p, sizeof(**p))))
600         return opt && odr_ok(o);
601     return
602         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
603         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
604             &(*p)->num_attributes) &&
605         z_Term(o, &(*p)->term, 0) &&
606         odr_sequence_end(o);
607 }
608
609 int z_ResultSetPlusAttributes(ODR o, Z_ResultSetPlusAttributes **p, int opt)
610 {
611     if (!(odr_implicit_settag(o, ODR_CONTEXT, 214) &&
612         odr_sequence_begin(o, p, sizeof(**p))))
613         return opt && odr_ok(o);
614     return
615         z_ResultSetId(o, &(*p)->resultSet, 0) &&
616         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
617         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
618             &(*p)->num_attributes) &&
619         odr_sequence_end(o);
620 }
621
622 int z_ProximityOperator(ODR o, Z_ProximityOperator **p, int opt)
623 {
624     static Odr_arm arm[] =
625     {
626         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ProxCode_known, odr_integer},
627         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ProxCode_private, odr_integer},
628         {-1, -1, -1, -1, 0}
629     };
630
631     if (!odr_sequence_begin(o, p, sizeof(**p)))
632         return opt && odr_ok(o);
633     return
634         odr_implicit(o, odr_bool, &(*p)->exclusion, ODR_CONTEXT, 1, 1) &&
635         odr_implicit(o, odr_integer, &(*p)->distance, ODR_CONTEXT, 2, 0) &&
636         odr_implicit(o, odr_bool, &(*p)->ordered, ODR_CONTEXT, 3, 0) &&
637         odr_implicit(o, odr_integer, &(*p)->relationType, ODR_CONTEXT, 4, 0) &&
638         odr_constructed_begin(o, &(*p)->proximityUnitCode, ODR_CONTEXT, 5) &&
639         odr_choice(o, arm, &(*p)->proximityUnitCode, &(*p)->which) &&
640         odr_constructed_end(o) &&
641         odr_sequence_end(o);
642 }
643
644 int z_Operator(ODR o, Z_Operator **p, int opt)
645 {
646     static Odr_arm arm[] =
647     {
648         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_Operator_and, odr_null},
649         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Operator_or, odr_null},
650         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_Operator_and_not, odr_null},
651         {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_Operator_prox, z_ProximityOperator},
652         {-1, -1, -1, -1, 0}
653     };
654
655     if (!*p && o->direction != ODR_DECODE)
656         return opt;
657     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 46))
658         return opt && odr_ok(o);
659     if (o->direction == ODR_DECODE)
660         *p = odr_malloc(o, sizeof(**p));
661
662     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
663         odr_constructed_end(o))
664         return 1;
665     *p = 0;
666     return opt && odr_ok(o);
667 }
668
669 int z_Operand(ODR o, Z_Operand **p, int opt)
670 {
671     static Odr_arm arm[] =
672     {
673         {-1, -1, -1, Z_Operand_APT, z_AttributesPlusTerm},
674         {-1, -1, -1, Z_Operand_resultSetId, z_ResultSetId},
675         {-1, -1, -1, Z_Operand_resultAttr, z_ResultSetPlusAttributes},
676         {-1, -1, -1, -1, 0}
677     };
678
679     if (o->direction == ODR_DECODE)
680         *p = odr_malloc(o, sizeof(**p));
681     else if (!*p)
682         return opt;
683     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
684         return 1;
685     *p = 0;
686     return opt && odr_ok(o);
687 }
688
689 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt);
690
691 int z_Complex(ODR o, Z_Complex **p, int opt)
692 {
693     if (!odr_sequence_begin(o, p, sizeof(**p)))
694         return opt && odr_ok(o);
695     return
696         z_RPNStructure(o, &(*p)->s1, 0) &&
697         z_RPNStructure(o, &(*p)->s2, 0) &&
698         z_Operator(o, &(*p)->roperator, 0) &&
699         odr_sequence_end(o);
700 }
701
702 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt)
703 {
704     static Odr_arm arm[] = 
705     {
706         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_RPNStructure_simple, z_Operand},
707         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_RPNStructure_complex, z_Complex},
708         {-1 -1, -1, -1, 0}
709     };
710
711     if (o->direction == ODR_DECODE)
712         *p = odr_malloc(o, sizeof(**p));
713     else if (!*p)
714         return opt;
715     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
716         return 1;
717     *p = 0;
718     return opt && odr_ok(o);
719 }
720
721 int z_RPNQuery(ODR o, Z_RPNQuery **p, int opt)
722 {
723     if (!odr_sequence_begin(o, p, sizeof(**p)))
724         return opt && odr_ok(o);
725     return
726         odr_oid(o, &(*p)->attributeSetId, 0) &&
727         z_RPNStructure(o, &(*p)->RPNStructure, 0) &&
728         odr_sequence_end(o);
729 }
730
731 /* -----------------------END RPN QUERY ----------------------- */
732
733 int z_Query(ODR o, Z_Query **p, int opt)
734 {
735     static Odr_arm arm[] = 
736     {
737         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Query_type_1, z_RPNQuery},
738         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Query_type_2, odr_octetstring},
739         {ODR_EXPLICIT, ODR_CONTEXT, 101, Z_Query_type_101, z_RPNQuery},
740         {-1, -1, -1, -1, 0}
741     };
742
743     if (o->direction == ODR_DECODE)
744         *p = odr_malloc(o, sizeof(**p));
745     else if (!*p)
746         return opt;
747     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
748         return 1;
749     *p = 0;
750     return opt && odr_ok(o);
751 }
752
753 int z_SearchRequest(ODR o, Z_SearchRequest **p, int opt)
754 {
755     Z_SearchRequest *pp;
756
757     if (!odr_sequence_begin(o, p, sizeof(**p)))
758         return opt && odr_ok(o);
759     pp = *p;
760     return
761         z_ReferenceId(o, &pp->referenceId, 1) &&
762         odr_implicit(o, odr_integer, &pp->smallSetUpperBound, ODR_CONTEXT,
763             13, 0) &&
764         odr_implicit(o, odr_integer, &pp->largeSetLowerBound, ODR_CONTEXT,
765             14, 0) &&
766         odr_implicit(o, odr_integer, &pp->mediumSetPresentNumber, ODR_CONTEXT,
767             15, 0) &&
768         odr_implicit(o, odr_bool, &pp->replaceIndicator, ODR_CONTEXT, 16, 1) &&
769         odr_implicit(o, odr_visiblestring, &pp->resultSetName, ODR_CONTEXT,
770             17, 9) &&
771         odr_implicit_settag(o, ODR_CONTEXT, 18) &&
772         odr_sequence_of(o, z_DatabaseName, &pp->databaseNames,
773             &pp->num_databaseNames) &&
774         odr_explicit(o, z_ElementSetNames, &pp->smallSetElementSetNames,
775             ODR_CONTEXT, 100, 1) &&
776         odr_explicit(o, z_ElementSetNames, &pp->mediumSetElementSetNames,
777             ODR_CONTEXT, 101, 1) &&
778         odr_implicit(o, odr_oid, &pp->preferredRecordSyntax,
779             ODR_CONTEXT, 104, 1) &&
780         odr_explicit(o, z_Query, &pp->query, ODR_CONTEXT, 21, 0) &&
781 #ifdef Z_95
782         odr_implicit(o, z_OtherInformation, &(*p)->additionalSearchInfo,
783             ODR_CONTEXT, 203, 1) &&
784         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
785 #endif
786         odr_sequence_end(o);
787 }
788
789 /* ------------------------ RECORD ------------------------- */
790
791 int z_DatabaseRecord(ODR o, Z_DatabaseRecord **p, int opt)
792 {
793     return z_External(o, (Z_External **) p, opt);
794 }
795
796 #ifdef Z_95
797
798 int z_DefaultDiagFormat(ODR o, Z_DefaultDiagFormat **p, int opt)
799 {
800     static Odr_arm arm[] =
801     {
802         {-1, -1, -1, Z_DiagForm_v2AddInfo, odr_visiblestring},
803         {-1, -1, -1, Z_DiagForm_v3AddInfo, z_InternationalString},
804         {ODR_IMPLICIT, ODR_CONTEXT, ODR_VISIBLESTRING, Z_DiagForm_v2AddInfo,
805             odr_visiblestring}, /* To cater to a bug in the CNIDR servers */
806         {-1, -1, -1, -1, 0}
807     };
808     if (!odr_sequence_begin(o, p, sizeof(**p)))
809         return opt && odr_ok(o);
810     return
811         odr_oid(o, &(*p)->diagnosticSetId, 1) && /* SHOULD NOT BE OPT! */
812         odr_integer(o, &(*p)->condition, 0) &&
813         /*
814          * I no longer recall what server tagged the addinfo.. but it isn't
815          * hurting anyone, so...
816          * We need to turn it into a choice, or something, because of
817          * that damn generalstring in v3.
818          */
819         odr_choice(o, arm, &(*p)->addinfo, &(*p)->which) &&
820         odr_sequence_end(o);
821 }
822
823 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
824 {
825     static Odr_arm arm[] = 
826     {
827         {-1, -1, -1, Z_DiagRec_defaultFormat, z_DefaultDiagFormat},
828         {-1, -1, -1, Z_DiagRec_externallyDefined, z_External},
829         {-1, -1, -1, -1, 0}
830     };
831
832     if (o->direction == ODR_DECODE)
833         *p = odr_malloc(o, sizeof(**p));
834     else if (!*p)
835         return opt;
836     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
837         return 1;
838     *p = 0;
839     return opt && odr_ok(o);
840 }
841
842 #else
843
844 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
845 {
846     if (!odr_sequence_begin(o, p, sizeof(**p)))
847         return opt && odr_ok(o);
848     return
849         odr_oid(o, &(*p)->diagnosticSetId, 1) && /* SHOULD NOT BE OPT! */
850         odr_integer(o, &(*p)->condition, 0) &&
851         /*
852          * I no longer recall what server tagged the addinfo.. but it isn't
853          * hurting anyone, so...
854          * We need to turn it into a choice, or something, because of
855          * that damn generalstring in v3.
856          */
857         (odr_visiblestring(o, &(*p)->addinfo, 0) ||
858             odr_implicit(o, odr_cstring, &(*p)->addinfo, ODR_CONTEXT,
859             ODR_VISIBLESTRING, 1)) &&
860         odr_sequence_end(o);
861 }
862
863 #endif
864
865 int z_DiagRecs(ODR o, Z_DiagRecs **p, int opt)
866 {
867     if (o->direction == ODR_DECODE)
868         *p = odr_malloc(o, sizeof(**p));
869     else if (!*p)
870         return opt;
871
872         if (odr_sequence_of(o, z_DiagRec, &(*p)->diagRecs,
873         &(*p)->num_diagRecs))
874         return 1;
875     *p = 0;
876     return 0;
877 }
878
879 int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt)
880 {
881     static Odr_arm arm[] =
882     {
883         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_NamePlusRecord_databaseRecord,
884             z_DatabaseRecord},
885         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_NamePlusRecord_surrogateDiagnostic,
886             z_DiagRec},
887         {-1, -1, -1, -1, 0}
888     };
889
890     if (!odr_sequence_begin(o, p, sizeof(**p)))
891         return opt && odr_ok(o);
892     return
893         odr_implicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
894             0, 1) &&
895         odr_constructed_begin(o, &(*p)->u, ODR_CONTEXT, 1) &&
896         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
897         odr_constructed_end(o) &&
898         odr_sequence_end(o);
899 }
900
901 int z_NamePlusRecordList(ODR o, Z_NamePlusRecordList **p, int opt)
902 {
903     if (o->direction == ODR_DECODE)
904         *p = odr_malloc(o, sizeof(**p));
905     else if (!*p)
906         return opt;
907     if (odr_sequence_of(o, z_NamePlusRecord, &(*p)->records,
908         &(*p)->num_records))
909         return 1;
910     *p = 0;
911     return 0;
912 }
913
914 int z_Records(ODR o, Z_Records **p, int opt)
915 {
916     static Odr_arm arm[] = 
917     {
918         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_Records_DBOSD, z_NamePlusRecordList},
919         {ODR_IMPLICIT, ODR_CONTEXT, 130, Z_Records_NSD, z_DiagRec},
920         {ODR_IMPLICIT, ODR_CONTEXT, 205, Z_Records_multipleNSD,
921             z_DiagRecs},
922         {-1, -1, -1, -1, 0}
923     };
924
925     if (o->direction == ODR_DECODE)
926         *p = odr_malloc(o, sizeof(**p));
927     else if (!*p)
928         return opt;
929     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
930         return 1;
931     *p = 0;
932     return opt && odr_ok(o);
933 }
934
935 /* ------------------------ ACCESS CTRL SERVICE ----------------------- */
936
937 int z_AccessControlRequest(ODR o, Z_AccessControlRequest **p, int opt)
938 {
939     static Odr_arm arm[] = 
940     {
941         {ODR_IMPLICIT, ODR_CONTEXT, 37, Z_AccessRequest_simpleForm,
942             odr_octetstring},
943         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_AccessRequest_externallyDefined,
944             z_External},
945         {-1, -1, -1, -1, 0}
946     };
947     if (!odr_sequence_begin(o, p, sizeof(**p)))
948         return opt && odr_ok(o);
949     return
950         z_ReferenceId(o, &(*p)->referenceId, 1) &&
951         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
952 #ifdef Z_95
953         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
954 #endif
955         odr_sequence_end(o);
956 }
957
958 int z_AccessControlResponse(ODR o, Z_AccessControlResponse **p, int opt)
959 {
960     static Odr_arm arm[] = 
961     {
962         {ODR_IMPLICIT, ODR_CONTEXT, 38, Z_AccessResponse_simpleForm,
963             odr_octetstring},
964         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_AccessResponse_externallyDefined,
965             z_External},
966         {-1, -1, -1, -1, 0}
967     };
968     if (!odr_sequence_begin(o, p, sizeof(**p)))
969         return opt && odr_ok(o);
970     return
971         z_ReferenceId(o, &(*p)->referenceId, 1) &&
972         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
973         odr_explicit(o, z_DiagRec, &(*p)->diagnostic, ODR_CONTEXT, 223, 1) &&
974 #ifdef Z_95
975         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
976 #endif
977         odr_sequence_end(o);
978 }
979
980 /* ------------------------ SCAN SERVICE -------------------- */
981
982 int z_AttributeList(ODR o, Z_AttributeList **p, int opt)
983 {
984     if (o->direction == ODR_DECODE)
985         *p = odr_malloc(o, sizeof(**p));
986     else if (!*p)
987         return opt;
988
989     odr_implicit_settag(o, ODR_CONTEXT, 44);
990     if (odr_sequence_of(o, z_AttributeElement, &(*p)->attributes,
991         &(*p)->num_attributes))
992         return 1;
993     *p = 0;
994     return opt && odr_ok(o);
995 }
996
997 /*
998  * This is a temporary hack. We don't know just *what* old version of the
999  * protocol willow uses, so we'll just patiently wait for them to update
1000  */
1001 static int willow_scan = 0;
1002
1003 int z_WillowAttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
1004 {
1005     if (!*p && o->direction != ODR_DECODE)
1006         return opt;
1007     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 4))
1008     {
1009         o->t_class = -1;
1010         return opt && odr_ok(o);
1011     }
1012     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 1))
1013         return 0;
1014     if (!odr_constructed_begin(o, p, ODR_UNIVERSAL, ODR_SEQUENCE))
1015         return 0;
1016     if (!odr_implicit_settag(o, ODR_CONTEXT, 44))
1017         return 0;
1018     if (o->direction == ODR_DECODE)
1019         *p = odr_malloc(o, sizeof(**p));
1020     if (!odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
1021         &(*p)->num_attributes))
1022         return 0;
1023     if (!odr_sequence_end(o) || !odr_sequence_end(o))
1024         return 0;
1025     if (!z_Term(o, &(*p)->term, 0))
1026         return 0;
1027     if (!odr_constructed_end(o))
1028         return 0;
1029     willow_scan = 1;
1030     return 1;
1031 }
1032
1033 int z_AlternativeTerm(ODR o, Z_AlternativeTerm **p, int opt)
1034 {
1035     if (o->direction == ODR_DECODE)
1036         *p = odr_malloc(o, sizeof(**p));
1037     else if (!*p)
1038     {
1039         o->t_class = -1;
1040         return opt && odr_ok(o);
1041     }
1042
1043     if (odr_sequence_of(o, z_AttributesPlusTerm, &(*p)->terms,
1044         &(*p)->num_terms))
1045         return 1;
1046     *p = 0;
1047     return opt && !o->error;
1048 }
1049
1050 #if 1
1051
1052 int z_ByDatabase(ODR o, Z_ByDatabase **p, int opt)
1053 {
1054     if (!odr_sequence_begin(o, p, sizeof(**p)))
1055         return opt && odr_ok(o);
1056     return
1057         z_DatabaseName(o, &(*p)->db, 1) &&
1058         odr_implicit(o, odr_integer, &(*p)->num, ODR_CONTEXT, 1, 1) &&
1059         z_OtherInformation(o, &(*p)->otherDbInfo, 1) &&
1060         odr_sequence_end(o);
1061 }
1062
1063 int z_ByDatabaseList(ODR o, Z_ByDatabaseList **p, int opt)
1064 {
1065     if (!odr_initmember(o, p, sizeof(**p)))
1066         return opt && odr_ok(o);
1067     if (odr_sequence_of(o, z_ByDatabase, &(*p)->elements, &(*p)->num_elements))
1068         return 1;
1069     *p = 0;
1070     return opt && odr_ok(o);
1071 }
1072
1073 int z_ScanOccurrences(ODR o, Z_ScanOccurrences **p, int opt)
1074 {
1075     Odr_arm arm[] =
1076     {
1077         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_ScanOccurrences_global, odr_integer},
1078         {ODR_EXPLICIT, ODR_CONTEXT, 3, Z_ScanOccurrences_byDatabase,
1079             z_ByDatabaseList},
1080         {-1, -1, -1, -1, 0}
1081     };
1082
1083     if (!odr_initmember(o, p, sizeof(**p)))
1084         return opt && odr_ok(o);
1085     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1086         return 1;
1087     *p = 0;
1088     return opt && odr_ok(o);
1089 }
1090
1091 int z_OccurrenceByAttributesElem(ODR o, Z_OccurrenceByAttributesElem **p,
1092     int opt)
1093 {
1094     if (!odr_sequence_begin(o, p, sizeof(**p)))
1095         return opt && odr_ok(o);
1096     return
1097         odr_explicit(o, z_AttributeList, &(*p)->attributes, ODR_CONTEXT,
1098             1, 1) &&
1099         z_ScanOccurrences(o, &(*p)->occurrences, 1) &&
1100         z_OtherInformation(o, &(*p)->otherOccurInfo, 1) &&
1101         odr_sequence_end(o);
1102 }
1103
1104 int z_OccurrenceByAttributes(ODR o, Z_OccurrenceByAttributes **p, int opt)
1105 {
1106     if (!odr_initmember(o, p, sizeof(**p)))
1107         return opt && odr_ok(o);
1108     if (!odr_sequence_of(o, z_OccurrenceByAttributesElem, &(*p)->elements,
1109         &(*p)->num_elements))
1110         return 1;
1111     *p = 0;
1112     return opt && odr_ok(o);
1113 }
1114
1115 #else
1116
1117 /*
1118  * Incomplete definition of occurencebyattributes.
1119  */
1120
1121 int z_OccurrenceByAttributes(ODR o, Z_OccurrenceByAttributes **p, int opt)
1122 {
1123     if (!odr_sequence_begin(o, p, sizeof(**p)))
1124         return opt && odr_ok(o);
1125     return
1126         odr_explicit(o, z_AttributeList, &(*p)->attributes, ODR_CONTEXT, 1, 1)&&
1127         odr_explicit(o, odr_integer, &(*p)->global, ODR_CONTEXT, 2, 1) &&
1128         odr_sequence_end(o);
1129 }
1130
1131 #endif
1132
1133 int z_TermInfo(ODR o, Z_TermInfo **p, int opt)
1134 {
1135     if (!odr_sequence_begin(o, p, sizeof(**p)))
1136         return opt && odr_ok(o);
1137     return
1138         (willow_scan ? 
1139             odr_implicit(o, z_Term, &(*p)->term, ODR_CONTEXT, 1, 0) :
1140             z_Term(o, &(*p)->term, 0)) &&
1141         odr_implicit(o, z_InternationalString, &(*p)->displayTerm, ODR_CONTEXT,
1142             0, 1) &&
1143         z_AttributeList(o, &(*p)->suggestedAttributes, 1) &&
1144         odr_implicit(o, z_AlternativeTerm, &(*p)->alternativeTerm,
1145             ODR_CONTEXT, 4, 1) &&
1146         odr_implicit(o, odr_integer, &(*p)->globalOccurrences, ODR_CONTEXT,
1147             2, 1) &&
1148         odr_implicit(o, z_OccurrenceByAttributes, &(*p)->byAttributes,
1149             ODR_CONTEXT, 3, 1) &&
1150         z_OtherInformation(o, &(*p)->otherTermInfo, 1) &&
1151         odr_sequence_end(o);
1152 }
1153
1154 int z_Entry(ODR o, Z_Entry **p, int opt)
1155 {
1156     static Odr_arm arm[] =
1157     {
1158         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Entry_termInfo, z_TermInfo},
1159         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Entry_surrogateDiagnostic,
1160             z_DiagRec},
1161         {-1, -1, -1, -1, 0}
1162     };
1163
1164     if (o->direction == ODR_DECODE)
1165         *p = odr_malloc(o, sizeof(**p));
1166     else if (!*p)
1167         return opt;
1168
1169     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1170         return 1;
1171     *p = 0;
1172     return opt && odr_ok(o);
1173 }
1174
1175 int z_Entries(ODR o, Z_Entries **p, int opt)
1176 {
1177     if (o->direction == ODR_DECODE)
1178         *p = odr_malloc(o, sizeof(**p));
1179     else if (!*p)
1180         return opt;
1181
1182     if (odr_sequence_of(o, z_Entry, &(*p)->entries,
1183         &(*p)->num_entries))
1184         return 1;
1185     *p = 0;
1186     return 0;
1187 }
1188
1189 int z_ListEntries(ODR o, Z_ListEntries **p, int opt)
1190 {
1191     static Odr_arm arm[] =
1192     {
1193         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ListEntries_entries, z_Entries},
1194         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_ListEntries_nonSurrogateDiagnostics,
1195             z_DiagRecs},
1196         {-1, -1, -1, -1, 0}
1197     };
1198
1199     if (o->direction == ODR_DECODE)
1200         *p = odr_malloc(o, sizeof(**p));
1201     else if (!*p)
1202         return opt;
1203
1204     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1205         return 1;
1206     *p = 0;
1207     return opt && odr_ok(o);
1208 }
1209
1210 int z_ScanRequest(ODR o, Z_ScanRequest **p, int opt)
1211 {
1212     if (!odr_sequence_begin(o, p, sizeof(**p)))
1213         return opt && odr_ok(o);
1214     willow_scan = 0;
1215     return
1216         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1217         odr_implicit_settag(o, ODR_CONTEXT, 3) &&
1218         odr_sequence_of(o, z_DatabaseName, &(*p)->databaseNames,
1219             &(*p)->num_databaseNames) &&
1220         odr_oid(o, &(*p)->attributeSet, 1) &&
1221         (z_AttributesPlusTerm(o, &(*p)->termListAndStartPoint, 1) ?
1222             ((*p)->termListAndStartPoint ? 1 : 
1223         z_WillowAttributesPlusTerm(o, &(*p)->termListAndStartPoint, 0)) : 0) &&
1224         odr_implicit(o, odr_integer, &(*p)->stepSize, ODR_CONTEXT, 5, 1) &&
1225         odr_implicit(o, odr_integer, &(*p)->numberOfTermsRequested,
1226             ODR_CONTEXT, 6, 0) &&
1227         odr_implicit(o, odr_integer, &(*p)->preferredPositionInResponse,
1228             ODR_CONTEXT, 7, 1) &&
1229         odr_sequence_end(o);
1230 }
1231
1232 int z_ScanResponse(ODR o, Z_ScanResponse **p, int opt)
1233 {
1234     if (!odr_sequence_begin(o, p, sizeof(**p)))
1235         return opt && odr_ok(o);
1236     return
1237         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1238         odr_implicit(o, odr_integer, &(*p)->stepSize, ODR_CONTEXT, 3, 1) &&
1239         odr_implicit(o, odr_integer, &(*p)->scanStatus, ODR_CONTEXT, 4, 0) &&
1240         odr_implicit(o, odr_integer, &(*p)->numberOfEntriesReturned,
1241             ODR_CONTEXT, 5, 0) &&
1242         odr_implicit(o, odr_integer, &(*p)->positionOfTerm, ODR_CONTEXT, 6, 1)&&
1243         odr_explicit(o, z_ListEntries, &(*p)->entries, ODR_CONTEXT, 7, 1) &&
1244         odr_implicit(o, odr_oid, &(*p)->attributeSet, ODR_CONTEXT, 8, 1) &&
1245         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1246         odr_sequence_end(o);
1247 }
1248
1249 /* ------------------------ SEARCHRESPONSE ----------------*/
1250
1251 int z_NumberOfRecordsReturned(ODR o, int **p, int opt)
1252 {
1253     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 24, opt);
1254 }
1255
1256 int z_NextResultSetPosition(ODR o, int **p, int opt)
1257 {
1258     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 25, opt);
1259 }
1260
1261 int z_PresentStatus(ODR o, int **p, int opt)
1262 {
1263     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 27, opt);
1264 }
1265
1266 int z_SearchResponse(ODR o, Z_SearchResponse **p, int opt)
1267 {
1268     Z_SearchResponse *pp;
1269
1270     if (!odr_sequence_begin(o, p, sizeof(**p)))
1271         return opt && odr_ok(o);
1272     pp = *p;
1273     return
1274         z_ReferenceId(o, &pp->referenceId, 1) &&
1275         odr_implicit(o, odr_integer, &pp->resultCount, ODR_CONTEXT, 23, 0) &&
1276         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
1277         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
1278         odr_implicit(o, odr_bool, &pp->searchStatus, ODR_CONTEXT, 22, 0) &&
1279         odr_implicit(o, odr_integer, &pp->resultSetStatus, ODR_CONTEXT, 26,
1280             1) &&
1281         z_PresentStatus(o, &pp->presentStatus, 1) &&
1282         z_Records(o, &pp->records, 1) &&
1283 #ifdef Z_95
1284         odr_implicit(o, z_OtherInformation, &(*p)->additionalSearchInfo,
1285             ODR_CONTEXT, 203, 1) &&
1286         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1287 #endif
1288         odr_sequence_end(o);
1289 }
1290
1291 /* --------------------- PRESENT SERVICE ---------------------- */
1292
1293 int z_ElementSpec(ODR o, Z_ElementSpec **p, int opt)
1294 {
1295     static Odr_arm arm[] =
1296     {
1297         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSpec_elementSetName,
1298             odr_visiblestring},
1299         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_ElementSpec_externalSpec,
1300             z_External},
1301         {-1, -1, -1, -1, 0}
1302     };
1303
1304     if (o->direction == ODR_DECODE)
1305         *p = odr_malloc(o, sizeof(**p));
1306     else if (!*p)
1307         return opt;
1308
1309     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1310         return 1;
1311     *p = 0;
1312     return opt && odr_ok(o);
1313 }
1314
1315 int z_Specification(ODR o, Z_Specification **p, int opt)
1316 {
1317     if (!odr_sequence_begin(o, p, sizeof(**p)))
1318         return opt && odr_ok(o);
1319     return
1320         odr_implicit(o, odr_oid, &(*p)->schema, ODR_CONTEXT, 1, 1) &&
1321         z_ElementSpec(o, &(*p)->elementSpec, 1) &&
1322         odr_sequence_end(o);
1323 }
1324
1325 int z_DbSpecific(ODR o, Z_DbSpecific **p, int opt)
1326 {
1327     if (!odr_sequence_begin(o, p, sizeof(**p)))
1328         return opt && odr_ok(o);
1329     return
1330         odr_explicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
1331             1, 0) &&
1332         odr_implicit(o, z_Specification, &(*p)->spec, ODR_CONTEXT, 2, 0) &&
1333         odr_sequence_end(o);
1334 }
1335
1336 int z_CompSpec(ODR o, Z_CompSpec **p, int opt)
1337 {
1338     if (!odr_sequence_begin(o, p, sizeof(**p)))
1339         return opt && odr_ok(o);
1340     return
1341         odr_implicit(o, odr_bool, &(*p)->selectAlternativeSyntax, ODR_CONTEXT,
1342             1, 0) &&
1343         odr_implicit(o, z_Specification, &(*p)->generic, ODR_CONTEXT, 2, 1) &&
1344         odr_implicit_settag(o, ODR_CONTEXT, 3) &&
1345         (odr_sequence_of(o, z_DbSpecific, &(*p)->dbSpecific,
1346             &(*p)->num_dbSpecific) || odr_ok(o)) &&
1347         odr_implicit_settag(o, ODR_CONTEXT, 4) &&
1348         (odr_sequence_of(o, odr_oid, &(*p)->recordSyntax,
1349             &(*p)->num_recordSyntax) || odr_ok(o)) &&
1350         odr_sequence_end(o);
1351 }
1352
1353 int z_RecordComposition(ODR o, Z_RecordComposition **p, int opt)
1354 {
1355     static Odr_arm arm[] =
1356     {
1357         {ODR_EXPLICIT, ODR_CONTEXT, 19, Z_RecordComp_simple,
1358             z_ElementSetNames},
1359         {ODR_IMPLICIT, ODR_CONTEXT, 209, Z_RecordComp_complex,
1360             z_CompSpec},
1361         {-1, -1, -1, -1, 0}
1362     };
1363
1364     if (o->direction == ODR_DECODE)
1365         *p = odr_malloc(o, sizeof(**p));
1366     else if (!*p)
1367         return opt;
1368
1369     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1370         return 1;
1371     *p = 0;
1372     return opt && odr_ok(o);
1373 }
1374
1375 int z_Range(ODR o, Z_Range **p, int opt)
1376 {
1377     if (!odr_sequence_begin(o, p, sizeof(**p)))
1378         return opt && odr_ok(o);
1379     return
1380         odr_implicit(o, odr_integer, &(*p)->startingPosition, ODR_CONTEXT,
1381             1, 0) &&
1382         odr_implicit(o, odr_integer, &(*p)->numberOfRecords, ODR_CONTEXT,
1383             2, 0) &&
1384         odr_sequence_end(o);
1385 }
1386
1387 int z_PresentRequest(ODR o, Z_PresentRequest **p, int opt)
1388 {
1389     Z_PresentRequest *pp;
1390
1391     if (!odr_sequence_begin(o, p, sizeof(**p)))
1392         return opt && odr_ok(o);
1393     pp = *p;
1394     return
1395         z_ReferenceId(o, &pp->referenceId, 1) &&
1396         z_ResultSetId(o, &pp->resultSetId, 0) &&
1397         odr_implicit(o, odr_integer, &pp->resultSetStartPoint, ODR_CONTEXT,
1398             30, 0) &&
1399         odr_implicit(o, odr_integer, &pp->numberOfRecordsRequested, ODR_CONTEXT,
1400             29, 0) &&
1401 #ifdef Z_95
1402         odr_implicit_settag(o, ODR_CONTEXT, 212) &&
1403         (odr_sequence_of(o, z_Range, &(*p)->additionalRanges,
1404             &(*p)->num_ranges) || odr_ok(o)) &&
1405         z_RecordComposition(o, &(*p)->recordComposition, 1) &&
1406 #else
1407         odr_explicit(o, z_ElementSetNames, &pp->elementSetNames, ODR_CONTEXT,
1408             19, 1) &&
1409 #endif
1410         odr_implicit(o, odr_oid, &(*p)->preferredRecordSyntax, ODR_CONTEXT,
1411             104, 1) &&
1412 #ifdef Z_95
1413         odr_implicit(o, odr_integer, &(*p)->maxSegmentCount, ODR_CONTEXT,
1414             204, 1) &&
1415         odr_implicit(o, odr_integer, &(*p)->maxRecordSize, ODR_CONTEXT,
1416             206, 1) &&
1417         odr_implicit(o, odr_integer, &(*p)->maxSegmentSize, ODR_CONTEXT,
1418             207, 1) &&
1419         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1420 #endif
1421         odr_sequence_end(o);
1422 }
1423
1424 int z_PresentResponse(ODR o, Z_PresentResponse **p, int opt)
1425 {
1426     Z_PresentResponse *pp;
1427
1428     if (!odr_sequence_begin(o, p, sizeof(**p)))
1429         return opt && odr_ok(o);
1430     pp = *p;
1431     return
1432         z_ReferenceId(o, &pp->referenceId, 1) &&
1433         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
1434         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
1435         z_PresentStatus(o, &pp->presentStatus, 0) &&
1436         z_Records(o, &pp->records, 1) &&
1437 #ifdef Z_95
1438         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1439 #endif
1440         odr_sequence_end(o);
1441 }
1442
1443 /* ----------------------DELETE -------------------------- */
1444
1445 int z_DeleteSetStatus(ODR o, int **p, int opt)
1446 {
1447     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 33, opt);
1448 }
1449
1450 int z_ListStatus(ODR o, Z_ListStatus **p, int opt)
1451 {
1452     if (!odr_sequence_begin(o, p, sizeof(**p)))
1453         return opt && odr_ok(o);
1454     return
1455         z_ResultSetId(o, &(*p)->id, 0) &&
1456         z_DeleteSetStatus(o, &(*p)->status, 0) &&
1457         odr_sequence_end(o);
1458 }
1459
1460 int z_DeleteResultSetRequest(ODR o, Z_DeleteResultSetRequest **p, int opt)
1461 {
1462     if (!odr_sequence_begin(o, p, sizeof(**p)))
1463         return opt && odr_ok(o);
1464     return
1465         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1466         odr_implicit(o, odr_integer, &(*p)->deleteFunction, ODR_CONTEXT, 32,
1467             0) &&
1468         (odr_sequence_of(o, z_ListStatus, &(*p)->resultSetList,
1469             &(*p)->num_ids) || odr_ok(o)) &&
1470 #ifdef Z_95
1471         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1472 #endif
1473         odr_sequence_end(o);
1474 }
1475
1476 int z_DeleteResultSetResponse(ODR o, Z_DeleteResultSetResponse **p, int opt)
1477 {
1478     if (!odr_sequence_begin(o, p, sizeof(**p)))
1479         return opt && odr_ok(o);
1480     return
1481         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1482         odr_implicit(o, z_DeleteSetStatus, &(*p)->deleteOperationStatus,
1483             ODR_CONTEXT, 0, 1) &&
1484         odr_implicit_settag(o, ODR_CONTEXT, 1) &&
1485         (odr_sequence_of(o, z_ListStatus, &(*p)->deleteListStatuses,
1486             &(*p)->num_statuses) || odr_ok(o)) &&
1487         odr_implicit(o, odr_integer, &(*p)->numberNotDeleted, ODR_CONTEXT,
1488             34, 1) &&
1489         odr_implicit_settag(o, ODR_CONTEXT, 35) &&
1490         (odr_sequence_of(o, z_ListStatus, &(*p)->bulkStatuses,
1491             &(*p)->num_bulkStatuses) || odr_ok(o)) &&
1492         odr_implicit(o, odr_visiblestring, &(*p)->deleteMessage, ODR_CONTEXT,
1493             36, 1) &&
1494 #ifdef Z_95
1495         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1496 #endif
1497         odr_sequence_end(o);
1498 }
1499
1500 /* ------------------------ SEGMENT SERVICE -------------- */
1501
1502 int z_Segment(ODR o, Z_Segment **p, int opt)
1503 {
1504     if (!odr_sequence_begin(o, p, sizeof(**p)))
1505         return opt && odr_ok(o);
1506     return
1507         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1508         odr_implicit(o, odr_integer, &(*p)->numberOfRecordsReturned,
1509             ODR_CONTEXT, 24, 0) &&
1510         odr_implicit_settag(o, ODR_CONTEXT, 0) &&
1511         odr_sequence_of(o, z_NamePlusRecord, &(*p)->segmentRecords,
1512             &(*p)->num_segmentRecords) &&
1513         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1514         odr_sequence_end(o);
1515 }
1516
1517 /* ------------------------ CLOSE SERVICE ---------------- */
1518
1519 int z_Close(ODR o, Z_Close **p, int opt)
1520 {
1521     if (!odr_sequence_begin(o, p, sizeof(**p)))
1522         return opt && odr_ok(o);
1523     return
1524         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1525         odr_implicit(o, odr_integer, &(*p)->closeReason, ODR_CONTEXT, 211, 0) &&
1526         odr_implicit(o, odr_visiblestring, &(*p)->diagnosticInformation,
1527             ODR_CONTEXT, 3, 1) &&
1528         odr_implicit(o, odr_oid, &(*p)->resourceReportFormat, ODR_CONTEXT,
1529             4, 1) &&
1530         odr_implicit(o, z_External, &(*p)->resourceReport, ODR_CONTEXT,
1531             5, 1) &&
1532 #ifdef Z_95
1533         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1534 #endif
1535         odr_sequence_end(o);
1536 }
1537
1538 /* ------------------------ APDU ------------------------- */
1539
1540 int z_Permissions(ODR o, Z_Permissions **p, int opt)
1541 {
1542     if (!odr_sequence_begin(o, p, sizeof(**p)))
1543         return opt && odr_ok(o);
1544     return
1545         odr_implicit(o, z_InternationalString, &(*p)->userId, ODR_CONTEXT,
1546             1, 0) &&
1547         odr_implicit_settag(o, ODR_CONTEXT, 2) &&
1548         odr_sequence_of(o, odr_integer, &(*p)->allowableFunctions,
1549             &(*p)->num_allowableFunctions) &&
1550         odr_sequence_end(o);
1551 }
1552
1553 int z_ExtendedServicesRequest(ODR o, Z_ExtendedServicesRequest **p, int opt)
1554 {
1555     if (!odr_sequence_begin(o, p, sizeof(**p)))
1556         return opt && odr_ok(o);
1557     return
1558         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1559         odr_implicit(o, odr_integer, &(*p)->function, ODR_CONTEXT, 3, 0) &&
1560         odr_implicit(o, odr_oid, &(*p)->packageType, ODR_CONTEXT, 4, 0) &&
1561         odr_implicit(o, z_InternationalString, &(*p)->packageName, ODR_CONTEXT, 5, 1) &&
1562         odr_implicit(o, z_InternationalString, &(*p)->userId, ODR_CONTEXT, 6, 1) &&
1563         odr_implicit(o, z_IntUnit, &(*p)->retentionTime, ODR_CONTEXT, 7, 1) &&
1564         odr_implicit(o, z_Permissions, &(*p)->permissions, ODR_CONTEXT, 8, 1) &&
1565         odr_implicit(o, z_InternationalString, &(*p)->description, ODR_CONTEXT, 9, 1) &&
1566         odr_implicit(o, z_External, &(*p)->taskSpecificParameters, ODR_CONTEXT, 10, 1) &&
1567         odr_implicit(o, odr_integer, &(*p)->waitAction, ODR_CONTEXT, 11, 0) &&
1568         z_ElementSetName(o, &(*p)->elements, 1) &&
1569         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1570         odr_sequence_end(o);
1571 }
1572
1573 int z_ExtendedServicesResponse(ODR o, Z_ExtendedServicesResponse **p, int opt)
1574 {
1575     if (!odr_sequence_begin(o, p, sizeof(**p)))
1576         return opt && odr_ok(o);
1577     return
1578         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1579         odr_implicit(o, odr_integer, &(*p)->operationStatus, ODR_CONTEXT, 3, 0) &&
1580         odr_implicit_settag(o, ODR_CONTEXT, 4) &&
1581         (odr_sequence_of(o, z_DiagRec, &(*p)->diagnostics,
1582             &(*p)->num_diagnostics) || odr_ok(o)) &&
1583         odr_implicit(o, z_External, &(*p)->taskPackage, ODR_CONTEXT, 5, 1) &&
1584         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1585         odr_sequence_end(o);
1586 }
1587
1588 /* ------------------------ SORT ------------------------- */
1589
1590 int z_SortAttributes(ODR o, Z_SortAttributes **p, int opt)
1591 {
1592     if (!odr_sequence_begin(o, p, sizeof(**p)))
1593         return opt && odr_ok(o);
1594     return
1595         odr_oid(o, &(*p)->id, 0) &&
1596         z_AttributeList(o, &(*p)->list, 0) &&
1597         odr_sequence_end(o);
1598 }
1599
1600 int z_SortKey(ODR o, Z_SortKey **p, int opt)
1601 {
1602     static Odr_arm arm[] =
1603     {
1604         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_SortKey_sortField,
1605             z_InternationalString},
1606         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_SortKey_elementSpec, z_Specification},
1607         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_SortKey_sortAttributes,
1608             z_SortAttributes},
1609         {-1, -1, -1, -1, 0}
1610     };
1611
1612     if (!odr_initmember(o, p, sizeof(**p)))
1613         return opt && odr_ok(o);
1614     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1615         return 1;
1616     *p = 0;
1617     return opt && odr_ok(o);
1618 }
1619
1620 int z_SortDbSpecific(ODR o, Z_SortDbSpecific **p, int opt)
1621 {
1622     if (!odr_sequence_begin(o, p, sizeof(**p)))
1623         return opt && odr_ok(o);
1624     return
1625         z_DatabaseName(o, &(*p)->databaseName, 0) &&
1626         z_SortKey(o, &(*p)->dbSort, 0) &&
1627         odr_sequence_end(o);
1628 }
1629
1630 int z_SortDbSpecificList(ODR o, Z_SortDbSpecificList **p, int opt)
1631 {
1632     if (!odr_initmember(o, p, sizeof(**p)))
1633         return opt && odr_ok(o);
1634     if (odr_sequence_of(o, z_SortDbSpecific, &(*p)->dbSpecific,
1635         &(*p)->num_dbSpecific))
1636         return 1;
1637     *p = 0;
1638     return opt && odr_ok(o);
1639 }
1640
1641 int z_SortElement(ODR o, Z_SortElement **p, int opt)
1642 {
1643     static Odr_arm arm[] =
1644     {
1645         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_SortElement_generic, z_SortKey},
1646         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_SortElement_databaseSpecific,
1647             z_SortDbSpecificList},
1648         {-1, -1, -1, -1, 0}
1649     };
1650
1651     if (!odr_initmember(o, p, sizeof(**p)))
1652         return opt && odr_ok(o);
1653     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1654         return 1;
1655     *p = 0;
1656     return opt && odr_ok(o);
1657 }
1658
1659 int z_SortMissingValueAction(ODR o, Z_SortMissingValueAction **p, int opt)
1660 {
1661     static Odr_arm arm[] =
1662     {
1663         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_SortMissingValAct_abort, odr_null},
1664         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_SortMissingValAct_null, odr_null},
1665         {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_SortMissingValAct_valData,
1666             odr_octetstring},
1667         {-1, -1, -1, -1, 0}
1668     };
1669
1670     if (!odr_initmember(o, p, sizeof(**p)))
1671         return opt && odr_ok(o);
1672     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
1673         return 1;
1674     *p = 0;
1675     return opt && odr_ok(o);
1676 }
1677
1678 int z_SortKeySpec(ODR o, Z_SortKeySpec **p, int opt)
1679 {
1680     if (!odr_sequence_begin(o, p, sizeof(**p)))
1681         return opt && odr_ok(o);
1682     return
1683         z_SortElement(o, &(*p)->sortElement, 0) &&
1684         odr_implicit(o, odr_integer, &(*p)->sortRelation, ODR_CONTEXT, 1, 0) &&
1685         odr_implicit(o, odr_integer, &(*p)->caseSensitivity, ODR_CONTEXT,
1686             2, 0) &&
1687         odr_explicit(o, z_SortMissingValueAction, &(*p)->missingValueAction,
1688             ODR_CONTEXT, 3, 1) &&
1689         odr_sequence_end(o);
1690 }
1691
1692 int z_SortResponse(ODR o, Z_SortResponse **p, int opt)
1693 {
1694     if (!odr_sequence_begin(o, p, sizeof(**p)))
1695         return opt && odr_ok(o);
1696     return
1697         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1698         odr_implicit(o, odr_integer, &(*p)->sortStatus, ODR_CONTEXT,
1699             3, 0) &&
1700         odr_implicit(o, odr_integer, &(*p)->resultSetStatus, ODR_CONTEXT,
1701             4, 1) &&
1702         odr_implicit(o, z_DiagRecs, &(*p)->diagnostics, ODR_CONTEXT, 5, 1) &&
1703         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1704         odr_sequence_end(o);
1705 }
1706
1707 int z_SortKeySpecList(ODR o, Z_SortKeySpecList **p, int opt)
1708 {
1709     if (!odr_initmember(o, p, sizeof(**p)))
1710         return opt && odr_ok(o);
1711     if (odr_sequence_of(o, z_SortKeySpec, &(*p)->specs, &(*p)->num_specs))
1712         return 1;
1713     *p = 0;
1714     return opt && odr_ok(o);
1715 }
1716
1717 int z_SortRequest(ODR o, Z_SortRequest **p, int opt)
1718 {
1719     if (!odr_sequence_begin(o, p, sizeof(**p)))
1720         return opt && odr_ok(o);
1721     return
1722         z_ReferenceId(o, &(*p)->referenceId, 1) &&
1723         odr_implicit(o, z_StringList, &(*p)->inputResultSetNames, 
1724             ODR_CONTEXT, 3, 0) &&
1725         odr_implicit(o, z_InternationalString, &(*p)->sortedResultSetName,
1726             ODR_CONTEXT, 4, 0) &&
1727         odr_implicit(o, z_SortKeySpecList, &(*p)->sortSequence, ODR_CONTEXT,
1728             5, 0) &&
1729         z_OtherInformation(o, &(*p)->otherInfo, 1) &&
1730         odr_sequence_end(o);
1731 }
1732
1733 /* ------------------------ APDU ------------------------- */
1734
1735 int z_APDU(ODR o, Z_APDU **p, int opt)
1736 {
1737     static Odr_arm arm[] =
1738     {
1739         {ODR_IMPLICIT, ODR_CONTEXT, 20, Z_APDU_initRequest, z_InitRequest},
1740         {ODR_IMPLICIT, ODR_CONTEXT, 21, Z_APDU_initResponse, z_InitResponse},
1741         {ODR_IMPLICIT, ODR_CONTEXT, 22, Z_APDU_searchRequest, z_SearchRequest},
1742         {ODR_IMPLICIT, ODR_CONTEXT, 23, Z_APDU_searchResponse,
1743             z_SearchResponse},
1744         {ODR_IMPLICIT, ODR_CONTEXT, 24, Z_APDU_presentRequest,
1745             z_PresentRequest},
1746         {ODR_IMPLICIT, ODR_CONTEXT, 25, Z_APDU_presentResponse,
1747             z_PresentResponse},
1748         {ODR_IMPLICIT, ODR_CONTEXT, 26, Z_APDU_deleteResultSetRequest,
1749             z_DeleteResultSetRequest},
1750         {ODR_IMPLICIT, ODR_CONTEXT, 27, Z_APDU_deleteResultSetResponse,
1751             z_DeleteResultSetResponse},
1752         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_APDU_accessControlRequest,
1753             z_AccessControlRequest},
1754         {ODR_IMPLICIT, ODR_CONTEXT, 29, Z_APDU_accessControlResponse,
1755             z_AccessControlResponse},
1756         {ODR_IMPLICIT, ODR_CONTEXT, 30, Z_APDU_resourceControlRequest,
1757             z_ResourceControlRequest},
1758         {ODR_IMPLICIT, ODR_CONTEXT, 31, Z_APDU_resourceControlResponse,
1759             z_ResourceControlResponse},
1760         {ODR_IMPLICIT, ODR_CONTEXT, 32, Z_APDU_triggerResourceControlRequest,
1761             z_TriggerResourceControlRequest},
1762         {ODR_IMPLICIT, ODR_CONTEXT, 35, Z_APDU_scanRequest, z_ScanRequest},
1763         {ODR_IMPLICIT, ODR_CONTEXT, 36, Z_APDU_scanResponse, z_ScanResponse},
1764         {ODR_IMPLICIT, ODR_CONTEXT, 43, Z_APDU_sortRequest, z_SortRequest},
1765         {ODR_IMPLICIT, ODR_CONTEXT, 44, Z_APDU_sortResponse, z_SortResponse},
1766         {ODR_IMPLICIT, ODR_CONTEXT, 45, Z_APDU_segmentRequest, z_Segment},
1767         {ODR_IMPLICIT, ODR_CONTEXT, 46, Z_APDU_extendedServicesRequest,
1768             z_ExtendedServicesRequest},
1769         {ODR_IMPLICIT, ODR_CONTEXT, 47, Z_APDU_extendedServicesResponse,
1770             z_ExtendedServicesResponse},
1771         {ODR_IMPLICIT, ODR_CONTEXT, 48, Z_APDU_close, z_Close},
1772
1773         {-1, -1, -1, -1, 0}
1774     };
1775
1776     if (o->direction == ODR_DECODE)
1777         *p = odr_malloc(o, sizeof(**p));
1778     if (!odr_choice(o, arm, &(*p)->u, &(*p)->which))
1779     {
1780         if (o->direction == ODR_DECODE)
1781             *p = 0;
1782         return opt && odr_ok(o);
1783     }
1784     return 1;
1785 }