Added state-handle and some support for asynchronous activities.
[yaz-moved-to-github.git] / odr / odr_choice.c
1 /*
2  * Copyright (C) 1994, Index Data I/S 
3  * All rights reserved.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: odr_choice.c,v $
7  * Revision 1.5  1995-03-18 12:16:31  quinn
8  * Minor changes.
9  *
10  * Revision 1.4  1995/03/14  16:59:38  quinn
11  * Added odr_constructed_more check
12  *
13  * Revision 1.3  1995/03/08  12:12:22  quinn
14  * Added better error checking.
15  *
16  * Revision 1.2  1995/02/09  15:51:48  quinn
17  * Works better now.
18  *
19  * Revision 1.1  1995/02/07  17:52:59  quinn
20  * A damn mess, but now things work, I think.
21  *
22  */
23
24 #include <odr.h>
25
26 int odr_choice(ODR o, Odr_arm arm[], void *p, void *whichp)
27 {
28     int i, cl = -1, tg, cn, *which = whichp;
29
30     if (o->error)
31         return 0;
32     if (o->direction != ODR_DECODE && !*(char**)p)
33         return 0;
34     for (i = 0; arm[i].fun; i++)
35     {
36         if (o->direction == ODR_DECODE)
37             *which = arm[i].which;
38         else if (*which != arm[i].which)
39             continue;
40
41         if (arm[i].tagmode != ODR_NONE)
42         {
43             if (o->direction == ODR_DECODE && cl < 0)
44             {
45                 if (o->stackp > -1 && !odr_constructed_more(o))
46                     return 0;
47                 if (ber_dectag(o->bp, &cl, &tg, &cn) <= 0)
48                     return 0;
49             }
50             else if (o->direction != ODR_DECODE)
51             {
52                 cl = arm[i].class;
53                 tg = arm[i].tag;
54             }
55             if (tg == arm[i].tag && cl == arm[i].class)
56             {
57                 if (arm[i].tagmode == ODR_IMPLICIT)
58                 {
59                     odr_implicit_settag(o, cl, tg);
60                     return (*arm[i].fun)(o, p, 0);
61                 }
62                 /* explicit */
63                 if (!odr_constructed_begin(o, p, cl, tg))
64                     return 0;
65                 return (*arm[i].fun)(o, p, 0) &&
66                     odr_constructed_end(o);
67             }
68         }
69         else  /* no tagging. Have to poll type */
70             if ((*arm[i].fun)(o, p, 0))
71                 return 1;
72     }
73     *which = -1;
74     *(char*)p = 0;
75     return 0;
76 }