Added SILC Thread Queue API
[silc.git] / lib / silcasn1 / silcasn1_i.h
1 /*
2
3   silcasn1_i.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2003 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #ifndef SILCASN1_I_H
21 #define SILCASN1_I_H
22
23 #ifndef SILCASN1_H
24 #error "Do not include this header directly"
25 #endif
26
27 /* ASN.1 context */
28 struct SilcAsn1Object {
29   SilcStack orig_stack;         /* Stack given to silc_asn1_alloc */
30   SilcStack stack1;             /* Stack for encoder */
31   SilcStack stack2;             /* Internal stack for encoding/decoding */
32   va_list ap;                   /* List of ASN.1 types given as argument */
33   unsigned int accumul  : 1;    /* Accumulate memory from stack for result */
34   unsigned int switched  : 1;   /* Set when stack2 is set to stack1 */
35 };
36
37 /* The maximum depth for recursion in encoder and decoder. */
38 #define SILC_ASN1_RECURSION_DEPTH 512
39
40 /* Implementation specific special tags.  Range is 0x7000 - 0x7fff. */
41 #define SILC_ASN1_TAG_ANY           0x7000  /* SILC_ASN1_ANY given  */
42 #define SILC_ASN1_TAG_FUNC          0x7001  /* Callback encoder/decoder */
43 #define SILC_ASN1_TAG_OPTS          0x7002  /* SILC_ASN1_OPTS given */
44 #define SILC_ASN1_TAG_CHOICE        0x7003  /* SILC_ASN1_CHOICE given */
45 #define SILC_ASN1_TAG_SEQUENCE_OF   0x7004  /* SILC_ASN1_SEQUENCE_OF given */
46 #define SILC_ASN1_TAG_ANY_PRIMITIVE 0x7005  /* Pre-encoded primitive data */
47 #define SILC_ASN1_TAG_SHORT_INTEGER 0x7006  /* Short integer */
48
49 /* Helper macros for adding the arguments to encoder and decoder. */
50
51 /* The arguments to silc_asn1_encode and silc_asn1_decode are constructed
52    as follows:
53
54    The first argument for type is a 32 bit integer where first 15-bits are
55    reserved for the type.  If the bit 16 is set then type and tag are same
56    and next argument is NOT the tag number.  If bit 16 is not set then
57    next argument is a 32 bit tag number.  This then also means that the type
58    is either implicitly or explicitly tagged.  The second 16-bits of the
59    first 32-bits argument is reserved for options.
60
61    Any argument that follow the type and optional tag number argument are
62    type specific arguments.
63
64    The SILC_ASN1_Ux macros set the bit 16, since the type and tag are same,
65    and also options are set to zero (0).
66
67    The SILC_ASN1_Tx macros does not set bit 16, but separate tag argument is
68    provided.  Options may or may not be zero, and they are put at the high
69    16-bits part of the first 32-bit argument.
70 */
71
72 #define SILC_ASN1_U0(type) \
73   SILC_ASN1_TAG_ ## type | 0x8000
74 #define SILC_ASN1_U1(type, x) \
75   SILC_ASN1_TAG_ ## type | 0x8000, (x)
76 #define SILC_ASN1_U2(type, x, xl) \
77   SILC_ASN1_TAG_ ## type | 0x8000, (x), (xl)
78
79 #define SILC_ASN1_T0(type, o, t) \
80   SILC_ASN1_TAG_ ## type | (o) << 16, (t)
81 #define SILC_ASN1_T1(type, o, t, x) \
82   SILC_ASN1_TAG_ ## type | (o) << 16, (t), (x)
83 #define SILC_ASN1_T2(type, o, t, x, xl) \
84   SILC_ASN1_TAG_ ## type | (o) << 16, (t), (x), (xl)
85
86 /* Macro to retreive type, options and tag.  The ret_type will include
87    the actual type, ret_class the BER class from options, ret_opts the
88    options (without the class), and ret_tag the tag. */
89 #define SILC_ASN1_ARGS(asn1, ret_type, ret_tag, ret_class, ret_opts)    \
90   ret_type = va_arg(asn1->ap, SilcUInt32);                              \
91   ret_tag = ret_class = ret_opts = 0;                                   \
92   if (ret_type != SILC_ASN1_END &&                                      \
93       ret_type != SILC_ASN1_TAG_OPTS) {                                 \
94     if (ret_type & 0x8000)                                              \
95       ret_tag = (ret_type & 0xffff) & ~0x8000;                          \
96     else                                                                \
97       ret_tag = va_arg(asn1->ap, SilcUInt32);                           \
98     ret_class = ret_type >> 16 & 0xf;                                   \
99     ret_opts = ret_type >> 16 & ~0xf;                                   \
100     if (ret_class)                                                      \
101       ret_class--;                                                      \
102     ret_type = (ret_type & 0xffff) & ~0x8000;                           \
103   }
104
105 /* Internal functions */
106
107 #if defined(SILC_DEBUG)
108 /* Returns string representation of a tag */
109 const char *silc_asn1_tag_name(SilcAsn1Tag tag);
110 #endif /* SILC_DEBUG */
111
112 #ifdef SILC_DIST_INPLACE
113 /* Dumps the ASN.1 data block into standard output (stdout). */
114 SilcBool silc_asn1_dump(SilcAsn1 asn1, SilcBuffer src);
115 #endif /* SILC_DIST_INPLACE */
116
117 #endif /* SILCASN1_I_H */