~ubuntu-branches/ubuntu/trusty/virtualbox-lts-xenial/trusty-proposed

« back to all changes in this revision

Viewing changes to include/iprt/asn1-generator-pass.h

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2016-02-23 14:28:26 UTC
  • Revision ID: package-import@ubuntu.com-20160223142826-bdu69el2z6wa2a44
Tags: upstream-4.3.36-dfsg
ImportĀ upstreamĀ versionĀ 4.3.36-dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 * IPRT - ASN.1 Code Generator, One Pass.
 
3
 */
 
4
 
 
5
/*
 
6
 * Copyright (C) 2006-2014 Oracle Corporation
 
7
 *
 
8
 * This file is part of VirtualBox Open Source Edition (OSE), as
 
9
 * available from http://www.virtualbox.org. This file is free software;
 
10
 * you can redistribute it and/or modify it under the terms of the GNU
 
11
 * General Public License (GPL) as published by the Free Software
 
12
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 
13
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 
14
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 
15
 *
 
16
 * The contents of this file may alternatively be used under the terms
 
17
 * of the Common Development and Distribution License Version 1.0
 
18
 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
 
19
 * VirtualBox OSE distribution, in which case the provisions of the
 
20
 * CDDL are applicable instead of those of the GPL.
 
21
 *
 
22
 * You may elect to license modified versions of this file under the
 
23
 * terms and conditions of either the GPL or the CDDL or both.
 
24
 */
 
25
 
 
26
 
 
27
#ifndef ___iprt_asn1_generator_pass_h
 
28
#define ___iprt_asn1_generator_pass_h
 
29
 
 
30
#include <iprt/formats/asn1.h>
 
31
 
 
32
 
 
33
/** @def RTASN1TMPL_MEMBER_OPT_ANY
 
34
 * Used for optional entries without any specific type at the end of a
 
35
 * structure.
 
36
 *
 
37
 * For example PolicyQualifierInfo's qualifier member which is defined as:
 
38
 *      ANY DEFINED BY policyQualifierId
 
39
 *
 
40
 * Defaults to RTASN1TMPL_MEMBER_EX.
 
41
 */
 
42
 
 
43
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_EX
 
44
 * Optional member with implict tag, extended version.
 
45
 *
 
46
 * This is what all the other RTASN1TMPL_MEMBER_OPT_ITAG* macros defere to.
 
47
 */
 
48
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_CP
 
49
 * Optional member of a typical primitive type with an implicit context tag.
 
50
 *
 
51
 * Examples of this can be found in AuthorityKeyIdentifier where the first and
 
52
 * last member are primitive types (normally anyways).:
 
53
 *      keyIdentifier [1] OCTET STRING OPTIONAL,
 
54
 *      authorityCertSerialNumber [3] INTEGER OPTIONAL
 
55
 */
 
56
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_UC
 
57
 * Optional member of a constructed type from the universal tag class.
 
58
 */
 
59
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_UP
 
60
 * Optional member of a primitive type from the universal tag class.
 
61
 */
 
62
 
 
63
 
 
64
/** @name Expansion Passes (RTASN1TMPL_PASS values)
 
65
 * @{  */
 
66
#define RTASN1TMPL_PASS_INTERNAL_HEADER 1
 
67
 
 
68
#define RTASN1TMPL_PASS_VTABLE          2
 
69
#define RTASN1TMPL_PASS_ENUM            3
 
70
#define RTASN1TMPL_PASS_DELETE          4
 
71
#define RTASN1TMPL_PASS_COMPARE         5
 
72
 
 
73
#define RTASN1TMPL_PASS_CHECK_SANITY    8
 
74
 
 
75
#define RTASN1TMPL_PASS_INIT           16
 
76
#define RTASN1TMPL_PASS_CLONE          17
 
77
#define RTASN1TMPL_PASS_SETTERS_1      18
 
78
#define RTASN1TMPL_PASS_SETTERS_2      19
 
79
 
 
80
#define RTASN1TMPL_PASS_DECODE         24
 
81
/** @} */
 
82
 
 
83
/** @name ITAG clues
 
84
 * @{  */
 
85
#define RTASN1TMPL_ITAG_F_CC            1 /**< context, constructed. */
 
86
#define RTASN1TMPL_ITAG_F_CP            2 /**< context, probably primary. (w/ numeric value) */
 
87
#define RTASN1TMPL_ITAG_F_UP            3 /**< universal, probably primary. (w/ ASN1_TAG_XXX value) */
 
88
#define RTASN1TMPL_ITAG_F_UC            4 /**< universal, constructed. (w/ ASN1_TAG_XXX value) */
 
89
/** @} */
 
90
/** Expands the ITAG clues into tag flag and tag class. */
 
91
#define RTASN1TMPL_ITAG_F_EXPAND(a_fClue) \
 
92
        (  a_fClue == RTASN1TMPL_ITAG_F_CC ? (ASN1_TAGCLASS_CONTEXT   | ASN1_TAGFLAG_CONSTRUCTED ) \
 
93
         : a_fClue == RTASN1TMPL_ITAG_F_CP ? (ASN1_TAGCLASS_CONTEXT   | ASN1_TAGFLAG_PRIMITIVE) \
 
94
         : a_fClue == RTASN1TMPL_ITAG_F_UP ? (ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_PRIMITIVE) \
 
95
         : a_fClue == RTASN1TMPL_ITAG_F_UC ? (ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED) \
 
96
         : 0 )
 
97
 
 
98
#define RTASN1TMPL_SEMICOLON_DUMMY() typedef unsigned RTASN1TMPLSEMICOLONDUMMY
 
99
 
 
100
#endif /* !___iprt_asn1_generator_pass_h */
 
101
 
 
102
 
 
103
#if RTASN1TMPL_PASS == RTASN1TMPL_PASS_INTERNAL_HEADER
 
104
/*
 
105
 *
 
106
 * Internal header file.
 
107
 *
 
108
 */
 
109
# define RTASN1TMPL_BEGIN_COMMON() extern DECLHIDDEN(RTASN1COREVTABLE const) RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
 
110
 
 
111
# define RTASN1TMPL_BEGIN_SEQCORE()                 RTASN1TMPL_BEGIN_COMMON()
 
112
# define RTASN1TMPL_BEGIN_SETCORE()                 RTASN1TMPL_BEGIN_COMMON()
 
113
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)                                 RTASN1TMPL_SEMICOLON_DUMMY()
 
114
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)                          RTASN1TMPL_SEMICOLON_DUMMY()
 
115
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                            RTASN1TMPL_SEMICOLON_DUMMY()
 
116
# define RTASN1TMPL_END_SEQCORE()                   RTASN1TMPL_SEMICOLON_DUMMY()
 
117
# define RTASN1TMPL_END_SETCORE()                   RTASN1TMPL_SEMICOLON_DUMMY()
 
118
 
 
119
 
 
120
# define RTASN1TMPL_BEGIN_PCHOICE()                 RTASN1TMPL_BEGIN_COMMON()
 
121
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
122
                                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
 
123
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
124
                                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
 
125
# define RTASN1TMPL_END_PCHOICE()                   RTASN1TMPL_SEMICOLON_DUMMY()
 
126
 
 
127
 
 
128
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_BEGIN_COMMON()
 
129
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_BEGIN_COMMON()
 
130
 
 
131
 
 
132
 
 
133
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_VTABLE
 
134
/*
 
135
 *
 
136
 * Internal header file.
 
137
 *
 
138
 */
 
139
# ifndef RTASN1TMPL_VTABLE_FN_ENCODE_PREP
 
140
#  define RTASN1TMPL_VTABLE_FN_ENCODE_PREP  NULL
 
141
# endif
 
142
# ifndef RTASN1TMPL_VTABLE_FN_ENCODE_WRITE
 
143
#  define RTASN1TMPL_VTABLE_FN_ENCODE_WRITE NULL
 
144
# endif
 
145
# define RTASN1TMPL_BEGIN_COMMON(a_uDefaultTag, a_fDefaultClass) \
 
146
    DECL_HIDDEN_CONST(RTASN1COREVTABLE const) RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable) = \
 
147
    { \
 
148
        /* When the Asn1Core is at the start of the structure, we can reuse the _Delete and _Enum APIs here. */ \
 
149
        /* .pszName = */        RT_XSTR(RTASN1TMPL_EXT_NAME), \
 
150
        /* .cb = */             sizeof(RTASN1TMPL_TYPE), \
 
151
        /* .uDefaultTag = */    a_uDefaultTag, \
 
152
        /* .fDefaultClass = */  a_fDefaultClass, \
 
153
        /* .uReserved = */      0, \
 
154
        (PFNRTASN1COREVTDTOR)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete), \
 
155
        (PFNRTASN1COREVTENUM)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Enum), \
 
156
        (PFNRTASN1COREVTCLONE)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Clone), \
 
157
        (PFNRTASN1COREVTCOMPARE)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Compare), \
 
158
        (PFNRTASN1COREVTCHECKSANITY)RT_CONCAT(RTASN1TMPL_EXT_NAME,_CheckSanity), \
 
159
        RTASN1TMPL_VTABLE_FN_ENCODE_PREP, \
 
160
        RTASN1TMPL_VTABLE_FN_ENCODE_WRITE \
 
161
    }
 
162
 
 
163
# define RTASN1TMPL_BEGIN_SEQCORE() \
 
164
    AssertCompileMemberOffset(RTASN1TMPL_TYPE, SeqCore, 0); \
 
165
    RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SEQUENCE, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
 
166
# define RTASN1TMPL_BEGIN_SETCORE() \
 
167
    AssertCompileMemberOffset(RTASN1TMPL_TYPE, SetCore, 0); \
 
168
    RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SET, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
 
169
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)                                 RTASN1TMPL_SEMICOLON_DUMMY()
 
170
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)                          RTASN1TMPL_SEMICOLON_DUMMY()
 
171
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                            RTASN1TMPL_SEMICOLON_DUMMY()
 
172
# define RTASN1TMPL_END_SEQCORE()                                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
173
# define RTASN1TMPL_END_SETCORE()                                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
174
 
 
175
# define RTASN1TMPL_BEGIN_PCHOICE() \
 
176
    AssertCompileMemberOffset(RTASN1TMPL_TYPE, Dummy, 0); \
 
177
    RTASN1TMPL_BEGIN_COMMON(UINT8_MAX, UINT8_MAX)
 
178
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
179
                                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
 
180
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
181
                                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
 
182
# define RTASN1TMPL_END_PCHOICE()                                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
183
 
 
184
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) \
 
185
    AssertCompileMemberOffset(RTASN1TMPL_TYPE, SeqCore, 0); \
 
186
    RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SEQUENCE, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
 
187
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) \
 
188
    AssertCompileMemberOffset(RTASN1TMPL_TYPE, SetCore, 0); \
 
189
    RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SET, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
 
190
 
 
191
 
 
192
 
 
193
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_INIT
 
194
/*
 
195
 *
 
196
 * Initialization to standard / default values.
 
197
 *
 
198
 */
 
199
# define RTASN1TMPL_BEGIN_COMMON() \
 
200
RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Init)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, PCRTASN1ALLOCATORVTABLE pAllocator) \
 
201
{ \
 
202
    RT_ZERO(*pThis)
 
203
# define RTASN1TMPL_END_COMMON() \
 
204
    return rc; \
 
205
} RTASN1TMPL_SEMICOLON_DUMMY()
 
206
 
 
207
# define RTASN1TMPL_BEGIN_SEQCORE() \
 
208
    RTASN1TMPL_BEGIN_COMMON(); \
 
209
    int rc = RTAsn1SequenceCore_Init(&pThis->SeqCore, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable))
 
210
# define RTASN1TMPL_BEGIN_SETCORE() \
 
211
    RTASN1TMPL_BEGIN_COMMON(); \
 
212
    int rc = RTAsn1SetCore_Init(&pThis->SetCore, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable))
 
213
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
214
    if (RT_SUCCESS(rc)) \
 
215
        rc = RT_CONCAT(a_Api,_Init)(&pThis->a_Name, pAllocator)
 
216
 
 
217
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
 
218
    RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
 
219
    pThis->a_enmMembNm = RT_CONCAT(a_enmType,_NOT_PRESENT)
 
220
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
221
                                                                                                    do { } while (0)
 
222
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                            do { } while (0)
 
223
 
 
224
# define RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_DefVal, a_Constraints) \
 
225
    if (RT_SUCCESS(rc)) \
 
226
    { \
 
227
        rc = RT_CONCAT(a_Api,_InitDefault)(&pThis->a_Name, a_DefVal, pAllocator); \
 
228
        if (RT_SUCCESS(rc)) \
 
229
            rc = RTAsn1Core_SetTagAndFlags(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), \
 
230
                                           a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)); \
 
231
    }
 
232
# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) do { } while (0) /* All optional members are left as not-present. */
 
233
# define RTASN1TMPL_END_SEQCORE() \
 
234
    if (RT_FAILURE(rc)) \
 
235
        RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
 
236
    RTASN1TMPL_END_COMMON()
 
237
# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_SEQCORE()
 
238
 
 
239
/* No choice, just an empty, non-present structure. */
 
240
# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_BEGIN_COMMON(); int rc = VINF_SUCCESS
 
241
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
242
                                                                                                    do { } while (0)
 
243
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
244
                                                                                                    do { } while (0)
 
245
# define RTASN1TMPL_END_PCHOICE()   RTASN1TMPL_END_COMMON()
 
246
 
 
247
 
 
248
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, a_OfApi, a_OfMember) \
 
249
    RTASN1TMPL_BEGIN_COMMON(); \
 
250
    RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
 
251
    int rc = RT_CONCAT(a_OfApi,_Init)(&pThis->a_OfMember, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)); \
 
252
    if (RT_FAILURE(rc)) \
 
253
        RT_ZERO(*pThis); \
 
254
    RTASN1TMPL_END_COMMON()
 
255
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SeqOfCore, SeqCore)
 
256
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SetOfCore, SetCore)
 
257
 
 
258
 
 
259
 
 
260
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_DECODE
 
261
/*
 
262
 *
 
263
 * Decode ASN.1.
 
264
 *
 
265
 */
 
266
# define RTASN1TMPL_BEGIN_COMMON() \
 
267
RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_DecodeAsn1)(PRTASN1CURSOR pCursor, uint32_t fFlags, \
 
268
                                                                RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, const char *pszErrorTag) \
 
269
{ \
 
270
    RT_ZERO(*pThis);
 
271
 
 
272
# define RTASN1TMPL_END_COMMON() \
 
273
    return rc; \
 
274
} RTASN1TMPL_SEMICOLON_DUMMY()
 
275
 
 
276
 
 
277
# define RTASN1TMPL_BEGIN_SEQCORE() \
 
278
    RTASN1TMPL_BEGIN_COMMON(); \
 
279
    RTASN1CURSOR ThisCursor; \
 
280
    int rc = RTAsn1CursorGetSequenceCursor(pCursor, fFlags, &pThis->SeqCore, &ThisCursor, pszErrorTag); \
 
281
    if (RT_FAILURE(rc)) \
 
282
        return rc; \
 
283
    pCursor = &ThisCursor; \
 
284
    pThis->SeqCore.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
 
285
# define RTASN1TMPL_BEGIN_SETCORE() \
 
286
    RTASN1TMPL_BEGIN_COMMON(); \
 
287
    RTASN1CURSOR ThisCursor; \
 
288
    int rc = RTAsn1CursorGetSetCursor(pCursor, fFlags, &pThis->SetCore, &ThisCursor, pszErrorTag); \
 
289
    if (RT_FAILURE(rc)) \
 
290
        return rc; \
 
291
    pCursor = &ThisCursor; \
 
292
    pThis->SetCore.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
 
293
 
 
294
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
295
    if (RT_SUCCESS(rc)) \
 
296
         rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, 0, &pThis->a_Name, #a_Name)
 
297
 
 
298
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
 
299
    if (RT_SUCCESS(rc)) \
 
300
    { \
 
301
        int rc2; /* not initialized! */ \
 
302
        RTAsn1CursorInitAllocation(pCursor, &pThis->a_Allocation); \
 
303
        pThis->a_enmMembNm = RT_CONCAT(a_enmType, _INVALID); \
 
304
        if (false) do { /*nothing*/ } while (0)
 
305
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
306
        else a_IfStmt \
 
307
        do { \
 
308
            rc2 = RTAsn1MemAllocZ(&pThis->a_Allocation, (void **)&pThis->a_UnionNm.a_PtrName, \
 
309
                                  sizeof(*pThis->a_UnionNm.a_PtrName)); \
 
310
            if (RT_SUCCESS(rc2)) \
 
311
            { \
 
312
                pThis->a_enmMembNm = a_enmValue; \
 
313
                rc2 = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, 0, pThis->a_UnionNm.a_PtrName, #a_UnionNm "." #a_PtrName); \
 
314
            } \
 
315
        } while (0)
 
316
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
 
317
        rc = rc2; /* Should trigger warning if a _DEFAULT is missing. */  \
 
318
    }
 
319
 
 
320
# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
321
    Error_Missing_Specific_Macro_In_Decode_Pass()
 
322
 
 
323
# define RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_DefVal, a_Constraints) \
 
324
    if (RT_SUCCESS(rc)) \
 
325
    { \
 
326
        if (RTAsn1CursorIsNextEx(pCursor, a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue))) \
 
327
            rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, 0, &pThis->a_Name, #a_Name); \
 
328
        else \
 
329
            rc = RT_CONCAT(a_Api,_InitDefault)(&pThis->a_Name, a_DefVal, pCursor->pPrimary->pAllocator); \
 
330
        if (RT_SUCCESS(rc)) \
 
331
            rc = RTAsn1Core_SetTagAndFlags(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), \
 
332
                                           a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)); \
 
333
    } do {} while (0)
 
334
 
 
335
# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, a_Constraints) \
 
336
    if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, ASN1_TAG_UTF8_STRING, ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_PRIMITIVE)) \
 
337
        rc = RTAsn1CursorGetUtf8String(pCursor, 0, &pThis->a_Name, #a_Name)
 
338
 
 
339
# define RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_Constraints) \
 
340
    if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)) /** @todo || CER */) \
 
341
        rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, RTASN1CURSOR_GET_F_IMPLICIT, &pThis->a_Name, #a_Name)
 
342
 
 
343
# define RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING(a_Name, a_cMaxBits, a_uTag) \
 
344
    if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, a_uTag, ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED)) \
 
345
        rc = RTAsn1CursorGetBitStringEx(pCursor, RTASN1CURSOR_GET_F_IMPLICIT, a_cMaxBits, &pThis->a_Name, #a_Name)
 
346
 
 
347
# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
 
348
    if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, a_uTag, ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED)) \
 
349
    { \
 
350
        RTASN1CURSOR CtxCursor; \
 
351
        rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, &pThis->a_TnNm.a_CtxTagN, &CtxCursor, #a_TnNm); \
 
352
        if (RT_SUCCESS(rc)) \
 
353
        { \
 
354
            rc = RT_CONCAT(a_Api,_DecodeAsn1)(&CtxCursor, 0, &pThis->a_TnNm.a_Name, #a_Name); \
 
355
            if (RT_SUCCESS(rc)) \
 
356
                rc = RTAsn1CursorCheckEnd(&CtxCursor); \
 
357
        } \
 
358
    } do { } while (0)
 
359
 
 
360
# define RTASN1TMPL_MEMBER_OPT_ANY(a_Name, a_Type, a_Api) \
 
361
    if (RT_SUCCESS(rc) && pCursor->cbLeft > 0) \
 
362
        RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, RT_NOTHING)
 
363
 
 
364
# define RTASN1TMPL_END_SEQCORE() \
 
365
   if (RT_SUCCESS(rc)) \
 
366
       rc = RTAsn1CursorCheckEnd(&ThisCursor); \
 
367
   if (RT_SUCCESS(rc)) \
 
368
       return VINF_SUCCESS; \
 
369
   RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
 
370
   RTASN1TMPL_END_COMMON()
 
371
# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_SEQCORE()
 
372
 
 
373
 
 
374
# define RTASN1TMPL_BEGIN_PCHOICE() \
 
375
    RTASN1TMPL_BEGIN_COMMON(); \
 
376
    RTAsn1Dummy_InitEx(&pThis->Dummy); \
 
377
    pThis->Dummy.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
 
378
    RTAsn1CursorInitAllocation(pCursor, &pThis->Allocation); \
 
379
    RTASN1CORE Asn1Peek; \
 
380
    int rc = RTAsn1CursorPeek(pCursor, &Asn1Peek); \
 
381
    if (RT_SUCCESS(rc)) \
 
382
    { \
 
383
        if (false) do {} while (0)
 
384
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
385
        else if (   Asn1Peek.uTag == (a_uTag) \
 
386
                 && (Asn1Peek.fClass == RTASN1TMPL_ITAG_F_EXPAND(a_fClue) /** @todo || CER */ ) ) \
 
387
        do { \
 
388
            pThis->enmChoice = a_enmChoice; \
 
389
            rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrName, sizeof(*pThis->a_PtrName)); \
 
390
            if (RT_SUCCESS(rc)) \
 
391
                rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, RTASN1CURSOR_GET_F_IMPLICIT, pThis->a_PtrName, #a_PtrName); \
 
392
        } while (0)
 
393
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
394
        else if (Asn1Peek.uTag == (a_uTag) && Asn1Peek.fClass == (ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED)) \
 
395
        do { \
 
396
            pThis->enmChoice = a_enmChoice; \
 
397
            rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrTnNm, sizeof(*pThis->a_PtrTnNm)); \
 
398
            if (RT_SUCCESS(rc)) \
 
399
            { \
 
400
                RTASN1CURSOR CtxCursor; \
 
401
                rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, &pThis->a_PtrTnNm->a_CtxTagN, \
 
402
                                                                         &CtxCursor, "T" #a_uTag); \
 
403
                if (RT_SUCCESS(rc)) \
 
404
                    rc = RT_CONCAT(a_Api,_DecodeAsn1)(&CtxCursor, RTASN1CURSOR_GET_F_IMPLICIT, \
 
405
                                                      &pThis->a_PtrTnNm->a_Name, #a_Name); \
 
406
                if (RT_SUCCESS(rc)) \
 
407
                    rc = RTAsn1CursorCheckEnd(&CtxCursor); \
 
408
            } \
 
409
        } while (0)
 
410
#define RTASN1TMPL_END_PCHOICE() \
 
411
        else \
 
412
            rc = RTAsn1CursorSetInfo(pCursor, VERR_GENERAL_FAILURE, "%s: Unknown choice: tag=%#x fClass=%#x", \
 
413
                                     pszErrorTag, Asn1Peek.uTag, Asn1Peek.fClass); \
 
414
        if (RT_SUCCESS(rc)) \
 
415
            return VINF_SUCCESS; \
 
416
    } \
 
417
    RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
 
418
    RTASN1TMPL_END_COMMON()
 
419
 
 
420
 
 
421
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, a_OfApi, a_OfMember, a_fnGetCursor) \
 
422
    RTASN1TMPL_BEGIN_COMMON(); \
 
423
    RTASN1CURSOR ThisCursor; \
 
424
    int rc = a_fnGetCursor(pCursor, fFlags, &pThis->a_OfMember, &ThisCursor, pszErrorTag); \
 
425
    if (RT_SUCCESS(rc)) \
 
426
    { \
 
427
        pCursor = &ThisCursor; \
 
428
        pThis->a_OfMember.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
 
429
        RTAsn1CursorInitAllocation(pCursor, &pThis->Allocation); \
 
430
        \
 
431
        uint32_t i = 0; \
 
432
        while (   pCursor->cbLeft > 0 \
 
433
               && RT_SUCCESS(rc)) \
 
434
        { \
 
435
            rc = RTAsn1MemGrowArray(&pThis->Allocation, \
 
436
                                    (void **)&pThis->paItems, \
 
437
                                    sizeof(pThis->paItems[0]), \
 
438
                                    i, \
 
439
                                    i + 1); \
 
440
            if (RT_SUCCESS(rc)) \
 
441
            { \
 
442
                rc = RT_CONCAT(a_ItemApi,_DecodeAsn1)(pCursor, 0, &pThis->paItems[i], "paItems[#]"); \
 
443
                if (RT_SUCCESS(rc)) \
 
444
                { \
 
445
                    i++; \
 
446
                    pThis->cItems = i; \
 
447
                    continue; \
 
448
                } \
 
449
            } \
 
450
            break; \
 
451
        } \
 
452
        if (RT_SUCCESS(rc)) \
 
453
        { \
 
454
            rc = RTAsn1CursorCheckEnd(pCursor); \
 
455
            if (RT_SUCCESS(rc)) \
 
456
                return VINF_SUCCESS; \
 
457
        } \
 
458
        RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
 
459
    } \
 
460
    RTASN1TMPL_END_COMMON()
 
461
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) \
 
462
    RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SeqOfCore, SeqCore, RTAsn1CursorGetSequenceCursor)
 
463
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) \
 
464
    RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SetOfCore, SetCore, RTAsn1CursorGetSetCursor)
 
465
 
 
466
 
 
467
# define RTASN1TMPL_EXEC_DECODE(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
 
468
 
 
469
 
 
470
 
 
471
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_ENUM
 
472
/*
 
473
 *
 
474
 * Enumeration.
 
475
 *
 
476
 */
 
477
# define RTASN1TMPL_BEGIN_COMMON() \
 
478
RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Enum)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
 
479
                                                          PFNRTASN1ENUMCALLBACK pfnCallback, \
 
480
                                                          uint32_t uDepth, void *pvUser) \
 
481
{ \
 
482
    if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis)) \
 
483
        return VINF_SUCCESS; \
 
484
    uDepth++; \
 
485
    int rc = VINF_SUCCESS
 
486
 
 
487
# define RTASN1TMPL_END_COMMON() \
 
488
    return rc; \
 
489
} RTASN1TMPL_SEMICOLON_DUMMY()
 
490
 
 
491
# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
 
492
# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
 
493
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
494
        if (rc == VINF_SUCCESS) \
 
495
            rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), #a_Name, uDepth, pvUser)
 
496
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
 
497
        if (rc == VINF_SUCCESS) \
 
498
            switch (pThis->a_enmMembNm) \
 
499
            { \
 
500
                default: rc = VERR_INTERNAL_ERROR_3; break
 
501
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
502
                case a_enmValue: \
 
503
                    rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_UnionNm.a_PtrName), #a_UnionNm "." #a_PtrName, \
 
504
                                     uDepth, pvUser); \
 
505
                    break
 
506
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
 
507
                case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
 
508
            }
 
509
# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
510
        if (rc == VINF_SUCCESS && RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name)) \
 
511
            rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), #a_Name, uDepth, pvUser)
 
512
# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
 
513
        if (rc == VINF_SUCCESS && RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core)) \
 
514
        { \
 
515
            rc = pfnCallback(&pThis->a_TnNm.a_CtxTagN.Asn1Core, #a_Name, uDepth, pvUser); \
 
516
            if (rc == VINF_SUCCESS) \
 
517
                rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_TnNm.a_Name), #a_TnNm "." #a_Name, uDepth, pvUser); \
 
518
        } do {} while (0)
 
519
# define RTASN1TMPL_END_SEQCORE()   RTASN1TMPL_END_COMMON()
 
520
# define RTASN1TMPL_END_SETCORE()   RTASN1TMPL_END_COMMON()
 
521
 
 
522
 
 
523
# define RTASN1TMPL_BEGIN_PCHOICE() \
 
524
    RTASN1TMPL_BEGIN_COMMON(); \
 
525
    switch (pThis->enmChoice) \
 
526
    { \
 
527
        default: rc = VERR_INTERNAL_ERROR_3; break
 
528
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
529
        case a_enmChoice: rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName), #a_PtrName, uDepth, pvUser); break
 
530
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
531
        case a_enmChoice: \
 
532
            rc = pfnCallback(&pThis->a_PtrTnNm->a_CtxTagN.Asn1Core, "T" #a_uTag "." #a_CtxTagN, uDepth, pvUser); \
 
533
            if (rc == VINF_SUCCESS) \
 
534
                rc = pfnCallback(RT_CONCAT(a_Api, _GetAsn1Core)(&pThis->a_PtrTnNm->a_Name), \
 
535
                                 "T" #a_uTag "." #a_Name, uDepth + 1, pvUser); \
 
536
            break
 
537
#define RTASN1TMPL_END_PCHOICE() \
 
538
    } \
 
539
    RTASN1TMPL_END_COMMON()
 
540
 
 
541
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
 
542
    RTASN1TMPL_BEGIN_COMMON(); \
 
543
    for (uint32_t i = 0; i < pThis->cItems && rc == VINF_SUCCESS; i++) \
 
544
        rc = pfnCallback(RT_CONCAT(a_ItemApi,_GetAsn1Core)(&pThis->paItems[i]), "paItems[#]", uDepth, pvUser); \
 
545
    RTASN1TMPL_END_COMMON()
 
546
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
547
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
548
 
 
549
 
 
550
 
 
551
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_CLONE
 
552
/*
 
553
 *
 
554
 * Clone another instance of the type.
 
555
 *
 
556
 */
 
557
# define RTASN1TMPL_BEGIN_COMMON() \
 
558
RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Clone)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
 
559
                                                           RT_CONCAT(PC,RTASN1TMPL_TYPE) pSrc, \
 
560
                                                           PCRTASN1ALLOCATORVTABLE pAllocator) \
 
561
{ \
 
562
    RT_ZERO(*pThis); \
 
563
    if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pSrc)) \
 
564
        return VINF_SUCCESS; \
 
565
 
 
566
# define RTASN1TMPL_END_COMMON() \
 
567
    return rc; \
 
568
} RTASN1TMPL_SEMICOLON_DUMMY()
 
569
 
 
570
# define RTASN1TMPL_BEGIN_SEQCORE() \
 
571
    RTASN1TMPL_BEGIN_COMMON(); \
 
572
    int rc = RTAsn1SequenceCore_Clone(&pThis->SeqCore, &RT_CONCAT3(g_, RTASN1TMPL_INT_NAME, _Vtable), &pSrc->SeqCore)
 
573
# define RTASN1TMPL_BEGIN_SETCORE() \
 
574
    RTASN1TMPL_BEGIN_COMMON(); \
 
575
    int rc = RTAsn1SetCore_Clone(&pThis->SetCore, &RT_CONCAT3(g_, RTASN1TMPL_INT_NAME, _Vtable), &pSrc->SetCore)
 
576
 
 
577
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
578
    if (RT_SUCCESS(rc)) \
 
579
        rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_Name, &pSrc->a_Name, pAllocator); \
 
580
 
 
581
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
 
582
    if (RT_SUCCESS(rc)) \
 
583
    { \
 
584
        RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
 
585
        pThis->a_enmMembNm = pSrc->a_enmMembNm; \
 
586
        switch (pSrc->a_enmMembNm) \
 
587
        { \
 
588
            default: rc = VERR_INTERNAL_ERROR_3; break
 
589
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
590
            case a_enmValue: \
 
591
                rc = RTAsn1MemAllocZ(&pThis->a_Allocation, (void **)&pThis->a_UnionNm.a_PtrName, \
 
592
                                      sizeof(*pThis->a_UnionNm.a_PtrName)); \
 
593
                if (RT_SUCCESS(rc)) \
 
594
                    rc = RT_CONCAT(a_Api,_Clone)(pThis->a_UnionNm.a_PtrName, pSrc->a_UnionNm.a_PtrName, pAllocator); \
 
595
                break
 
596
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
 
597
            case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
 
598
        } \
 
599
     }
 
600
 
 
601
/* Optional members and members with defaults are the same as a normal member when cloning. */
 
602
# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, a_Constraints) \
 
603
    RTASN1TMPL_MEMBER_OPT_EX(a_Name, RTASN1STRING, RTAsn1Utf8String, a_Constraints RT_NOTHING)
 
604
# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
 
605
    if (RTASN1CORE_IS_PRESENT(&pSrc->a_TnNm.a_CtxTagN.Asn1Core) && RT_SUCCESS(rc)) \
 
606
    { \
 
607
        rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Clone)(&pThis->a_TnNm.a_CtxTagN, &pSrc->a_TnNm.a_CtxTagN); \
 
608
        if (RT_SUCCESS(rc)) \
 
609
            rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_TnNm.a_Name, &pSrc->a_TnNm.a_Name, pAllocator); \
 
610
    } do { } while (0)
 
611
 
 
612
# define RTASN1TMPL_END_SEQCORE() \
 
613
    if (RT_FAILURE(rc)) \
 
614
        RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
 
615
    RTASN1TMPL_END_COMMON()
 
616
# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_SEQCORE()
 
617
 
 
618
 
 
619
# define RTASN1TMPL_BEGIN_PCHOICE() \
 
620
    RTASN1TMPL_BEGIN_COMMON(); \
 
621
    RTAsn1Dummy_InitEx(&pThis->Dummy); \
 
622
    RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
 
623
    int rc; \
 
624
    pThis->enmChoice = pSrc->enmChoice; \
 
625
    switch (pSrc->enmChoice) \
 
626
    { \
 
627
        default: rc = VERR_INTERNAL_ERROR_3; break
 
628
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
629
        case a_enmChoice: \
 
630
            rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrName, sizeof(*pThis->a_PtrName)); \
 
631
            if (RT_SUCCESS(rc)) \
 
632
                rc = RT_CONCAT(a_Api,_Clone)(pThis->a_PtrName, pSrc->a_PtrName, pAllocator); break
 
633
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
634
        case a_enmChoice: /* A bit of presence paranoia here, but better safe than sorry... */ \
 
635
            rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrTnNm, sizeof(*pThis->a_PtrTnNm)); \
 
636
            if (RT_SUCCESS(rc) && RTASN1CORE_IS_PRESENT(&pSrc->a_PtrTnNm->a_CtxTagN.Asn1Core)) \
 
637
            { \
 
638
                RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Clone)(&pThis->a_PtrTnNm->a_CtxTagN, &pSrc->a_PtrTnNm->a_CtxTagN); \
 
639
                rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_PtrTnNm->a_Name, &pSrc->a_PtrTnNm->a_Name, pAllocator); \
 
640
            } \
 
641
            break
 
642
#define RTASN1TMPL_END_PCHOICE() \
 
643
    } \
 
644
    if (RT_FAILURE(rc)) \
 
645
        RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
 
646
    RTASN1TMPL_END_COMMON()
 
647
 
 
648
 
 
649
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, a_OfApi, a_OfMember) \
 
650
    RTASN1TMPL_BEGIN_COMMON(); \
 
651
    int rc = RT_CONCAT(a_OfApi,_Clone)(&pThis->a_OfMember, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable), &pSrc->a_OfMember); \
 
652
    if (RT_SUCCESS(rc)) \
 
653
    { \
 
654
        RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
 
655
        uint32_t const cItems = pSrc->cItems; \
 
656
        if (cItems > 0) \
 
657
        { \
 
658
            rc = RTAsn1MemGrowArray(&pThis->Allocation, (void **)&pThis->paItems, sizeof(pThis->paItems[0]), 0, cItems); \
 
659
            if (RT_SUCCESS(rc)) \
 
660
            { \
 
661
                uint32_t i = 0; \
 
662
                while (i < cItems) \
 
663
                { \
 
664
                    rc = RT_CONCAT(a_ItemApi,_Clone)(&pThis->paItems[i], &pSrc->paItems[i], pAllocator); \
 
665
                    if (RT_SUCCESS(rc)) \
 
666
                        pThis->cItems = ++i; \
 
667
                    else \
 
668
                    { \
 
669
                        pThis->cItems = i; \
 
670
                        RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
 
671
                        return rc; \
 
672
                    } \
 
673
                } \
 
674
            } \
 
675
            else \
 
676
                RT_ZERO(*pThis); \
 
677
        } \
 
678
    } \
 
679
    RTASN1TMPL_END_COMMON()
 
680
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SeqOfCore, SeqCore)
 
681
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SetOfCore, SetCore)
 
682
 
 
683
# define RTASN1TMPL_EXEC_CLONE(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
 
684
 
 
685
 
 
686
 
 
687
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_SETTERS_1
 
688
/*
 
689
 *
 
690
 * Member setter helpers.
 
691
 *
 
692
 */
 
693
# define RTASN1TMPL_BEGIN_SEQCORE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
 
694
# define RTASN1TMPL_BEGIN_SETCORE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
 
695
#if 1 /** @todo later */
 
696
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)                     RTASN1TMPL_SEMICOLON_DUMMY()
 
697
#else
 
698
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
699
    RTDECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RTASN1TMPL_TYPE *pThis, a_Type const *pValue, \
 
700
                                                            PCRTASN1ALLOCATORVTABLE pAllocator) \
 
701
    { \
 
702
        if (RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name)) \
 
703
            RT_CONCAT(a_Api,_Delete)(&pThis->a_Name); \
 
704
        return RT_CONCAT(a_Api,_Clone)(&pThis->a_Name, pValue, pAllocator, true /* fResetImplicit */); \
 
705
    } RTASN1TMPL_SEMICOLON_DUMMY()
 
706
#endif
 
707
 
 
708
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)              RTASN1TMPL_SEMICOLON_DUMMY()
 
709
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                RTASN1TMPL_SEMICOLON_DUMMY()
 
710
# define RTASN1TMPL_END_SEQCORE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
711
# define RTASN1TMPL_END_SETCORE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
712
 
 
713
 
 
714
# define RTASN1TMPL_BEGIN_PCHOICE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
 
715
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints)   RTASN1TMPL_SEMICOLON_DUMMY()
 
716
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
 
717
# define RTASN1TMPL_END_PCHOICE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
718
 
 
719
 
 
720
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SEMICOLON_DUMMY()
 
721
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SEMICOLON_DUMMY()
 
722
 
 
723
 
 
724
 
 
725
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_SETTERS_2
 
726
/*
 
727
 *
 
728
 * Member setters.
 
729
 *
 
730
 */
 
731
# define RTASN1TMPL_BEGIN_SEQCORE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
 
732
# define RTASN1TMPL_BEGIN_SETCORE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
 
733
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)                     RTASN1TMPL_SEMICOLON_DUMMY()
 
734
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)              RTASN1TMPL_SEMICOLON_DUMMY()
 
735
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                RTASN1TMPL_SEMICOLON_DUMMY()
 
736
# define RTASN1TMPL_END_SEQCORE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
737
# define RTASN1TMPL_END_SETCORE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
 
738
 
 
739
 
 
740
# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
 
741
 
 
742
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
743
RTASN1TMPL_DECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, RT_CONCAT(PC,a_Type) pSrc,\
 
744
                                                                 PCRTASN1ALLOCATORVTABLE pAllocator) \
 
745
{ \
 
746
    AssertPtr(pSrc); AssertPtr(pThis); \
 
747
    RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); /* See _Init. */ \
 
748
    RTAsn1Dummy_InitEx(&pThis->Dummy); \
 
749
    RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
 
750
    pThis->enmChoice = a_enmChoice; \
 
751
    int rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrName, sizeof(*pThis->a_PtrName)); \
 
752
    if (RT_SUCCESS(rc)) \
 
753
    { \
 
754
        rc = RT_CONCAT(a_Api,_Clone)(pThis->a_PtrName, pSrc, pAllocator); \
 
755
        if (RT_SUCCESS(rc)) \
 
756
        { \
 
757
            RTAsn1Core_ResetImplict(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName)); \
 
758
            rc = RTAsn1Core_SetTagAndFlags(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName), \
 
759
                                           a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)); \
 
760
        } \
 
761
    } \
 
762
    return rc; \
 
763
} RTASN1TMPL_SEMICOLON_DUMMY()
 
764
 
 
765
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
766
RTASN1TMPL_DECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, RT_CONCAT(PC,a_Type) pSrc,\
 
767
                                                                 PCRTASN1ALLOCATORVTABLE pAllocator) \
 
768
{ \
 
769
    AssertPtr(pThis); AssertPtr(pSrc); Assert(RT_CONCAT(a_Api,_IsPresent)(pSrc)); \
 
770
    RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); /* See _Init. */ \
 
771
    RTAsn1Dummy_InitEx(&pThis->Dummy); \
 
772
    RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
 
773
    pThis->enmChoice = a_enmChoice; \
 
774
    int rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrTnNm, sizeof(*pThis->a_PtrTnNm)); \
 
775
    if (RT_SUCCESS(rc)) \
 
776
    { \
 
777
        rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Init)(&pThis->a_PtrTnNm->a_CtxTagN, pAllocator); \
 
778
        if (RT_SUCCESS(rc)) \
 
779
        { \
 
780
            rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_PtrTnNm->a_Name, pSrc, pAllocator); \
 
781
            if (RT_SUCCESS(rc)) \
 
782
                RTAsn1Core_ResetImplict(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_PtrTnNm->a_Name)); \
 
783
        } \
 
784
    } \
 
785
    return rc; \
 
786
} RTASN1TMPL_SEMICOLON_DUMMY()
 
787
 
 
788
#define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
 
789
 
 
790
 
 
791
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SEMICOLON_DUMMY()
 
792
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SEMICOLON_DUMMY()
 
793
 
 
794
 
 
795
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_COMPARE
 
796
/*
 
797
 *
 
798
 * Compare two instances of the type.
 
799
 *
 
800
 */
 
801
# define RTASN1TMPL_BEGIN_COMMON() \
 
802
RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Compare)(RT_CONCAT(PC,RTASN1TMPL_TYPE) pLeft, \
 
803
                                                             RT_CONCAT(PC,RTASN1TMPL_TYPE) pRight) \
 
804
{ \
 
805
    if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pLeft)) \
 
806
        return 0 - (int)RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pRight); \
 
807
    if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pRight)) \
 
808
        return -1; \
 
809
    int iDiff = 0
 
810
 
 
811
# define RTASN1TMPL_END_COMMON() \
 
812
    return iDiff; \
 
813
} RTASN1TMPL_SEMICOLON_DUMMY()
 
814
 
 
815
# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
 
816
# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
 
817
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
818
    if (!iDiff) \
 
819
        iDiff = RT_CONCAT(a_Api,_Compare)(&pLeft->a_Name, &pRight->a_Name)
 
820
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
 
821
    if (!iDiff && pLeft->a_enmMembNm != pRight->a_enmMembNm) \
 
822
        iDiff = pLeft->a_enmMembNm < pRight->a_enmMembNm ? -1 : 1; \
 
823
    else if (!iDiff) \
 
824
        switch (pLeft->a_enmMembNm) \
 
825
        { \
 
826
            default: break
 
827
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
828
            case a_enmValue: iDiff = RT_CONCAT(a_Api,_Compare)(pLeft->a_UnionNm.a_PtrName, pRight->a_UnionNm.a_PtrName); break
 
829
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
 
830
            case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
 
831
        }
 
832
# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
 
833
    if (!iDiff) \
 
834
    { \
 
835
        if (RTASN1CORE_IS_PRESENT(&pLeft->a_TnNm.a_CtxTagN.Asn1Core)) \
 
836
        { \
 
837
            if (RTASN1CORE_IS_PRESENT(&pRight->a_TnNm.a_CtxTagN.Asn1Core)) \
 
838
                iDiff = RT_CONCAT(a_Api,_Compare)(&pLeft->a_TnNm.a_Name, &pRight->a_TnNm.a_Name); \
 
839
            else \
 
840
                iDiff = -1; \
 
841
        } \
 
842
        else \
 
843
            iDiff = 0 - (int)RTASN1CORE_IS_PRESENT(&pRight->a_TnNm.a_CtxTagN.Asn1Core); \
 
844
    } do { } while (0)
 
845
# define RTASN1TMPL_END_SEQCORE()   RTASN1TMPL_END_COMMON()
 
846
# define RTASN1TMPL_END_SETCORE()   RTASN1TMPL_END_COMMON()
 
847
 
 
848
# define RTASN1TMPL_BEGIN_PCHOICE() \
 
849
    RTASN1TMPL_BEGIN_COMMON(); \
 
850
    if (pLeft->enmChoice != pRight->enmChoice) \
 
851
        return pLeft->enmChoice < pRight->enmChoice ? -1 : 1; \
 
852
    switch (pLeft->enmChoice) \
 
853
    { \
 
854
        default: break
 
855
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
856
        case a_enmChoice: iDiff = RT_CONCAT(a_Api,_Compare)(pLeft->a_PtrName, pRight->a_PtrName); break
 
857
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
858
        case a_enmChoice: iDiff = RT_CONCAT(a_Api,_Compare)(&pLeft->a_PtrTnNm->a_Name, &pRight->a_PtrTnNm->a_Name); break
 
859
#define RTASN1TMPL_END_PCHOICE() \
 
860
    } \
 
861
    RTASN1TMPL_END_COMMON()
 
862
 
 
863
 
 
864
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
 
865
    RTASN1TMPL_BEGIN_COMMON(); \
 
866
    uint32_t cItems = pLeft->cItems; \
 
867
    if (cItems == pRight->cItems) \
 
868
        for (uint32_t i = 0; iDiff == 0 && i < cItems; i++) \
 
869
            iDiff = RT_CONCAT(a_ItemApi,_Compare)(&pLeft->paItems[i], &pRight->paItems[i]); \
 
870
    else \
 
871
        iDiff = cItems < pRight->cItems ? -1 : 1; \
 
872
    RTASN1TMPL_END_COMMON()
 
873
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
874
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
875
 
 
876
 
 
877
 
 
878
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_CHECK_SANITY
 
879
/*
 
880
 *
 
881
 * Checks the sanity of the type.
 
882
 *
 
883
 */
 
884
# ifndef RTASN1TMPL_SANITY_CHECK_EXPR
 
885
#  define RTASN1TMPL_SANITY_CHECK_EXPR() VINF_SUCCESS
 
886
# endif
 
887
# define RTASN1TMPL_BEGIN_COMMON() \
 
888
RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_CheckSanity)(RT_CONCAT(PC,RTASN1TMPL_TYPE) pThis, uint32_t fFlags,  \
 
889
                                                                 PRTERRINFO pErrInfo, const char *pszErrorTag) \
 
890
{ \
 
891
    if (RT_UNLIKELY(!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis))) \
 
892
        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s: Missing (%s).", pszErrorTag, RT_XSTR(RTASN1TMPL_TYPE)); \
 
893
    int rc = VINF_SUCCESS
 
894
 
 
895
# define RTASN1TMPL_END_COMMON() \
 
896
    if (RT_SUCCESS(rc)) \
 
897
        rc = (RTASN1TMPL_SANITY_CHECK_EXPR()); \
 
898
    return rc; \
 
899
} RTASN1TMPL_SEMICOLON_DUMMY()
 
900
 
 
901
# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
 
902
# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
 
903
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
904
    if (RT_SUCCESS(rc)) \
 
905
    { \
 
906
        if (RT_LIKELY(RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name))) \
 
907
        { \
 
908
            rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
 
909
                                               pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
 
910
            { a_Constraints } \
 
911
        } \
 
912
        else \
 
913
            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s: Missing member %s (%s).", \
 
914
                               pszErrorTag, #a_Name, RT_XSTR(RTASN1TMPL_TYPE)); \
 
915
    } do {} while (0)
 
916
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
 
917
    if (RT_SUCCESS(rc)) \
 
918
        switch (pThis->a_enmMembNm) \
 
919
        { \
 
920
            default: \
 
921
                rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
922
                                   "%s: Invalid " #a_enmMembNm " value: %d", pszErrorTag, pThis->a_enmMembNm); \
 
923
                break
 
924
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
925
            case a_enmValue: \
 
926
                rc = RT_CONCAT(a_Api,_CheckSanity)(pThis->a_UnionNm.a_PtrName, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
 
927
                                                   pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_UnionNm "." #a_PtrName); \
 
928
                break
 
929
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
 
930
            case RT_CONCAT(a_enmType,_NOT_PRESENT): \
 
931
                rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
932
                                   "%s: Invalid " #a_enmMembNm " value: " #a_enmType "_NOT_PRESENT", \
 
933
                                   pszErrorTag, pThis->a_enmMembNm); \
 
934
                break; \
 
935
        }
 
936
# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
937
    if (RT_SUCCESS(rc) && RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name)) \
 
938
    { \
 
939
        rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
 
940
                                           pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
 
941
        { a_Constraints } \
 
942
    }
 
943
# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
 
944
    if (RT_SUCCESS(rc)) \
 
945
    { \
 
946
        bool const fOuterPresent = RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core); \
 
947
        bool const fInnerPresent = RT_CONCAT(a_Api,_IsPresent)(&pThis->a_TnNm.a_Name); \
 
948
        if (fOuterPresent && fInnerPresent) \
 
949
        { \
 
950
            rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_TnNm.a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
 
951
                                               pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
 
952
            { a_Constraints } \
 
953
        } \
 
954
        else if (RT_UNLIKELY(RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core) != fInnerPresent)) \
 
955
            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
956
                               "%s::" #a_TnNm "." #a_Name ": Explict tag precense mixup; " #a_CtxTagN "=%d " #a_Name "=%d.", \
 
957
                               pszErrorTag, fOuterPresent, fInnerPresent); \
 
958
    } do { } while (0)
 
959
# define RTASN1TMPL_END_SEQCORE()   RTASN1TMPL_END_COMMON()
 
960
# define RTASN1TMPL_END_SETCORE()   RTASN1TMPL_END_COMMON()
 
961
 
 
962
 
 
963
# define RTASN1TMPL_BEGIN_PCHOICE() \
 
964
    RTASN1TMPL_BEGIN_COMMON(); \
 
965
    switch (pThis->enmChoice) \
 
966
    { \
 
967
        default: \
 
968
            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
969
                               "%s: Invalid enmChoice value: %d", pszErrorTag, pThis->enmChoice); \
 
970
            break
 
971
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
972
        case a_enmChoice: \
 
973
            if (pThis->a_PtrName && RT_CONCAT(a_Api,_IsPresent)(pThis->a_PtrName)) \
 
974
            { \
 
975
                PCRTASN1CORE pCore = RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName); \
 
976
                if (pCore->uTag == a_uTag && pCore->fClass == RTASN1TMPL_ITAG_F_EXPAND(a_fClue)) \
 
977
                { \
 
978
                    rc = RT_CONCAT(a_Api,_CheckSanity)(pThis->a_PtrName, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
 
979
                                                       pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
 
980
                    { a_Constraints } \
 
981
                } \
 
982
                else \
 
983
                    rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
984
                                       "%s::" #a_Name ": Tag/class mismatch: expected %#x/%#x, actual %#x/%x.", \
 
985
                                       pszErrorTag, a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue), pCore->uTag, pCore->fClass); \
 
986
            } \
 
987
            else \
 
988
                rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Not present.", pszErrorTag); \
 
989
            break
 
990
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
991
        case a_enmChoice: \
 
992
            if (   pThis->a_PtrTnNm \
 
993
                && RTASN1CORE_IS_PRESENT(&(pThis->a_PtrTnNm->a_CtxTagN.Asn1Core)) \
 
994
                && RT_CONCAT(a_Api,_IsPresent)(&pThis->a_PtrTnNm->a_Name) ) \
 
995
            { \
 
996
                rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_PtrTnNm->a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
 
997
                                                   pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
 
998
                { a_Constraints } \
 
999
            } \
 
1000
            else \
 
1001
                rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Not present.", pszErrorTag); \
 
1002
            break
 
1003
#define RTASN1TMPL_END_PCHOICE() \
 
1004
    } \
 
1005
    RTASN1TMPL_END_COMMON()
 
1006
 
 
1007
 
 
1008
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
 
1009
    RTASN1TMPL_BEGIN_COMMON(); \
 
1010
    for (uint32_t i = 0; RT_SUCCESS(rc) && i < pThis->cItems; i++) \
 
1011
        rc = RT_CONCAT(a_ItemApi,_CheckSanity)(&pThis->paItems[i], fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
 
1012
                                               pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::paItems[#]"); \
 
1013
    if (RT_SUCCESS(rc)) { RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY(); } \
 
1014
    RTASN1TMPL_END_COMMON()
 
1015
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
1016
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
1017
 
 
1018
/* The constraints. */
 
1019
# define RTASN1TMPL_MEMBER_CONSTR_MIN_MAX(a_Name, a_Type, a_Api, cbMin, cbMax, a_MoreConstraints) \
 
1020
    if (RT_SUCCESS(rc) && ((cbMin) != 0 || (cbMax) != UINT32_MAX)) \
 
1021
    { \
 
1022
        PCRTASN1CORE pCore = RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name); \
 
1023
        if (RT_UNLIKELY(pCore->cb < (cbMin) || pCore->cb > (cbMax))) \
 
1024
            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
1025
                               "%s::" #a_Name ": Content size is out of range: %#x not in {%#x..%#x}", \
 
1026
                               pszErrorTag, pCore->cb, cbMin, cbMax); \
 
1027
    } \
 
1028
    { a_MoreConstraints }
 
1029
 
 
1030
# define RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, cMinBits, cMaxBits, a_MoreConstraints) \
 
1031
    if (RT_SUCCESS(rc) && ((cMinBits) != 0 || (cMaxBits) != UINT32_MAX)) \
 
1032
    { \
 
1033
        if (RT_UNLIKELY(   ((cMinBits) == 0          ? false : pThis->a_Name.cBits + 1U < (cMinBits) + 1U /* warning avoiding */) \
 
1034
                        || ((cMaxBits) == UINT32_MAX ? false : pThis->a_Name.cBits + 1U > (cMaxBits) + 1U /* ditto */) ) ) \
 
1035
            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
1036
                               "%s::" #a_Name ": Bit size is out of range: %#x not in {%#x..%#x}", \
 
1037
                               pszErrorTag, pThis->a_Name.cBits, cMinBits, cMaxBits); \
 
1038
    } \
 
1039
    { a_MoreConstraints }
 
1040
 
 
1041
# define RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX(a_Name, uMin, uMax, a_MoreConstraints) \
 
1042
    if (RT_SUCCESS(rc)) \
 
1043
    { \
 
1044
        if (RT_UNLIKELY(   RTAsn1Integer_UnsignedCompareWithU64(&pThis->a_Name, uMin) < 0 \
 
1045
                        || RTAsn1Integer_UnsignedCompareWithU64(&pThis->a_Name, uMax) > 0) ) \
 
1046
            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
 
1047
                               "%s::" #a_Name ": Out of range: %#x not in {%#llx..%#llx}", \
 
1048
                               pszErrorTag, pThis->a_Name.Asn1Core.cb > 8 ? UINT64_MAX : pThis->a_Name.uValue.u, \
 
1049
                               (uint64_t)(uMin), (uint64_t)(uMax)); \
 
1050
    } \
 
1051
    { a_MoreConstraints }
 
1052
 
 
1053
# define RTASN1TMPL_MEMBER_CONSTR_PRESENT(a_Name, a_Api, a_MoreConstraints) \
 
1054
    if (RT_SUCCESS(rc) && RT_UNLIKELY(!RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name))) \
 
1055
        rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Missing.", pszErrorTag); \
 
1056
    { a_MoreConstraints }
 
1057
 
 
1058
 
 
1059
 
 
1060
# define RTASN1TMPL_EXEC_CHECK_SANITY(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
 
1061
 
 
1062
 
 
1063
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_DELETE
 
1064
/*
 
1065
 *
 
1066
 * Delete wrappers.
 
1067
 *
 
1068
 */
 
1069
# define RTASN1TMPL_BEGIN_COMMON() \
 
1070
RTASN1TMPL_DECL(void) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis) \
 
1071
{ \
 
1072
    if (RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis)) \
 
1073
    {   do { } while (0)
 
1074
 
 
1075
# define RTASN1TMPL_END_COMMON() \
 
1076
    } \
 
1077
    RT_ZERO(*pThis); \
 
1078
} RTASN1TMPL_SEMICOLON_DUMMY()
 
1079
 
 
1080
# define RTASN1TMPL_BEGIN_SEQCORE()                                 RTASN1TMPL_BEGIN_COMMON()
 
1081
# define RTASN1TMPL_BEGIN_SETCORE()                                 RTASN1TMPL_BEGIN_COMMON()
 
1082
# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)     RT_CONCAT(a_Api,_Delete)(&pThis->a_Name)
 
1083
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
 
1084
    switch (pThis->a_enmMembNm) \
 
1085
    { \
 
1086
        default: break
 
1087
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
1088
        case a_enmValue: \
 
1089
            if (pThis->a_UnionNm.a_PtrName) \
 
1090
            { \
 
1091
                RT_CONCAT(a_Api,_Delete)(pThis->a_UnionNm.a_PtrName); \
 
1092
                RTAsn1MemFree(&pThis->Allocation, pThis->a_UnionNm.a_PtrName); \
 
1093
                pThis->a_UnionNm.a_PtrName = NULL; \
 
1094
            } \
 
1095
            break
 
1096
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
 
1097
    }
 
1098
# define RTASN1TMPL_END_SEQCORE()                                   RTASN1TMPL_END_COMMON()
 
1099
# define RTASN1TMPL_END_SETCORE()                                   RTASN1TMPL_END_COMMON()
 
1100
 
 
1101
 
 
1102
# define RTASN1TMPL_BEGIN_PCHOICE() \
 
1103
    RTASN1TMPL_BEGIN_COMMON(); \
 
1104
    switch (pThis->enmChoice) \
 
1105
    { \
 
1106
        default: break
 
1107
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
 
1108
        case a_enmChoice: \
 
1109
            if (pThis->a_PtrName) \
 
1110
            { \
 
1111
                RT_CONCAT(a_Api,_Delete)(pThis->a_PtrName); \
 
1112
                RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrName); \
 
1113
                pThis->a_PtrName = NULL; \
 
1114
            } \
 
1115
            break
 
1116
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
 
1117
        case a_enmChoice: \
 
1118
            if (pThis->a_PtrTnNm) \
 
1119
            { \
 
1120
                RT_CONCAT(a_Api,_Delete)(&pThis->a_PtrTnNm->a_Name); \
 
1121
                RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrTnNm); \
 
1122
                pThis->a_PtrTnNm = NULL; \
 
1123
            } \
 
1124
            break
 
1125
# define RTASN1TMPL_END_PCHOICE() \
 
1126
    } \
 
1127
    RTASN1TMPL_END_COMMON()
 
1128
 
 
1129
 
 
1130
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
 
1131
    RTASN1TMPL_BEGIN_COMMON(); \
 
1132
    uint32_t i = pThis->cItems; \
 
1133
    while (i-- > 0) \
 
1134
        RT_CONCAT(a_ItemApi,_Delete)(&pThis->paItems[i]); \
 
1135
    RTAsn1MemFree(&pThis->Allocation, pThis->paItems); \
 
1136
    pThis->paItems = NULL; \
 
1137
    RTASN1TMPL_END_COMMON()
 
1138
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
1139
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
1140
 
 
1141
 
 
1142
#else
 
1143
# error "Invalid/missing RTASN1TMPL_PASS value."
 
1144
#endif
 
1145
 
 
1146
 
 
1147
 
 
1148
/*
 
1149
 * Default aliases for simplified versions of macros if no specialization
 
1150
 * was required above.
 
1151
 */
 
1152
/* Non-optional members. */
 
1153
#ifndef RTASN1TMPL_MEMBER
 
1154
# define RTASN1TMPL_MEMBER(a_Name, a_Type, a_Api) \
 
1155
    RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, RT_NOTHING)
 
1156
#endif
 
1157
 
 
1158
#ifndef RTASN1TMPL_MEMBER_UTF8_STRING_MIN_MAX
 
1159
# define RTASN1TMPL_MEMBER_UTF8_STRING_MIN_MAX(a_Name) \
 
1160
    RTASN1TMPL_MEMBER(a_Name, RTASN1STRING, RTAsn1String)
 
1161
#endif
 
1162
#ifndef RTASN1TMPL_MEMBER_UTF8_STRING
 
1163
# define RTASN1TMPL_MEMBER_UTF8_STRING(a_Name) \
 
1164
    RTASN1TMPL_MEMBER_UTF8_STRING_MIN_MAX(a_Name, 0, UINT32_MAX)
 
1165
#endif
 
1166
 
 
1167
#ifndef RTASN1TMPL_MEMBER_STRING_MIN_MAX
 
1168
# define RTASN1TMPL_MEMBER_STRING_MIN_MAX(a_Name, a_cbMin, a_cbMax) \
 
1169
    RTASN1TMPL_MEMBER(a_Name, RTASN1STRING, RTAsn1String)
 
1170
#endif
 
1171
#ifndef RTASN1TMPL_MEMBER_STRING
 
1172
# define RTASN1TMPL_MEMBER_STRING(a_Name) \
 
1173
    RTASN1TMPL_MEMBER_STRING_MIN_MAX(a_Name, 0, UINT32_MAX)
 
1174
#endif
 
1175
#ifndef RTASN1TMPL_MEMBER_XTAG_EX
 
1176
# define RTASN1TMPL_MEMBER_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
 
1177
    RTASN1TMPL_MEMBER_EX(a_TnNm.a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
 
1178
#endif
 
1179
 
 
1180
/* Any/dynamic members.  */
 
1181
#ifndef RTASN1TMPL_MEMBER_DYN_BEGIN
 
1182
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)   do { } while (0)
 
1183
#endif
 
1184
#ifndef RTASN1TMPL_MEMBER_DYN_END
 
1185
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)     do { } while (0)
 
1186
#endif
 
1187
#ifndef RTASN1TMPL_MEMBER_DYN_COMMON
 
1188
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
 
1189
    RTASN1TMPL_MEMBER(a_UnionNm.a_PtrName, a_Type, a_Api)
 
1190
#endif
 
1191
#ifndef RTASN1TMPL_MEMBER_DYN
 
1192
# define RTASN1TMPL_MEMBER_DYN(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_WhenExpr) \
 
1193
    RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, if (a_WhenExpr))
 
1194
#endif
 
1195
#ifndef RTASN1TMPL_MEMBER_DYN_DEFAULT
 
1196
# define RTASN1TMPL_MEMBER_DYN_DEFAULT(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue) \
 
1197
    RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, RT_NOTHING)
 
1198
#endif
 
1199
 
 
1200
/* Optional members. */
 
1201
#ifndef RTASN1TMPL_MEMBER_OPT_EX
 
1202
# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
 
1203
    RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
 
1204
#endif
 
1205
#ifndef RTASN1TMPL_MEMBER_OPT
 
1206
# define RTASN1TMPL_MEMBER_OPT(a_Name, a_Type, a_Api) \
 
1207
    RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, RT_NOTHING)
 
1208
#endif
 
1209
 
 
1210
#ifndef RTASN1TMPL_MEMBER_OPT_XTAG_EX
 
1211
# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
 
1212
    RTASN1TMPL_MEMBER_OPT_EX(a_TnNm.a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
 
1213
#endif
 
1214
#ifndef RTASN1TMPL_MEMBER_OPT_XTAG
 
1215
# define RTASN1TMPL_MEMBER_OPT_XTAG(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag) \
 
1216
    RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, RT_NOTHING)
 
1217
#endif
 
1218
 
 
1219
#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_EX
 
1220
# define RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_Constraints) \
 
1221
    RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
 
1222
#endif
 
1223
#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_UP
 
1224
# define RTASN1TMPL_MEMBER_OPT_ITAG_UP(a_Name, a_Type, a_Api, a_uTag) \
 
1225
    RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_UP, RT_NOTHING)
 
1226
#endif
 
1227
#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_UC
 
1228
# define RTASN1TMPL_MEMBER_OPT_ITAG_UC(a_Name, a_Type, a_Api, a_uTag) \
 
1229
    RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_UC, RT_NOTHING)
 
1230
#endif
 
1231
#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_CP
 
1232
# define RTASN1TMPL_MEMBER_OPT_ITAG_CP(a_Name, a_Type, a_Api, a_uTag) \
 
1233
    RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_CP, RT_NOTHING)
 
1234
#endif
 
1235
#ifndef RTASN1TMPL_MEMBER_OPT_ITAG
 
1236
# define RTASN1TMPL_MEMBER_OPT_ITAG(a_Name, a_Type, a_Api, a_uTag) \
 
1237
    RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_CC, RT_NOTHING)
 
1238
#endif
 
1239
#ifndef RTASN1TMPL_MEMBER_OPT_ANY
 
1240
# define RTASN1TMPL_MEMBER_OPT_ANY(a_Name, a_Type, a_Api) \
 
1241
    RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, RT_NOTHING)
 
1242
#endif
 
1243
 
 
1244
#ifndef RTASN1TMPL_MEMBER_DEF_ITAG_EX
 
1245
# define RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_DefVal, a_Constraints) \
 
1246
    RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_Constraints RT_NOTHING)
 
1247
#endif
 
1248
#ifndef RTASN1TMPL_MEMBER_DEF_ITAG_UP
 
1249
# define RTASN1TMPL_MEMBER_DEF_ITAG_UP(a_Name, a_Type, a_Api, a_uTag, a_DefVal) \
 
1250
    RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_UP, a_DefVal, RT_NOTHING)
 
1251
#endif
 
1252
 
 
1253
#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING
 
1254
# define RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING(a_Name, a_cMaxBits, a_uTag) \
 
1255
    RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, RTASN1BITSTRING, RTAsn1BitString, a_uTag, RTASN1TMPL_ITAG_F_CP, \
 
1256
                                  RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, 0, a_cMaxBits, RT_NOTHING))
 
1257
#endif
 
1258
 
 
1259
#ifndef RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX
 
1260
# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, a_Constraints) \
 
1261
    RTASN1TMPL_MEMBER_OPT_EX(a_Name, RTASN1STRING, RTAsn1String, a_Constraints RT_NOTHING)
 
1262
#endif
 
1263
#ifndef RTASN1TMPL_MEMBER_OPT_UTF8_STRING
 
1264
# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING(a_Name) \
 
1265
    RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, RT_NOTHING)
 
1266
#endif
 
1267
 
 
1268
#ifndef RTASN1TMPL_MEMBER_OPT_STRING_EX
 
1269
# define RTASN1TMPL_MEMBER_OPT_STRING_EX(a_Name, a_Constraints) \
 
1270
    RTASN1TMPL_MEMBER_OPT_EX(a_Name, RTASN1STRING, RTAsn1String, a_Constraints RT_NOTHING)
 
1271
#endif
 
1272
#ifndef RTASN1TMPL_MEMBER_OPT_STRING
 
1273
# define RTASN1TMPL_MEMBER_OPT_STRING(a_Name) \
 
1274
    RTASN1TMPL_MEMBER_OPT_STRING_EX(a_Name, RT_NOTHING)
 
1275
#endif
 
1276
 
 
1277
/* Pointer choices. */
 
1278
#ifndef RTASN1TMPL_PCHOICE_ITAG_UP
 
1279
# define RTASN1TMPL_PCHOICE_ITAG_UP(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
 
1280
    RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_UP, RT_NOTHING)
 
1281
#endif
 
1282
#ifndef RTASN1TMPL_PCHOICE_ITAG_UC
 
1283
# define RTASN1TMPL_PCHOICE_ITAG_UC(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
 
1284
    RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_UC, RT_NOTHING)
 
1285
#endif
 
1286
#ifndef RTASN1TMPL_PCHOICE_ITAG_CP
 
1287
# define RTASN1TMPL_PCHOICE_ITAG_CP(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
 
1288
    RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_CP, RT_NOTHING)
 
1289
#endif
 
1290
#ifndef RTASN1TMPL_PCHOICE_ITAG
 
1291
# define RTASN1TMPL_PCHOICE_ITAG(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
 
1292
    RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_CC, RT_NOTHING)
 
1293
#endif
 
1294
 
 
1295
#ifndef RTASN1TMPL_PCHOICE_XTAG
 
1296
# define RTASN1TMPL_PCHOICE_XTAG(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api) \
 
1297
    RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, RT_NOTHING)
 
1298
#endif
 
1299
 
 
1300
 
 
1301
/*
 
1302
 * Constraints are only used in the sanity check pass, so provide subs for the
 
1303
 * others passes.
 
1304
 */
 
1305
#ifndef RTASN1TMPL_MEMBER_CONSTR_MIN_MAX
 
1306
# define RTASN1TMPL_MEMBER_CONSTR_MIN_MAX(a_Name, a_Type, a_Api, cbMin, cbMax, a_MoreConstraints)
 
1307
#endif
 
1308
#ifndef RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX
 
1309
# define RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, cMinBits, cMaxBits, a_MoreConstraints)
 
1310
#endif
 
1311
#ifndef RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX
 
1312
# define RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX(a_Name, uMin, uMax, a_MoreConstraints)
 
1313
#endif
 
1314
#ifndef RTASN1TMPL_MEMBER_CONSTR_PRESENT
 
1315
# define RTASN1TMPL_MEMBER_CONSTR_PRESENT(a_Name, a_Api, a_MoreConstraints)
 
1316
#endif
 
1317
 
 
1318
 
 
1319
/*
 
1320
 * Stub exec hacks.
 
1321
 */
 
1322
#ifndef RTASN1TMPL_EXEC_DECODE
 
1323
# define RTASN1TMPL_EXEC_DECODE(a_Expr) /* no semi colon allowed after this */
 
1324
#endif
 
1325
#ifndef RTASN1TMPL_EXEC_CLONE
 
1326
# define RTASN1TMPL_EXEC_CLONE(a_Expr)  /* no semi colon allowed after this */
 
1327
#endif
 
1328
#ifndef RTASN1TMPL_EXEC_CHECK_SANITY
 
1329
# define RTASN1TMPL_EXEC_CHECK_SANITY(a_Expr)  /* no semi colon allowed after this */
 
1330
#endif
 
1331
 
 
1332
#define RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY() do { } while (0)
 
1333
 
 
1334
 
 
1335
/*
 
1336
 * Generate the requested code.
 
1337
 */
 
1338
#ifndef RTASN1TMPL_TEMPLATE_FILE
 
1339
# error "No template file (RTASN1TMPL_TEMPLATE_FILE) is specified."
 
1340
#endif
 
1341
#include RTASN1TMPL_TEMPLATE_FILE
 
1342
 
 
1343
 
 
1344
 
 
1345
/*
 
1346
 * Undo all the macros.
 
1347
 */
 
1348
#undef RTASN1TMPL_DECL
 
1349
#undef RTASN1TMPL_TYPE
 
1350
#undef RTASN1TMPL_EXT_NAME
 
1351
#undef RTASN1TMPL_INT_NAME
 
1352
 
 
1353
#undef RTASN1TMPL_PASS
 
1354
 
 
1355
#undef RTASN1TMPL_BEGIN_COMMON
 
1356
#undef RTASN1TMPL_END_COMMON
 
1357
#undef RTASN1TMPL_BEGIN_SEQCORE
 
1358
#undef RTASN1TMPL_BEGIN_SETCORE
 
1359
#undef RTASN1TMPL_MEMBER
 
1360
#undef RTASN1TMPL_MEMBER_EX
 
1361
#undef RTASN1TMPL_MEMBER_DYN_BEGIN
 
1362
#undef RTASN1TMPL_MEMBER_DYN
 
1363
#undef RTASN1TMPL_MEMBER_DYN_DEFAULT
 
1364
#undef RTASN1TMPL_MEMBER_DYN_COMMON
 
1365
#undef RTASN1TMPL_MEMBER_DYN_END
 
1366
#undef RTASN1TMPL_MEMBER_OPT
 
1367
#undef RTASN1TMPL_MEMBER_OPT_EX
 
1368
#undef RTASN1TMPL_MEMBER_OPT_ITAG
 
1369
#undef RTASN1TMPL_MEMBER_OPT_ITAG_EX
 
1370
#undef RTASN1TMPL_MEMBER_OPT_ITAG_CP
 
1371
#undef RTASN1TMPL_MEMBER_OPT_ITAG_UC
 
1372
#undef RTASN1TMPL_MEMBER_OPT_ITAG_UP
 
1373
#undef RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING
 
1374
#undef RTASN1TMPL_MEMBER_OPT_UTF8_STRING
 
1375
#undef RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX
 
1376
#undef RTASN1TMPL_MEMBER_OPT_XTAG
 
1377
#undef RTASN1TMPL_MEMBER_OPT_XTAG_EX
 
1378
#undef RTASN1TMPL_MEMBER_OPT_ANY
 
1379
#undef RTASN1TMPL_MEMBER_DEF_ITAG_UP
 
1380
#undef RTASN1TMPL_MEMBER_DEF_ITAG_EX
 
1381
#undef RTASN1TMPL_END_SEQCORE
 
1382
#undef RTASN1TMPL_END_SETCORE
 
1383
 
 
1384
#undef RTASN1TMPL_BEGIN_PCHOICE
 
1385
#undef RTASN1TMPL_PCHOICE_ITAG
 
1386
#undef RTASN1TMPL_PCHOICE_ITAG_UP
 
1387
#undef RTASN1TMPL_PCHOICE_ITAG_CP
 
1388
#undef RTASN1TMPL_PCHOICE_ITAG_EX
 
1389
#undef RTASN1TMPL_PCHOICE_XTAG
 
1390
#undef RTASN1TMPL_PCHOICE_XTAG_EX
 
1391
#undef RTASN1TMPL_END_PCHOICE
 
1392
 
 
1393
#undef RTASN1TMPL_SET_SEQ_OF_COMMON
 
1394
#undef RTASN1TMPL_SEQ_OF
 
1395
#undef RTASN1TMPL_SET_OF
 
1396
 
 
1397
#undef RTASN1TMPL_VTABLE_FN_ENCODE_PREP
 
1398
#undef RTASN1TMPL_VTABLE_FN_ENCODE_WRITE
 
1399
 
 
1400
#undef RTASN1TMPL_MEMBER_CONSTR_MIN_MAX
 
1401
#undef RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX
 
1402
#undef RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX
 
1403
#undef RTASN1TMPL_MEMBER_CONSTR_PRESENT
 
1404
 
 
1405
#undef RTASN1TMPL_SANITY_CHECK_EXPR
 
1406
 
 
1407
#undef RTASN1TMPL_EXEC_DECODE
 
1408
#undef RTASN1TMPL_EXEC_CLONE
 
1409
#undef RTASN1TMPL_EXEC_CHECK_SANITY
 
1410
 
 
1411
#undef RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY
 
1412