Improved EXTERNAL
[yaz-moved-to-github.git] / asn / prt-ext.c
1 /*
2  * Copyright (c) 1995, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: prt-ext.c,v $
7  * Revision 1.1  1995-08-15 13:37:41  quinn
8  * Improved EXTERNAL
9  *
10  *
11  */
12
13 #include <proto.h>
14
15 int z_External(ODR o, Z_External **p, int opt)
16 {
17     oident *oid;
18
19     static Odr_arm arm[] =
20     {
21         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_single, odr_any},
22         {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_External_octet, odr_octetstring},
23         {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_External_arbitrary, odr_bitstring},
24
25         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_SUTRS, z_SUTRS},
26         {ODR_EXPLICIT, ODR_CONTEXT, 0, Z_External_explainRecord,
27             z_ExplainRecord},
28         {-1, -1, -1, -1, 0}
29     };
30     /*
31      * The table below should be moved to the ODR structure itself and
32      * be an image of the association context: To help
33      * map indirect references when they show up. 
34      */
35     static struct
36     {
37         oid_value dref;
38         int what;          /* discriminator value for the external CHOICE */
39     } tab[] =
40     {
41         {VAL_SUTRS, Z_External_SUTRS},
42         {VAL_EXPLAIN, Z_External_explainRecord},
43         {VAL_NONE, 0}
44     };
45
46     odr_implicit_settag(o, ODR_UNIVERSAL, ODR_EXTERNAL);
47     if (!odr_sequence_begin(o, p, sizeof(**p)))
48         return opt && odr_ok(o);
49     if (!(odr_oid(o, &(*p)->direct_reference, 1) &&
50         odr_integer(o, &(*p)->indirect_reference, 1) &&
51         odr_graphicstring(o, &(*p)->descriptor, 1)))
52         return 0;
53     /*
54      * Do we know this beast?
55      */
56     if (o->direction == ODR_DECODE && (*p)->direct_reference &&
57         (oid = oid_getentbyoid((*p)->direct_reference)))
58     {
59         int i;
60
61         for (i = 0; tab[i].dref != VAL_NONE; i++)
62             if (oid->value == tab[i].dref)
63             {
64                 odr_choice_bias(o, tab[i].what);
65                 break;
66             }
67     }
68     return
69         odr_choice(o, arm, &(*p)->u, &(*p)->which) &&
70         odr_sequence_end(o);
71 }