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