2
* IPRT - ASN.1 Code Generator, One Pass.
6
* Copyright (C) 2006-2014 Oracle Corporation
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.
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.
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.
27
#ifndef ___iprt_asn1_generator_pass_h
28
#define ___iprt_asn1_generator_pass_h
30
#include <iprt/formats/asn1.h>
33
/** @def RTASN1TMPL_MEMBER_OPT_ANY
34
* Used for optional entries without any specific type at the end of a
37
* For example PolicyQualifierInfo's qualifier member which is defined as:
38
* ANY DEFINED BY policyQualifierId
40
* Defaults to RTASN1TMPL_MEMBER_EX.
43
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_EX
44
* Optional member with implict tag, extended version.
46
* This is what all the other RTASN1TMPL_MEMBER_OPT_ITAG* macros defere to.
48
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_CP
49
* Optional member of a typical primitive type with an implicit context tag.
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
56
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_UC
57
* Optional member of a constructed type from the universal tag class.
59
/** @def RTASN1TMPL_MEMBER_OPT_ITAG_UP
60
* Optional member of a primitive type from the universal tag class.
64
/** @name Expansion Passes (RTASN1TMPL_PASS values)
66
#define RTASN1TMPL_PASS_INTERNAL_HEADER 1
68
#define RTASN1TMPL_PASS_VTABLE 2
69
#define RTASN1TMPL_PASS_ENUM 3
70
#define RTASN1TMPL_PASS_DELETE 4
71
#define RTASN1TMPL_PASS_COMPARE 5
73
#define RTASN1TMPL_PASS_CHECK_SANITY 8
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
80
#define RTASN1TMPL_PASS_DECODE 24
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) */
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) \
98
#define RTASN1TMPL_SEMICOLON_DUMMY() typedef unsigned RTASN1TMPLSEMICOLONDUMMY
100
#endif /* !___iprt_asn1_generator_pass_h */
103
#if RTASN1TMPL_PASS == RTASN1TMPL_PASS_INTERNAL_HEADER
106
* Internal header file.
109
# define RTASN1TMPL_BEGIN_COMMON() extern DECLHIDDEN(RTASN1COREVTABLE const) RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
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()
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()
128
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_BEGIN_COMMON()
129
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_BEGIN_COMMON()
133
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_VTABLE
136
* Internal header file.
139
# ifndef RTASN1TMPL_VTABLE_FN_ENCODE_PREP
140
# define RTASN1TMPL_VTABLE_FN_ENCODE_PREP NULL
142
# ifndef RTASN1TMPL_VTABLE_FN_ENCODE_WRITE
143
# define RTASN1TMPL_VTABLE_FN_ENCODE_WRITE NULL
145
# define RTASN1TMPL_BEGIN_COMMON(a_uDefaultTag, a_fDefaultClass) \
146
DECL_HIDDEN_CONST(RTASN1COREVTABLE const) RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable) = \
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 \
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()
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()
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)
193
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_INIT
196
* Initialization to standard / default values.
199
# define RTASN1TMPL_BEGIN_COMMON() \
200
RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Init)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, PCRTASN1ALLOCATORVTABLE pAllocator) \
203
# define RTASN1TMPL_END_COMMON() \
205
} RTASN1TMPL_SEMICOLON_DUMMY()
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)
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) \
222
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) do { } while (0)
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)) \
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)); \
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()
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) \
243
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
245
# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_END_COMMON()
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)) \
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)
260
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_DECODE
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) \
272
# define RTASN1TMPL_END_COMMON() \
274
} RTASN1TMPL_SEMICOLON_DUMMY()
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)) \
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)) \
291
pCursor = &ThisCursor; \
292
pThis->SetCore.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
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)
298
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
299
if (RT_SUCCESS(rc)) \
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) \
308
rc2 = RTAsn1MemAllocZ(&pThis->a_Allocation, (void **)&pThis->a_UnionNm.a_PtrName, \
309
sizeof(*pThis->a_UnionNm.a_PtrName)); \
310
if (RT_SUCCESS(rc2)) \
312
pThis->a_enmMembNm = a_enmValue; \
313
rc2 = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, 0, pThis->a_UnionNm.a_PtrName, #a_UnionNm "." #a_PtrName); \
316
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
317
rc = rc2; /* Should trigger warning if a _DEFAULT is missing. */ \
320
# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
321
Error_Missing_Specific_Macro_In_Decode_Pass()
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)) \
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); \
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)); \
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)
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)
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)
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)) \
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)) \
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); \
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)
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()
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)) \
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 */ ) ) \
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); \
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)) \
396
pThis->enmChoice = a_enmChoice; \
397
rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrTnNm, sizeof(*pThis->a_PtrTnNm)); \
398
if (RT_SUCCESS(rc)) \
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); \
410
#define RTASN1TMPL_END_PCHOICE() \
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; \
417
RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
418
RTASN1TMPL_END_COMMON()
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)) \
427
pCursor = &ThisCursor; \
428
pThis->a_OfMember.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
429
RTAsn1CursorInitAllocation(pCursor, &pThis->Allocation); \
432
while ( pCursor->cbLeft > 0 \
435
rc = RTAsn1MemGrowArray(&pThis->Allocation, \
436
(void **)&pThis->paItems, \
437
sizeof(pThis->paItems[0]), \
440
if (RT_SUCCESS(rc)) \
442
rc = RT_CONCAT(a_ItemApi,_DecodeAsn1)(pCursor, 0, &pThis->paItems[i], "paItems[#]"); \
443
if (RT_SUCCESS(rc)) \
452
if (RT_SUCCESS(rc)) \
454
rc = RTAsn1CursorCheckEnd(pCursor); \
455
if (RT_SUCCESS(rc)) \
456
return VINF_SUCCESS; \
458
RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
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)
467
# define RTASN1TMPL_EXEC_DECODE(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
471
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_ENUM
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) \
482
if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis)) \
483
return VINF_SUCCESS; \
485
int rc = VINF_SUCCESS
487
# define RTASN1TMPL_END_COMMON() \
489
} RTASN1TMPL_SEMICOLON_DUMMY()
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) \
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) \
503
rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_UnionNm.a_PtrName), #a_UnionNm "." #a_PtrName, \
506
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
507
case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
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)) \
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); \
519
# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
520
# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
523
# define RTASN1TMPL_BEGIN_PCHOICE() \
524
RTASN1TMPL_BEGIN_COMMON(); \
525
switch (pThis->enmChoice) \
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) \
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); \
537
#define RTASN1TMPL_END_PCHOICE() \
539
RTASN1TMPL_END_COMMON()
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)
551
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_CLONE
554
* Clone another instance of the type.
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) \
563
if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pSrc)) \
564
return VINF_SUCCESS; \
566
# define RTASN1TMPL_END_COMMON() \
568
} RTASN1TMPL_SEMICOLON_DUMMY()
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)
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); \
581
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
582
if (RT_SUCCESS(rc)) \
584
RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
585
pThis->a_enmMembNm = pSrc->a_enmMembNm; \
586
switch (pSrc->a_enmMembNm) \
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) \
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); \
596
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
597
case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
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)) \
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); \
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()
619
# define RTASN1TMPL_BEGIN_PCHOICE() \
620
RTASN1TMPL_BEGIN_COMMON(); \
621
RTAsn1Dummy_InitEx(&pThis->Dummy); \
622
RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
624
pThis->enmChoice = pSrc->enmChoice; \
625
switch (pSrc->enmChoice) \
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) \
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)) \
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); \
642
#define RTASN1TMPL_END_PCHOICE() \
644
if (RT_FAILURE(rc)) \
645
RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
646
RTASN1TMPL_END_COMMON()
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)) \
654
RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
655
uint32_t const cItems = pSrc->cItems; \
658
rc = RTAsn1MemGrowArray(&pThis->Allocation, (void **)&pThis->paItems, sizeof(pThis->paItems[0]), 0, cItems); \
659
if (RT_SUCCESS(rc)) \
664
rc = RT_CONCAT(a_ItemApi,_Clone)(&pThis->paItems[i], &pSrc->paItems[i], pAllocator); \
665
if (RT_SUCCESS(rc)) \
666
pThis->cItems = ++i; \
670
RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
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)
683
# define RTASN1TMPL_EXEC_CLONE(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
687
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_SETTERS_1
690
* Member setter helpers.
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()
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) \
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()
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()
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()
720
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
721
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
725
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_SETTERS_2
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()
740
# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
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) \
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)) \
754
rc = RT_CONCAT(a_Api,_Clone)(pThis->a_PtrName, pSrc, pAllocator); \
755
if (RT_SUCCESS(rc)) \
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)); \
763
} RTASN1TMPL_SEMICOLON_DUMMY()
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) \
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)) \
777
rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Init)(&pThis->a_PtrTnNm->a_CtxTagN, pAllocator); \
778
if (RT_SUCCESS(rc)) \
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)); \
786
} RTASN1TMPL_SEMICOLON_DUMMY()
788
#define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
791
# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
792
# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
795
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_COMPARE
798
* Compare two instances of the type.
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) \
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)) \
811
# define RTASN1TMPL_END_COMMON() \
813
} RTASN1TMPL_SEMICOLON_DUMMY()
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) \
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; \
824
switch (pLeft->a_enmMembNm) \
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; \
832
# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
835
if (RTASN1CORE_IS_PRESENT(&pLeft->a_TnNm.a_CtxTagN.Asn1Core)) \
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); \
843
iDiff = 0 - (int)RTASN1CORE_IS_PRESENT(&pRight->a_TnNm.a_CtxTagN.Asn1Core); \
845
# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
846
# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
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) \
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() \
861
RTASN1TMPL_END_COMMON()
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]); \
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)
878
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_CHECK_SANITY
881
* Checks the sanity of the type.
884
# ifndef RTASN1TMPL_SANITY_CHECK_EXPR
885
# define RTASN1TMPL_SANITY_CHECK_EXPR() VINF_SUCCESS
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) \
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
895
# define RTASN1TMPL_END_COMMON() \
896
if (RT_SUCCESS(rc)) \
897
rc = (RTASN1TMPL_SANITY_CHECK_EXPR()); \
899
} RTASN1TMPL_SEMICOLON_DUMMY()
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)) \
906
if (RT_LIKELY(RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name))) \
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); \
913
rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s: Missing member %s (%s).", \
914
pszErrorTag, #a_Name, RT_XSTR(RTASN1TMPL_TYPE)); \
916
# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation) \
917
if (RT_SUCCESS(rc)) \
918
switch (pThis->a_enmMembNm) \
921
rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
922
"%s: Invalid " #a_enmMembNm " value: %d", pszErrorTag, pThis->a_enmMembNm); \
924
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
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); \
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); \
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)) \
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); \
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)) \
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) \
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); \
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); \
959
# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
960
# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
963
# define RTASN1TMPL_BEGIN_PCHOICE() \
964
RTASN1TMPL_BEGIN_COMMON(); \
965
switch (pThis->enmChoice) \
968
rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
969
"%s: Invalid enmChoice value: %d", pszErrorTag, pThis->enmChoice); \
971
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
973
if (pThis->a_PtrName && RT_CONCAT(a_Api,_IsPresent)(pThis->a_PtrName)) \
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)) \
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); \
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); \
988
rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Not present.", pszErrorTag); \
990
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
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) ) \
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); \
1001
rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Not present.", pszErrorTag); \
1003
#define RTASN1TMPL_END_PCHOICE() \
1005
RTASN1TMPL_END_COMMON()
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)
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)) \
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); \
1028
{ a_MoreConstraints }
1030
# define RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, cMinBits, cMaxBits, a_MoreConstraints) \
1031
if (RT_SUCCESS(rc) && ((cMinBits) != 0 || (cMaxBits) != UINT32_MAX)) \
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); \
1039
{ a_MoreConstraints }
1041
# define RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX(a_Name, uMin, uMax, a_MoreConstraints) \
1042
if (RT_SUCCESS(rc)) \
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)); \
1051
{ a_MoreConstraints }
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 }
1060
# define RTASN1TMPL_EXEC_CHECK_SANITY(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
1063
#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_DELETE
1069
# define RTASN1TMPL_BEGIN_COMMON() \
1070
RTASN1TMPL_DECL(void) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis) \
1072
if (RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis)) \
1075
# define RTASN1TMPL_END_COMMON() \
1078
} RTASN1TMPL_SEMICOLON_DUMMY()
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) \
1087
# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
1089
if (pThis->a_UnionNm.a_PtrName) \
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; \
1096
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) \
1098
# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
1099
# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
1102
# define RTASN1TMPL_BEGIN_PCHOICE() \
1103
RTASN1TMPL_BEGIN_COMMON(); \
1104
switch (pThis->enmChoice) \
1107
# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
1109
if (pThis->a_PtrName) \
1111
RT_CONCAT(a_Api,_Delete)(pThis->a_PtrName); \
1112
RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrName); \
1113
pThis->a_PtrName = NULL; \
1116
# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
1118
if (pThis->a_PtrTnNm) \
1120
RT_CONCAT(a_Api,_Delete)(&pThis->a_PtrTnNm->a_Name); \
1121
RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrTnNm); \
1122
pThis->a_PtrTnNm = NULL; \
1125
# define RTASN1TMPL_END_PCHOICE() \
1127
RTASN1TMPL_END_COMMON()
1130
# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
1131
RTASN1TMPL_BEGIN_COMMON(); \
1132
uint32_t i = pThis->cItems; \
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)
1143
# error "Invalid/missing RTASN1TMPL_PASS value."
1149
* Default aliases for simplified versions of macros if no specialization
1150
* was required above.
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)
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)
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)
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)
1171
#ifndef RTASN1TMPL_MEMBER_STRING
1172
# define RTASN1TMPL_MEMBER_STRING(a_Name) \
1173
RTASN1TMPL_MEMBER_STRING_MIN_MAX(a_Name, 0, UINT32_MAX)
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)
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)
1184
#ifndef RTASN1TMPL_MEMBER_DYN_END
1185
# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation) do { } while (0)
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)
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))
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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))
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)
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)
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)
1272
#ifndef RTASN1TMPL_MEMBER_OPT_STRING
1273
# define RTASN1TMPL_MEMBER_OPT_STRING(a_Name) \
1274
RTASN1TMPL_MEMBER_OPT_STRING_EX(a_Name, RT_NOTHING)
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)
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)
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)
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)
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)
1302
* Constraints are only used in the sanity check pass, so provide subs for the
1305
#ifndef RTASN1TMPL_MEMBER_CONSTR_MIN_MAX
1306
# define RTASN1TMPL_MEMBER_CONSTR_MIN_MAX(a_Name, a_Type, a_Api, cbMin, cbMax, a_MoreConstraints)
1308
#ifndef RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX
1309
# define RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, cMinBits, cMaxBits, a_MoreConstraints)
1311
#ifndef RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX
1312
# define RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX(a_Name, uMin, uMax, a_MoreConstraints)
1314
#ifndef RTASN1TMPL_MEMBER_CONSTR_PRESENT
1315
# define RTASN1TMPL_MEMBER_CONSTR_PRESENT(a_Name, a_Api, a_MoreConstraints)
1322
#ifndef RTASN1TMPL_EXEC_DECODE
1323
# define RTASN1TMPL_EXEC_DECODE(a_Expr) /* no semi colon allowed after this */
1325
#ifndef RTASN1TMPL_EXEC_CLONE
1326
# define RTASN1TMPL_EXEC_CLONE(a_Expr) /* no semi colon allowed after this */
1328
#ifndef RTASN1TMPL_EXEC_CHECK_SANITY
1329
# define RTASN1TMPL_EXEC_CHECK_SANITY(a_Expr) /* no semi colon allowed after this */
1332
#define RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY() do { } while (0)
1336
* Generate the requested code.
1338
#ifndef RTASN1TMPL_TEMPLATE_FILE
1339
# error "No template file (RTASN1TMPL_TEMPLATE_FILE) is specified."
1341
#include RTASN1TMPL_TEMPLATE_FILE
1346
* Undo all the macros.
1348
#undef RTASN1TMPL_DECL
1349
#undef RTASN1TMPL_TYPE
1350
#undef RTASN1TMPL_EXT_NAME
1351
#undef RTASN1TMPL_INT_NAME
1353
#undef RTASN1TMPL_PASS
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
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
1393
#undef RTASN1TMPL_SET_SEQ_OF_COMMON
1394
#undef RTASN1TMPL_SEQ_OF
1395
#undef RTASN1TMPL_SET_OF
1397
#undef RTASN1TMPL_VTABLE_FN_ENCODE_PREP
1398
#undef RTASN1TMPL_VTABLE_FN_ENCODE_WRITE
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
1405
#undef RTASN1TMPL_SANITY_CHECK_EXPR
1407
#undef RTASN1TMPL_EXEC_DECODE
1408
#undef RTASN1TMPL_EXEC_CLONE
1409
#undef RTASN1TMPL_EXEC_CHECK_SANITY
1411
#undef RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY