Added Resource control protocol
[yaz-moved-to-github.git] / asn / proto.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: proto.c,v $
7  * Revision 1.15  1995-03-30 09:08:39  quinn
8  * Added Resource control protocol
9  *
10  * Revision 1.14  1995/03/29  08:06:13  quinn
11  * Added a few v3 elements
12  *
13  * Revision 1.13  1995/03/20  11:26:52  quinn
14  * *** empty log message ***
15  *
16  * Revision 1.12  1995/03/20  09:45:09  quinn
17  * Working towards v3
18  *
19  * Revision 1.11  1995/03/17  10:17:25  quinn
20  * Added memory management.
21  *
22  * Revision 1.10  1995/03/15  11:17:40  quinn
23  * Fixed some return-checks from choice.. need better ay to handle those..
24  *
25  * Revision 1.9  1995/03/15  08:37:06  quinn
26  * Fixed protocol bugs.
27  *
28  * Revision 1.8  1995/03/14  16:59:24  quinn
29  * Fixed OPTIONAL flag in attributeelement
30  *
31  * Revision 1.7  1995/03/07  16:29:33  quinn
32  * Added authentication stuff.
33  *
34  * Revision 1.6  1995/03/01  14:46:03  quinn
35  * Fixed protocol bug in 8777query.
36  *
37  * Revision 1.5  1995/02/14  11:54:22  quinn
38  * Fixing include.
39  *
40  * Revision 1.4  1995/02/10  15:54:30  quinn
41  * Small adjustments.
42  *
43  * Revision 1.3  1995/02/09  15:51:39  quinn
44  * Works better now.
45  *
46  * Revision 1.2  1995/02/06  21:26:07  quinn
47  * Repaired this evening's damages..
48  *
49  * Revision 1.1  1995/02/06  16:44:47  quinn
50  * First hack at Z/SR protocol
51  *
52  */
53
54 #include <odr.h>
55
56 #include <proto.h>
57
58 /* ---------------------- GLOBAL DEFS ------------------- */
59
60 int z_ReferenceId(ODR o, Z_ReferenceId **p, int opt)
61 {
62     return odr_implicit(o, odr_octetstring, (Odr_oct**) p, ODR_CONTEXT, 2, opt);
63 }
64
65 int z_DatabaseName(ODR o, Z_DatabaseName **p, int opt)
66 {
67     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 105,
68         opt);
69 }
70
71 int z_ResultSetId(ODR o, char **p, int opt)
72 {
73     return odr_implicit(o, odr_visiblestring, (char **) p, ODR_CONTEXT, 31,
74         opt);
75 }
76
77 int z_UserInformationField(ODR o, Z_UserInformationField **p, int opt)
78 {
79     return odr_explicit(o, odr_external, (Odr_external **)p, ODR_CONTEXT,
80         11, opt);
81 }
82
83 /* ---------------------- INITIALIZE SERVICE ------------------- */
84
85 int z_NSRAuthentication(ODR o, Z_NSRAuthentication **p, int opt)
86 {
87     if (!odr_sequence_begin(o, p, sizeof(**p)))
88         return opt;
89     return
90         odr_visiblestring(o, &(*p)->user, 0) &&
91         odr_visiblestring(o, &(*p)->password, 0) &&
92         odr_visiblestring(o, &(*p)->account, 0) &&
93         odr_sequence_end(o);
94 }
95
96 int z_IdPass(ODR o, Z_IdPass **p, int opt)
97 {
98     if (!odr_sequence_begin(o, p, sizeof(**p)))
99         return opt;
100     return
101         odr_implicit(o, odr_visiblestring, &(*p)->groupId, ODR_CONTEXT, 0, 0) &&
102         odr_implicit(o, odr_visiblestring, &(*p)->userId, ODR_CONTEXT, 1, 0) &&
103         odr_implicit(o, odr_visiblestring, &(*p)->password, ODR_CONTEXT, 2,
104             0) &&
105         odr_sequence_end(o);
106 }
107
108 int z_StrAuthentication(ODR o, char **p, int opt)
109 {
110     return odr_visiblestring(o, p, opt);
111 }
112
113 int z_IdAuthentication(ODR o, Z_IdAuthentication **p, int opt)
114 {
115     static Odr_arm arm[] =
116     {
117         {-1, -1, -1, Z_IdAuthentication_open, z_StrAuthentication},
118         {-1, -1, -1, Z_IdAuthentication_idPass, z_NSRAuthentication},
119         {-1, -1, -1, Z_IdAuthentication_anonymous, odr_null},
120         {-1, -1, -1, Z_IdAuthentication_other, odr_external},
121         {-1, -1, -1, -1, 0}
122     };
123
124     if (o->direction == ODR_DECODE)
125         *p = odr_malloc(o, sizeof(**p));
126
127     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
128         return 1;
129     *p = 0;
130     return opt && !o->error;
131 }
132
133 int z_InitRequest(ODR o, Z_InitRequest **p, int opt)
134 {
135     Z_InitRequest *pp;
136
137     if (!odr_sequence_begin(o, p, sizeof(**p)))
138         return opt;
139     pp = *p;
140     return
141         z_ReferenceId(o, &pp->referenceId, 1) &&
142         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
143             3, 0) &&
144         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
145         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
146             5, 0) &&
147         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
148             6, 0) &&
149         odr_explicit(o, z_IdAuthentication, &pp->idAuthentication, ODR_CONTEXT,
150             7, 1) &&
151         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
152             110, 1) &&
153         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
154             111, 1) &&
155         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
156             ODR_CONTEXT, 112, 1) &&
157         z_UserInformationField(o, &pp->userInformationField, 1) &&
158         odr_sequence_end(o);
159 }
160
161 int z_InitResponse(ODR o, Z_InitResponse **p, int opt)
162 {
163     Z_InitResponse *pp;
164
165     if (!odr_sequence_begin(o, p, sizeof(**p)))
166         return opt;
167     pp = *p;
168     return
169         z_ReferenceId(o, &pp->referenceId, 1) &&
170         odr_implicit(o, odr_bitstring, &pp->protocolVersion, ODR_CONTEXT, 
171             3, 0) &&
172         odr_implicit(o, odr_bitstring, &pp->options, ODR_CONTEXT, 4, 0) &&
173         odr_implicit(o, odr_integer, &pp->preferredMessageSize, ODR_CONTEXT,
174             5, 0) &&
175         odr_implicit(o, odr_integer, &pp->maximumRecordSize, ODR_CONTEXT,
176             6, 0) &&
177         odr_implicit(o, odr_bool, &pp->result, ODR_CONTEXT, 12, 0) &&
178         odr_implicit(o, odr_visiblestring, &pp->implementationId, ODR_CONTEXT,
179             110, 1) &&
180         odr_implicit(o, odr_visiblestring, &pp->implementationName, ODR_CONTEXT,
181             111, 1) &&
182         odr_implicit(o, odr_visiblestring, &pp->implementationVersion,
183             ODR_CONTEXT, 112, 1) &&
184         z_UserInformationField(o, &pp->userInformationField, 1) &&
185         odr_sequence_end(o);
186 }
187
188 /* ------------------ RESOURCE CONTROL ----------------*/
189
190 int z_TriggerResourceControlRequest(ODR o, Z_TriggerResourceControlRequest **p,
191                                     int opt)
192 {
193     if (!odr_sequence_begin(o, p, sizeof(**p)))
194         return opt;
195     return
196         z_ReferenceId(o, &(*p)->referenceId, 1) &&
197         odr_implicit(o, odr_integer, &(*p)->requestedAction, ODR_CONTEXT,
198             46, 0) &&
199         odr_implicit(o, odr_oid, &(*p)->prefResourceReportFormat,
200             ODR_CONTEXT, 47, 1) &&
201         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
202             48, 1) &&
203         odr_sequence_end(o);
204 }
205
206 int z_ResourceControlRequest(ODR o, Z_ResourceControlRequest **p, int opt)
207 {
208     if (!odr_sequence_begin(o, p, sizeof(**p)))
209         return opt;
210     return
211         z_ReferenceId(o, &(*p)->referenceId, 1) &&
212         odr_implicit(o, odr_bool, &(*p)->suspendedFlag, ODR_CONTEXT, 39, 1)&&
213         odr_explicit(o, odr_external, &(*p)->resourceReport, ODR_CONTEXT,
214             40, 1) &&
215         odr_implicit(o, odr_integer, &(*p)->partialResultsAvailable,
216             ODR_CONTEXT, 41, 1) &&
217         odr_implicit(o, odr_bool, &(*p)->responseRequired, ODR_CONTEXT,
218             42, 0) &&
219         odr_implicit(o, odr_bool, &(*p)->triggeredRequestFlag,
220             ODR_CONTEXT, 43, 1) &&
221         odr_sequence_end(o);
222 }
223
224 int z_ResourceControlResponse(ODR o, Z_ResourceControlResponse **p, int opt)
225 {
226     if (!odr_sequence_begin(o, p, sizeof(**p)))
227         return opt;
228     return
229         z_ReferenceId(o, &(*p)->referenceId, 1) &&
230         odr_implicit(o, odr_bool, &(*p)->continueFlag, ODR_CONTEXT, 44, 0) &&
231         odr_implicit(o, odr_bool, &(*p)->resultSetWanted, ODR_CONTEXT,
232             45, 1) &&
233         odr_sequence_end(o);
234 }
235
236 /* ------------------------ SEARCH SERVICE ----------------------- */
237
238 int z_ElementSetName(ODR o, char **p, int opt)
239 {
240     return odr_implicit(o, odr_visiblestring, (char**) p, ODR_CONTEXT, 103,
241         opt);
242 }
243
244 int z_PreferredRecordSyntax(ODR o, Z_PreferredRecordSyntax **p, int opt)
245 {
246     return odr_implicit(o, odr_oid, (Odr_oid**) p, ODR_CONTEXT, 104, opt);
247 }
248
249 int z_DatabaseSpecificUnit(ODR o, Z_DatabaseSpecificUnit **p, int opt)
250 {
251     if (!odr_sequence_begin(o, p, sizeof(**p)))
252         return opt;
253     return
254         z_DatabaseName(o, &(*p)->databaseName, 0) &&
255         z_ElementSetName(o, &(*p)->elementSetName, 0) &&
256         odr_sequence_end(o);
257 }
258
259 int z_DatabaseSpecific(ODR o, Z_DatabaseSpecific **p, int opt)
260 {
261     if (o->direction == ODR_DECODE)
262         *p = odr_malloc(o, sizeof(**p));
263     else if (!*p)
264         return opt;
265
266     odr_implicit_settag(o, ODR_CONTEXT, 1);
267     if (odr_sequence_of(o, z_DatabaseSpecificUnit, &(*p)->elements,
268         &(*p)->num_elements))
269         return 1;
270     *p = 0;
271     return 0;
272 }
273
274 int z_ElementSetNames(ODR o, Z_ElementSetNames **p, int opt)
275 {
276     static Odr_arm arm[] =
277     {
278         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_ElementSetNames_generic,
279             z_ElementSetName},
280         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_ElementSetNames_databaseSpecific,
281             z_DatabaseSpecific},
282         {-1, -1, -1, -1, 0}
283     };
284
285     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 19))
286         return opt;
287
288     if (o->direction == ODR_DECODE)
289         *p = odr_malloc(o, sizeof(**p));
290
291     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
292         odr_constructed_end(o))
293         return 1;
294     *p = 0;
295     return 0;
296 }
297
298 /* ----------------------- RPN QUERY -----------------------*/
299
300 int z_AttributeElement(ODR o, Z_AttributeElement **p, int opt)
301 {
302     if (!odr_sequence_begin(o, p, sizeof(**p)))
303         return opt;
304     return
305         odr_implicit(o, odr_integer, &(*p)->attributeType, ODR_CONTEXT,
306             120, 0) &&
307         odr_implicit(o, odr_integer, &(*p)->attributeValue, ODR_CONTEXT,
308             121, 0) &&
309         odr_sequence_end(o);
310 }
311
312 int z_AttributesPlusTerm(ODR o, Z_AttributesPlusTerm **p, int opt)
313 {
314     if (!(odr_implicit_settag(o, ODR_CONTEXT, 102) &&
315         odr_sequence_begin(o, p, sizeof(**p))))
316         return opt;
317     return
318         odr_implicit_settag(o, ODR_CONTEXT, 44) &&
319         odr_sequence_of(o, z_AttributeElement, &(*p)->attributeList,
320             &(*p)->num_attributes) &&
321         odr_implicit(o, odr_octetstring, &(*p)->term, ODR_CONTEXT, 45, 0) &&
322         odr_sequence_end(o);
323 }
324
325 int z_Operator(ODR o, Z_Operator **p, int opt)
326 {
327     static Odr_arm arm[] =
328     {
329         {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_Operator_and, odr_null},
330         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Operator_or, odr_null},
331         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_Operator_and_not, odr_null},
332         {-1, -1, -1, -1, 0}
333     };
334     int dummy = 999;
335
336     if (!*p && o->direction != ODR_DECODE)
337         return opt;
338     if (!odr_constructed_begin(o, p, ODR_CONTEXT, 46))
339         return opt;
340     if (o->direction == ODR_DECODE)
341         *p = odr_malloc(o, sizeof(**p));
342     else
343         (*p)->u.and = &dummy;
344
345     if (odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
346         odr_constructed_end(o))
347         return 1;
348     *p = 0;
349     return opt && !o->error;
350 }
351
352 int z_Operand(ODR o, Z_Operand **p, int opt)
353 {
354     static Odr_arm arm[] =
355     {
356         {-1, -1, -1, Z_Operand_APT, z_AttributesPlusTerm},
357         {-1, -1, -1, Z_Operand_resultSetId, z_ResultSetId},
358         {-1, -1, -1, -1, 0}
359     };
360
361     if (o->direction ==ODR_DECODE)
362         *p = odr_malloc(o, sizeof(**p));
363     else if (!*p)
364         return opt;
365     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
366         return 1;
367     *p = 0;
368     return opt && !o->error;
369 }
370
371 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt);
372
373 int z_Complex(ODR o, Z_Complex **p, int opt)
374 {
375     if (!odr_sequence_begin(o, p, sizeof(**p)))
376         return opt;
377     return
378         z_RPNStructure(o, &(*p)->s1, 0) &&
379         z_RPNStructure(o, &(*p)->s2, 0) &&
380         z_Operator(o, &(*p)->operator, 0) &&
381         odr_sequence_end(o);
382 }
383
384 int z_RPNStructure(ODR o, Z_RPNStructure **p, int opt)
385 {
386     static Odr_arm arm[] = 
387     {
388         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_RPNStructure_simple, z_Operand},
389         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_RPNStructure_complex, z_Complex},
390         {-1 -1, -1, -1, 0}
391     };
392
393     if (o->direction == ODR_DECODE)
394         *p = odr_malloc(o, sizeof(**p));
395     else if (!*p)
396         return opt;
397     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
398         return 1;
399     *p = 0;
400     return opt && !o->error;
401 }
402
403 int z_RPNQuery(ODR o, Z_RPNQuery **p, int opt)
404 {
405     if (!odr_sequence_begin(o, p, sizeof(**p)))
406         return opt;
407     return
408         odr_oid(o, &(*p)->attributeSetId, 0) &&
409         z_RPNStructure(o, &(*p)->RPNStructure, 0) &&
410         odr_sequence_end(o);
411 }
412
413 /* -----------------------END RPN QUERY ----------------------- */
414
415 int z_Query(ODR o, Z_Query **p, int opt)
416 {
417     static Odr_arm arm[] = 
418     {
419         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_Query_type_1, z_RPNQuery},
420         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_Query_type_2, odr_octetstring},
421         {-1, -1, -1, -1, 0}
422     };
423
424     if (o->direction == ODR_DECODE)
425         *p = odr_malloc(o, sizeof(**p));
426     else if (!*p)
427         return opt;
428     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
429         return 1;
430     *p = 0;
431     return opt && !o->error;
432 }
433
434 int z_SearchRequest(ODR o, Z_SearchRequest **p, int opt)
435 {
436     Z_SearchRequest *pp;
437
438     if (!odr_sequence_begin(o, p, sizeof(**p)))
439         return opt;
440     pp = *p;
441     return
442         z_ReferenceId(o, &pp->referenceId, 1) &&
443         odr_implicit(o, odr_integer, &pp->smallSetUpperBound, ODR_CONTEXT,
444             13, 0) &&
445         odr_implicit(o, odr_integer, &pp->largeSetLowerBound, ODR_CONTEXT,
446             14, 0) &&
447         odr_implicit(o, odr_integer, &pp->mediumSetPresentNumber, ODR_CONTEXT,
448             15, 0) &&
449         odr_implicit(o, odr_bool, &pp->replaceIndicator, ODR_CONTEXT, 16, 1) &&
450         odr_implicit(o, odr_visiblestring, &pp->resultSetName, ODR_CONTEXT,
451             17, 9) &&
452         odr_implicit_settag(o, ODR_CONTEXT, 18) &&
453         odr_sequence_of(o, z_DatabaseName, &pp->databaseNames,
454             &pp->num_databaseNames) &&
455         odr_explicit(o, z_ElementSetNames, &pp->smallSetElementSetNames,
456             ODR_CONTEXT, 100, 1) &&
457         odr_explicit(o, z_ElementSetNames, &pp->mediumSetElementSetNames,
458             ODR_CONTEXT, 101, 1) &&
459         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
460         odr_explicit(o, z_Query, &pp->query, ODR_CONTEXT, 21, 0) &&
461         odr_sequence_end(o);
462 }
463
464 /* ------------------------ RECORD ------------------------- */
465
466 int z_DatabaseRecord(ODR o, Z_DatabaseRecord **p, int opt)
467 {
468     return odr_external(o, (Odr_external **) p, opt);
469 }
470
471 int z_DiagRec(ODR o, Z_DiagRec **p, int opt)
472 {
473     if (!odr_sequence_begin(o, p, sizeof(**p)))
474         return opt;
475     return
476         odr_oid(o, &(*p)->diagnosticSetId, 1) &&       /* SHOULD NOT BE OPT */
477         odr_integer(o, &(*p)->condition, 0) &&
478         (odr_visiblestring(o, &(*p)->addinfo, 0) ||
479         odr_implicit(o, odr_cstring, &(*p)->addinfo, ODR_CONTEXT, ODR_VISIBLESTRING, 1)) &&
480         odr_sequence_end(o);
481 }
482
483 int z_NamePlusRecord(ODR o, Z_NamePlusRecord **p, int opt)
484 {
485     static Odr_arm arm[] =
486     {
487         {ODR_EXPLICIT, ODR_CONTEXT, 1, Z_NamePlusRecord_databaseRecord,
488             z_DatabaseRecord},
489         {ODR_EXPLICIT, ODR_CONTEXT, 2, Z_NamePlusRecord_surrogateDiagnostic,
490             z_DiagRec},
491         {-1, -1, -1, -1, 0}
492     };
493
494     if (!odr_sequence_begin(o, p, sizeof(**p)))
495         return opt;
496     return
497         odr_implicit(o, z_DatabaseName, &(*p)->databaseName, ODR_CONTEXT,
498             0, 1) &&
499         odr_constructed_begin(o, &(*p)->u, ODR_CONTEXT, 1) &&
500         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
501         odr_constructed_end(o) &&
502         odr_sequence_end(o);
503 }
504
505 int z_NamePlusRecordList(ODR o, Z_NamePlusRecordList **p, int opt)
506 {
507     if (o->direction == ODR_DECODE)
508         *p = odr_malloc(o, sizeof(**p));
509     if (odr_sequence_of(o, z_NamePlusRecord, &(*p)->records,
510         &(*p)->num_records))
511         return 1;
512     *p = 0;
513     return 0;
514 }
515
516 int z_Records(ODR o, Z_Records **p, int opt)
517 {
518     Odr_arm arm[] = 
519     {
520         {ODR_IMPLICIT, ODR_CONTEXT, 28, Z_Records_DBOSD, z_NamePlusRecordList},
521         {ODR_IMPLICIT, ODR_CONTEXT, 130, Z_Records_NSD, z_DiagRec},
522         {-1, -1, -1, -1, 0}
523     };
524
525     if (o->direction == ODR_DECODE)
526         *p = odr_malloc(o, sizeof(**p));
527     else if (!*p)
528         return opt;
529     if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
530         return 1;
531     *p = 0;
532     return opt && !o->error;
533 }
534
535 /* ------------------------ SEARCHRESPONSE ----------------*/
536
537 int z_NumberOfRecordsReturned(ODR o, int **p, int opt)
538 {
539     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 24, opt);
540 }
541
542 int z_NextResultSetPosition(ODR o, int **p, int opt)
543 {
544     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 25, opt);
545 }
546
547 int z_PresentStatus(ODR o, int **p, int opt)
548 {
549     return odr_implicit(o, odr_integer, p, ODR_CONTEXT, 27, opt);
550 }
551
552 int z_SearchResponse(ODR o, Z_SearchResponse **p, int opt)
553 {
554     Z_SearchResponse *pp;
555
556     if (!odr_sequence_begin(o, p, sizeof(**p)))
557         return opt;
558     pp = *p;
559     return
560         z_ReferenceId(o, &pp->referenceId, 1) &&
561         odr_implicit(o, odr_integer, &pp->resultCount, ODR_CONTEXT, 23, 0) &&
562         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
563         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
564         odr_implicit(o, odr_bool, &pp->searchStatus, ODR_CONTEXT, 22, 0) &&
565         odr_implicit(o, odr_integer, &pp->resultSetStatus, ODR_CONTEXT, 26, 1) &&
566         z_PresentStatus(o, &pp->presentStatus, 1) &&
567         z_Records(o, &pp->records, 1) &&
568         odr_sequence_end(o);
569 }
570
571 /* --------------------- PRESENT SERVICE ---------------------- */
572
573 int z_PresentRequest(ODR o, Z_PresentRequest **p, int opt)
574 {
575     Z_PresentRequest *pp;
576
577     if (!odr_sequence_begin(o, p, sizeof(**p)))
578         return opt;
579     pp = *p;
580     return
581         z_ReferenceId(o, &pp->referenceId, 1) &&
582         z_ResultSetId(o, &pp->resultSetId, 0) &&
583         odr_implicit(o, odr_integer, &pp->resultSetStartPoint, ODR_CONTEXT,
584             30, 0) &&
585         odr_implicit(o, odr_integer, &pp->numberOfRecordsRequested, ODR_CONTEXT,
586             29, 0) &&
587         z_ElementSetNames(o, &pp->elementSetNames, 1) &&
588         z_PreferredRecordSyntax(o, &pp->preferredRecordSyntax, 1) &&
589         odr_sequence_end(o);
590 }
591
592 int z_PresentResponse(ODR o, Z_PresentResponse **p, int opt)
593 {
594     Z_PresentResponse *pp;
595
596     if (!odr_sequence_begin(o, p, sizeof(**p)))
597         return opt;
598     pp = *p;
599     return
600         z_ReferenceId(o, &pp->referenceId, 1) &&
601         z_NumberOfRecordsReturned(o, &pp->numberOfRecordsReturned, 0) &&
602         z_NextResultSetPosition(o, &pp->nextResultSetPosition, 0) &&
603         z_PresentStatus(o, &pp->presentStatus, 0) &&
604         z_Records(o, &pp->records, 1) &&
605         odr_sequence_end(o);
606 }
607
608 /* ------------------------ APDU ------------------------- */
609
610 int z_APDU(ODR o, Z_APDU **p, int opt)
611 {
612     static Odr_arm arm[] =
613     {
614         {ODR_IMPLICIT, ODR_CONTEXT, 20, Z_APDU_initRequest, z_InitRequest},
615         {ODR_IMPLICIT, ODR_CONTEXT, 21, Z_APDU_initResponse, z_InitResponse},
616         {ODR_IMPLICIT, ODR_CONTEXT, 22, Z_APDU_searchRequest, z_SearchRequest},
617         {ODR_IMPLICIT, ODR_CONTEXT, 23, Z_APDU_searchResponse, z_SearchResponse},
618         {ODR_IMPLICIT, ODR_CONTEXT, 24, Z_APDU_presentRequest, z_PresentRequest},
619         {ODR_IMPLICIT, ODR_CONTEXT, 25, Z_APDU_presentResponse, z_PresentResponse},
620
621         {-1, -1, -1, -1, 0}
622     };
623
624     if (o->direction == ODR_DECODE)
625         *p = odr_malloc(o, sizeof(**p));
626     if (!odr_choice(o, arm, &(*p)->u, &(*p)->which))
627     {
628         if (o->direction == ODR_DECODE)
629             *p = 0;
630         return opt && !o->error;
631     }
632     return 1;
633 }