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