VirtualBox

source: vbox/trunk/include/iprt/asn1-generator-pass.h@ 95897

Last change on this file since 95897 was 95630, checked in by vboxsync, 2 years ago

IPRT/RTAsn1,RTCrPkcs7,RTCrSpc: Generate setters for dynamic members. bugref:8691

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 84.4 KB
Line 
1/** @file
2 * IPRT - ASN.1 Code Generator, One Pass.
3 */
4
5/*
6 * Copyright (C) 2006-2022 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#ifndef ___iprt_asn1_generator_pass_h /* (special, only part of the file) */
27#define ___iprt_asn1_generator_pass_h
28
29#include <iprt/formats/asn1.h>
30#include <iprt/err.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_XTAG 2
69#define RTASN1TMPL_PASS_VTABLE 3
70#define RTASN1TMPL_PASS_ENUM 4
71#define RTASN1TMPL_PASS_DELETE 5
72#define RTASN1TMPL_PASS_COMPARE 6
73
74#define RTASN1TMPL_PASS_CHECK_SANITY 8
75
76#define RTASN1TMPL_PASS_INIT 16
77#define RTASN1TMPL_PASS_CLONE 17
78#define RTASN1TMPL_PASS_SETTERS_1 18
79#define RTASN1TMPL_PASS_SETTERS_2 19
80#define RTASN1TMPL_PASS_ARRAY 20
81
82#define RTASN1TMPL_PASS_DECODE 24
83/** @} */
84
85/** @name ITAG clues
86 * @{ */
87#define RTASN1TMPL_ITAG_F_CC 1 /**< context, constructed. */
88#define RTASN1TMPL_ITAG_F_CP 2 /**< context, probably primary. (w/ numeric value) */
89#define RTASN1TMPL_ITAG_F_UP 3 /**< universal, probably primary. (w/ ASN1_TAG_XXX value) */
90#define RTASN1TMPL_ITAG_F_UC 4 /**< universal, constructed. (w/ ASN1_TAG_XXX value) */
91/** @} */
92/** Expands the ITAG clues into tag flag and tag class. */
93#define RTASN1TMPL_ITAG_F_EXPAND(a_fClue) \
94 ( a_fClue == RTASN1TMPL_ITAG_F_CC ? (ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED ) \
95 : a_fClue == RTASN1TMPL_ITAG_F_CP ? (ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_PRIMITIVE) \
96 : a_fClue == RTASN1TMPL_ITAG_F_UP ? (ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_PRIMITIVE) \
97 : a_fClue == RTASN1TMPL_ITAG_F_UC ? (ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED) \
98 : 0 )
99
100#define RTASN1TMPL_SEMICOLON_DUMMY() typedef unsigned RTASN1TMPLSEMICOLONDUMMY
101
102#endif /* !___iprt_asn1_generator_pass_h */
103
104
105#if RTASN1TMPL_PASS == RTASN1TMPL_PASS_INTERNAL_HEADER
106/*
107 *
108 * Internal header file.
109 *
110 */
111# define RTASN1TMPL_BEGIN_COMMON() extern DECL_HIDDEN_DATA(RTASN1COREVTABLE const) RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
112
113# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
114# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
115# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
116# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
117 extern "C" DECL_HIDDEN_DATA(RTASN1COREVTABLE const) RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Vtable)
118
119# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
120# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
121# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
122# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
123
124
125# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_BEGIN_COMMON()
126# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
127 RTASN1TMPL_SEMICOLON_DUMMY()
128# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
129 extern "C" DECL_HIDDEN_DATA(RTASN1COREVTABLE const) RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable)
130
131# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
132
133
134# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_BEGIN_COMMON()
135# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_BEGIN_COMMON()
136
137
138
139#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_XTAG
140/*
141 *
142 * Generate a vtable and associated methods for explicitly tagged items (XTAG).
143 *
144 * These turned out to be a little problematic during encoding since there are
145 * two tags, the first encapsulating the second, thus the enumeration has to be
146 * nested or we cannot calculate the size of the first tag.
147 *
148 *
149 */
150# define RTASN1TMPL_BEGIN_COMMON() RTASN1TMPL_SEMICOLON_DUMMY()
151# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
152# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
153# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
154# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
155# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
156# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
157 /* This is the method we need to make it work. */ \
158 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Enum)(PRTASN1CORE pThisCore, \
159 PFNRTASN1ENUMCALLBACK pfnCallback, \
160 uint32_t uDepth, void *pvUser) \
161 { \
162 RTASN1TMPL_TYPE *pThis = RT_FROM_MEMBER(pThisCore, RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
163 if (RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core)) \
164 return pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_TnNm.a_Name), #a_TnNm "." #a_Name, uDepth + 1, pvUser); \
165 return VINF_SUCCESS; \
166 } \
167 /* The reminder of the methods shouldn't normally be needed, just stub them. */ \
168 static DECLCALLBACK(void) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Delete)(PRTASN1CORE pThisCore) \
169 { AssertFailed(); RT_NOREF_PV(pThisCore); } \
170 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Clone)(PRTASN1CORE pThisCore, PCRTASN1CORE pSrcCore, \
171 PCRTASN1ALLOCATORVTABLE pAllocator) \
172 { AssertFailed(); RT_NOREF_PV(pThisCore); RT_NOREF_PV(pSrcCore); RT_NOREF_PV(pAllocator); return VERR_INTERNAL_ERROR_2; } \
173 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Compare)(PCRTASN1CORE pLeftCore, \
174 PCRTASN1CORE pRightCore) \
175 { AssertFailed(); RT_NOREF_PV(pLeftCore); RT_NOREF_PV(pRightCore); return VERR_INTERNAL_ERROR_2; } \
176 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_CheckSanity)(PCRTASN1CORE pThisCore, uint32_t fFlags, \
177 PRTERRINFO pErrInfo, const char *pszErrorTag) \
178 { AssertFailed(); RT_NOREF_PV(pThisCore); RT_NOREF_PV(fFlags); RT_NOREF_PV(pErrInfo); RT_NOREF_PV(pszErrorTag); \
179 return VERR_INTERNAL_ERROR_2; } \
180 DECL_HIDDEN_CONST(RTASN1COREVTABLE const) RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Vtable) = \
181 { \
182 /* When the Asn1Core is at the start of the structure, we can reuse the _Delete and _Enum APIs here. */ \
183 /* .pszName = */ RT_XSTR(RTASN1TMPL_INT_NAME) "_XTAG_" RT_XSTR(a_Name), \
184 /* .cb = */ RT_SIZEOFMEMB(RTASN1TMPL_TYPE, a_TnNm), \
185 /* .uDefaultTag = */ a_uTag, \
186 /* .fDefaultClass = */ ASN1_TAGCLASS_CONTEXT, \
187 /* .uReserved = */ 0, \
188 RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Delete), \
189 RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Enum), \
190 RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Clone), \
191 RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Compare), \
192 RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_CheckSanity), \
193 /*.pfnEncodePrep */ NULL, \
194 /*.pfnEncodeWrite */ NULL \
195 }
196
197
198# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
199# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
200# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
201# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
202 RTASN1TMPL_SEMICOLON_DUMMY()
203# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
204 /* This is the method we need to make it work. */ \
205 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Enum)(PRTASN1CORE pThisCore, \
206 PFNRTASN1ENUMCALLBACK pfnCallback, \
207 uint32_t uDepth, void *pvUser) \
208 { \
209 if (RTASN1CORE_IS_PRESENT(pThisCore)) \
210 { \
211 /** @todo optimize this one day, possibly change the PCHOICE+XTAG representation. */ \
212 RTASN1TMPL_TYPE Tmp; \
213 *(PRTASN1CORE *)&Tmp.a_PtrTnNm = pThisCore; \
214 Assert(&Tmp.a_PtrTnNm->a_CtxTagN.Asn1Core == pThisCore); \
215 return pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&Tmp.a_PtrTnNm->a_Name), "T" #a_uTag "." #a_Name, uDepth + 1, pvUser); \
216 } \
217 return VINF_SUCCESS; \
218 } \
219 /* The reminder of the methods shouldn't normally be needed, just stub them. */ \
220 static DECLCALLBACK(void) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Delete)(PRTASN1CORE pThisCore) \
221 { AssertFailed(); RT_NOREF_PV(pThisCore); } \
222 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Clone)(PRTASN1CORE pThisCore, PCRTASN1CORE pSrcCore, \
223 PCRTASN1ALLOCATORVTABLE pAllocator) \
224 { AssertFailed(); RT_NOREF_PV(pThisCore); RT_NOREF_PV(pSrcCore); RT_NOREF_PV(pAllocator); return VERR_INTERNAL_ERROR_3; } \
225 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Compare)(PCRTASN1CORE pLeftCore, \
226 PCRTASN1CORE pRightCore) \
227 { AssertFailed(); RT_NOREF_PV(pLeftCore); RT_NOREF_PV(pRightCore); return VERR_INTERNAL_ERROR_3; } \
228 static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_CheckSanity)(PCRTASN1CORE pThisCore, uint32_t fFlags, \
229 PRTERRINFO pErrInfo, const char *pszErrorTag) \
230 { AssertFailed(); RT_NOREF_PV(pThisCore); RT_NOREF_PV(fFlags); RT_NOREF_PV(pErrInfo); RT_NOREF_PV(pszErrorTag); \
231 return VERR_INTERNAL_ERROR_3; } \
232 DECL_HIDDEN_CONST(RTASN1COREVTABLE const) RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable) = \
233 { \
234 /* When the Asn1Core is at the start of the structure, we can reuse the _Delete and _Enum APIs here. */ \
235 /* .pszName = */ RT_XSTR(RTASN1TMPL_INT_NAME) "_PCHOICE_XTAG_" RT_XSTR(a_Name), \
236 /* .cb = */ sizeof(*((RTASN1TMPL_TYPE *)(void *)0)->a_PtrTnNm), \
237 /* .uDefaultTag = */ a_uTag, \
238 /* .fDefaultClass = */ ASN1_TAGCLASS_CONTEXT, \
239 /* .uReserved = */ 0, \
240 RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Delete), \
241 RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Enum), \
242 RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Clone), \
243 RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Compare), \
244 RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_CheckSanity), \
245 /*.pfnEncodePrep */ NULL, \
246 /*.pfnEncodeWrite */ NULL \
247 }
248
249
250
251# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
252# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
253# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
254
255
256
257#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_VTABLE
258/*
259 *
260 * Internal header file.
261 *
262 */
263# ifndef RTASN1TMPL_VTABLE_FN_ENCODE_PREP
264# define RTASN1TMPL_VTABLE_FN_ENCODE_PREP NULL
265# endif
266# ifndef RTASN1TMPL_VTABLE_FN_ENCODE_WRITE
267# define RTASN1TMPL_VTABLE_FN_ENCODE_WRITE NULL
268# endif
269# define RTASN1TMPL_BEGIN_COMMON(a_uDefaultTag, a_fDefaultClass) \
270 DECL_HIDDEN_CONST(RTASN1COREVTABLE const) RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable) = \
271 { \
272 /* When the Asn1Core is at the start of the structure, we can reuse the _Delete and _Enum APIs here. */ \
273 /* .pszName = */ RT_XSTR(RTASN1TMPL_EXT_NAME), \
274 /* .cb = */ sizeof(RTASN1TMPL_TYPE), \
275 /* .uDefaultTag = */ a_uDefaultTag, \
276 /* .fDefaultClass = */ a_fDefaultClass, \
277 /* .uReserved = */ 0, \
278 (PFNRTASN1COREVTDTOR)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete), \
279 (PFNRTASN1COREVTENUM)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Enum), \
280 (PFNRTASN1COREVTCLONE)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Clone), \
281 (PFNRTASN1COREVTCOMPARE)RT_CONCAT(RTASN1TMPL_EXT_NAME,_Compare), \
282 (PFNRTASN1COREVTCHECKSANITY)RT_CONCAT(RTASN1TMPL_EXT_NAME,_CheckSanity), \
283 RTASN1TMPL_VTABLE_FN_ENCODE_PREP, \
284 RTASN1TMPL_VTABLE_FN_ENCODE_WRITE \
285 }
286
287# define RTASN1TMPL_BEGIN_SEQCORE() \
288 AssertCompileMemberOffset(RTASN1TMPL_TYPE, SeqCore, 0); \
289 RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SEQUENCE, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
290# define RTASN1TMPL_BEGIN_SETCORE() \
291 AssertCompileMemberOffset(RTASN1TMPL_TYPE, SetCore, 0); \
292 RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SET, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
293# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
294# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
295# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
296# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
297# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
298
299# define RTASN1TMPL_BEGIN_PCHOICE() \
300 AssertCompileMemberOffset(RTASN1TMPL_TYPE, Dummy, 0); \
301 RTASN1TMPL_BEGIN_COMMON(UINT8_MAX, UINT8_MAX)
302# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
303 RTASN1TMPL_SEMICOLON_DUMMY()
304# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
305 RTASN1TMPL_SEMICOLON_DUMMY()
306# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
307
308# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) \
309 AssertCompileMemberOffset(RTASN1TMPL_TYPE, SeqCore, 0); \
310 RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SEQUENCE, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
311# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) \
312 AssertCompileMemberOffset(RTASN1TMPL_TYPE, SetCore, 0); \
313 RTASN1TMPL_BEGIN_COMMON(ASN1_TAG_SET, ASN1_TAGCLASS_UNIVERSAL | ASN1_TAGFLAG_CONSTRUCTED)
314
315
316
317#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_INIT
318/*
319 *
320 * Initialization to standard / default values.
321 *
322 */
323# define RTASN1TMPL_BEGIN_COMMON() \
324RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Init)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, PCRTASN1ALLOCATORVTABLE pAllocator) \
325{ \
326 RT_NOREF_PV(pAllocator); \
327 RT_ZERO(*pThis)
328# define RTASN1TMPL_END_COMMON() \
329 return rc; \
330} RTASN1TMPL_SEMICOLON_DUMMY()
331
332# define RTASN1TMPL_BEGIN_SEQCORE() \
333 RTASN1TMPL_BEGIN_COMMON(); \
334 int rc = RTAsn1SequenceCore_Init(&pThis->SeqCore, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable))
335# define RTASN1TMPL_BEGIN_SETCORE() \
336 RTASN1TMPL_BEGIN_COMMON(); \
337 int rc = RTAsn1SetCore_Init(&pThis->SetCore, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable))
338# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
339 if (RT_SUCCESS(rc)) \
340 rc = RT_CONCAT(a_Api,_Init)(&pThis->a_Name, pAllocator)
341
342# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
343 RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
344 pThis->a_enmMembNm = RT_CONCAT(a_enmType,_NOT_PRESENT)
345# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
346 do { } while (0)
347# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) do { } while (0)
348
349# define RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_DefVal, a_Constraints) \
350 if (RT_SUCCESS(rc)) \
351 { \
352 rc = RT_CONCAT(a_Api,_InitDefault)(&pThis->a_Name, a_DefVal, pAllocator); \
353 if (RT_SUCCESS(rc)) \
354 rc = RTAsn1Core_SetTagAndFlags(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), \
355 a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)); \
356 }
357# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) do { } while (0) /* All optional members are left as not-present. */
358# define RTASN1TMPL_END_SEQCORE() \
359 if (RT_FAILURE(rc)) \
360 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
361 RTASN1TMPL_END_COMMON()
362# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_SEQCORE()
363
364/* No choice, just an empty, non-present structure. */
365# define RTASN1TMPL_BEGIN_PCHOICE() \
366 RTASN1TMPL_BEGIN_COMMON(); \
367 RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
368 int rc = VINF_SUCCESS
369# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
370 do { } while (0)
371# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
372 do { } while (0)
373# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_END_COMMON()
374
375
376# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, a_OfApi, a_OfMember) \
377 RTASN1TMPL_BEGIN_COMMON(); \
378 RTAsn1MemInitArrayAllocation(&pThis->Allocation, pAllocator, sizeof(a_ItemType)); \
379 int rc = RT_CONCAT(a_OfApi,_Init)(&pThis->a_OfMember, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)); \
380 if (RT_FAILURE(rc)) \
381 RT_ZERO(*pThis); \
382 RTASN1TMPL_END_COMMON()
383# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SeqOfCore, SeqCore)
384# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SetOfCore, SetCore)
385
386
387
388#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_DECODE
389/*
390 *
391 * Decode ASN.1.
392 *
393 */
394# define RTASN1TMPL_BEGIN_COMMON() \
395RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_DecodeAsn1)(PRTASN1CURSOR pCursor, uint32_t fFlags, \
396 RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, const char *pszErrorTag) \
397{ \
398 RT_ZERO(*pThis);
399
400# define RTASN1TMPL_END_COMMON() \
401 return rc; \
402} RTASN1TMPL_SEMICOLON_DUMMY()
403
404
405# define RTASN1TMPL_BEGIN_SEQCORE() \
406 RTASN1TMPL_BEGIN_COMMON(); \
407 RTASN1CURSOR ThisCursor; \
408 int rc = RTAsn1CursorGetSequenceCursor(pCursor, fFlags, &pThis->SeqCore, &ThisCursor, pszErrorTag); \
409 if (RT_FAILURE(rc)) \
410 return rc; \
411 pCursor = &ThisCursor; \
412 pThis->SeqCore.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
413# define RTASN1TMPL_BEGIN_SETCORE() \
414 RTASN1TMPL_BEGIN_COMMON(); \
415 RTASN1CURSOR ThisCursor; \
416 int rc = RTAsn1CursorGetSetCursor(pCursor, fFlags, &pThis->SetCore, &ThisCursor, pszErrorTag); \
417 if (RT_FAILURE(rc)) \
418 return rc; \
419 pCursor = &ThisCursor; \
420 pThis->SetCore.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable)
421
422# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
423 if (RT_SUCCESS(rc)) \
424 rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, 0, &pThis->a_Name, #a_Name)
425
426# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
427 if (RT_SUCCESS(rc)) \
428 { \
429 int rc2; /* not initialized! */ \
430 RTAsn1CursorInitAllocation(pCursor, &pThis->a_Allocation); \
431 pThis->a_enmMembNm = RT_CONCAT(a_enmType, _INVALID); \
432 if (false) do { /*nothing*/ } while (0)
433# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
434 else a_IfStmt \
435 do { \
436 rc2 = RTAsn1MemAllocZ(&pThis->a_Allocation, (void **)&pThis->a_UnionNm.a_PtrName, \
437 sizeof(*pThis->a_UnionNm.a_PtrName)); \
438 if (RT_SUCCESS(rc2)) \
439 { \
440 pThis->a_enmMembNm = a_enmValue; \
441 rc2 = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, 0, pThis->a_UnionNm.a_PtrName, #a_UnionNm "." #a_PtrName); \
442 } \
443 } while (0)
444# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
445 rc = rc2; /* Should trigger warning if a _DEFAULT is missing. */ \
446 }
447
448# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
449 Error_Missing_Specific_Macro_In_Decode_Pass()
450
451# define RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_DefVal, a_Constraints) \
452 if (RT_SUCCESS(rc)) \
453 { \
454 if (RTAsn1CursorIsNextEx(pCursor, a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue))) \
455 rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, 0, &pThis->a_Name, #a_Name); \
456 else \
457 rc = RT_CONCAT(a_Api,_InitDefault)(&pThis->a_Name, a_DefVal, pCursor->pPrimary->pAllocator); \
458 if (RT_SUCCESS(rc)) \
459 rc = RTAsn1Core_SetTagAndFlags(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), \
460 a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)); \
461 } do {} while (0)
462
463# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, a_Constraints) \
464 if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, ASN1_TAG_UTF8_STRING, ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_PRIMITIVE)) \
465 rc = RTAsn1CursorGetUtf8String(pCursor, 0, &pThis->a_Name, #a_Name)
466
467# define RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_Constraints) \
468 if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)) /** @todo || CER */) \
469 rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, RTASN1CURSOR_GET_F_IMPLICIT, &pThis->a_Name, #a_Name)
470
471# define RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING(a_Name, a_cMaxBits, a_uTag) \
472 if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, a_uTag, ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED)) \
473 rc = RTAsn1CursorGetBitStringEx(pCursor, RTASN1CURSOR_GET_F_IMPLICIT, a_cMaxBits, &pThis->a_Name, #a_Name)
474
475# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
476 if (RT_SUCCESS(rc) && RTAsn1CursorIsNextEx(pCursor, a_uTag, ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED)) \
477 { \
478 RTASN1CURSOR CtxCursor; \
479 rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, \
480 &RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Vtable), \
481 &pThis->a_TnNm.a_CtxTagN, &CtxCursor, #a_TnNm); \
482 if (RT_SUCCESS(rc)) \
483 { \
484 rc = RT_CONCAT(a_Api,_DecodeAsn1)(&CtxCursor, 0, &pThis->a_TnNm.a_Name, #a_Name); \
485 if (RT_SUCCESS(rc)) \
486 rc = RTAsn1CursorCheckEnd(&CtxCursor); \
487 } \
488 } do { } while (0)
489
490# define RTASN1TMPL_MEMBER_OPT_ANY(a_Name, a_Type, a_Api) \
491 if (RT_SUCCESS(rc) && pCursor->cbLeft > 0) \
492 RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, RT_NOTHING)
493
494# define RTASN1TMPL_END_SEQCORE() \
495 if (RT_SUCCESS(rc)) \
496 rc = RTAsn1CursorCheckSeqEnd(&ThisCursor, &pThis->SeqCore); \
497 if (RT_SUCCESS(rc)) \
498 return VINF_SUCCESS; \
499 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
500 RTASN1TMPL_END_COMMON()
501# define RTASN1TMPL_END_SETCORE() \
502 if (RT_SUCCESS(rc)) \
503 rc = RTAsn1CursorCheckSetEnd(&ThisCursor, &pThis->SetCore); \
504 if (RT_SUCCESS(rc)) \
505 return VINF_SUCCESS; \
506 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
507 RTASN1TMPL_END_COMMON()
508
509# define RTASN1TMPL_BEGIN_PCHOICE() \
510 RTASN1TMPL_BEGIN_COMMON(); \
511 RT_NOREF_PV(fFlags); \
512 RTAsn1Dummy_InitEx(&pThis->Dummy); \
513 pThis->Dummy.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
514 RTAsn1CursorInitAllocation(pCursor, &pThis->Allocation); \
515 RTASN1CORE Asn1Peek; \
516 int rc = RTAsn1CursorPeek(pCursor, &Asn1Peek); \
517 if (RT_SUCCESS(rc)) \
518 { \
519 if (false) do {} while (0)
520# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
521 else if ( Asn1Peek.uTag == (a_uTag) \
522 && (Asn1Peek.fClass == RTASN1TMPL_ITAG_F_EXPAND(a_fClue) /** @todo || CER */ ) ) \
523 do { \
524 pThis->enmChoice = a_enmChoice; \
525 rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrName, sizeof(*pThis->a_PtrName)); \
526 if (RT_SUCCESS(rc)) \
527 rc = RT_CONCAT(a_Api,_DecodeAsn1)(pCursor, RTASN1CURSOR_GET_F_IMPLICIT, pThis->a_PtrName, #a_PtrName); \
528 } while (0)
529# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
530 else if (Asn1Peek.uTag == (a_uTag) && Asn1Peek.fClass == (ASN1_TAGCLASS_CONTEXT | ASN1_TAGFLAG_CONSTRUCTED)) \
531 do { \
532 pThis->enmChoice = a_enmChoice; \
533 rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrTnNm, sizeof(*pThis->a_PtrTnNm)); \
534 if (RT_SUCCESS(rc)) \
535 { \
536 RTASN1CURSOR CtxCursor; \
537 rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, \
538 &RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable), \
539 &pThis->a_PtrTnNm->a_CtxTagN, &CtxCursor, "T" #a_uTag); \
540 if (RT_SUCCESS(rc)) \
541 rc = RT_CONCAT(a_Api,_DecodeAsn1)(&CtxCursor, RTASN1CURSOR_GET_F_IMPLICIT, \
542 &pThis->a_PtrTnNm->a_Name, #a_Name); \
543 if (RT_SUCCESS(rc)) \
544 rc = RTAsn1CursorCheckEnd(&CtxCursor); \
545 } \
546 } while (0)
547#define RTASN1TMPL_END_PCHOICE() \
548 else \
549 rc = RTAsn1CursorSetInfo(pCursor, VERR_GENERAL_FAILURE, "%s: Unknown choice: tag=%#x fClass=%#x", \
550 pszErrorTag, Asn1Peek.uTag, Asn1Peek.fClass); \
551 if (RT_SUCCESS(rc)) \
552 return VINF_SUCCESS; \
553 } \
554 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
555 RTASN1TMPL_END_COMMON()
556
557
558# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, a_OfApi, a_OfMember, a_fnGetCursor) \
559 RTASN1TMPL_BEGIN_COMMON(); \
560 RTASN1CURSOR ThisCursor; \
561 int rc = a_fnGetCursor(pCursor, fFlags, &pThis->a_OfMember, &ThisCursor, pszErrorTag); \
562 if (RT_SUCCESS(rc)) \
563 { \
564 pCursor = &ThisCursor; \
565 pThis->a_OfMember.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
566 RTAsn1CursorInitArrayAllocation(pCursor, &pThis->Allocation, sizeof(a_ItemType)); \
567 \
568 uint32_t i = 0; \
569 while ( pCursor->cbLeft > 0 \
570 && RT_SUCCESS(rc)) \
571 { \
572 rc = RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, i, i + 1); \
573 if (RT_SUCCESS(rc)) \
574 { \
575 rc = RT_CONCAT(a_ItemApi,_DecodeAsn1)(pCursor, 0, pThis->papItems[i], "papItems[#]"); \
576 if (RT_SUCCESS(rc)) \
577 { \
578 i++; \
579 pThis->cItems = i; \
580 continue; \
581 } \
582 } \
583 break; \
584 } \
585 if (RT_SUCCESS(rc)) \
586 { \
587 rc = RTAsn1CursorCheckEnd(pCursor); \
588 if (RT_SUCCESS(rc)) \
589 return VINF_SUCCESS; \
590 } \
591 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
592 } \
593 RTASN1TMPL_END_COMMON()
594# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) \
595 RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SeqOfCore, SeqCore, RTAsn1CursorGetSequenceCursor)
596# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) \
597 RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SetOfCore, SetCore, RTAsn1CursorGetSetCursor)
598
599
600# define RTASN1TMPL_EXEC_DECODE(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
601
602
603
604#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_ENUM
605/*
606 *
607 * Enumeration.
608 *
609 */
610# define RTASN1TMPL_BEGIN_COMMON() \
611RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Enum)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
612 PFNRTASN1ENUMCALLBACK pfnCallback, \
613 uint32_t uDepth, void *pvUser) \
614{ \
615 if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis)) \
616 return VINF_SUCCESS; \
617 uDepth++; \
618 int rc = VINF_SUCCESS
619
620# define RTASN1TMPL_END_COMMON() \
621 return rc; \
622} RTASN1TMPL_SEMICOLON_DUMMY()
623
624# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
625# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
626# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
627 if (rc == VINF_SUCCESS) \
628 rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), #a_Name, uDepth, pvUser)
629# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
630 if (rc == VINF_SUCCESS) \
631 switch (pThis->a_enmMembNm) \
632 { \
633 default: rc = VERR_INTERNAL_ERROR_3; break
634# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
635 case a_enmValue: \
636 rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_UnionNm.a_PtrName), #a_UnionNm "." #a_PtrName, \
637 uDepth, pvUser); \
638 break
639# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
640 case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
641 }
642# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
643 if (rc == VINF_SUCCESS && RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name)) \
644 rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), #a_Name, uDepth, pvUser)
645# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
646 if (rc == VINF_SUCCESS && RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core)) \
647 { \
648 rc = pfnCallback(&pThis->a_TnNm.a_CtxTagN.Asn1Core, #a_Name, uDepth, pvUser); \
649 } do {} while (0)
650# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
651# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
652
653
654# define RTASN1TMPL_BEGIN_PCHOICE() \
655 RTASN1TMPL_BEGIN_COMMON(); \
656 switch (pThis->enmChoice) \
657 { \
658 default: rc = VERR_INTERNAL_ERROR_3; break
659# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
660 case a_enmChoice: rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName), #a_PtrName, uDepth, pvUser); break
661# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
662 case a_enmChoice: rc = pfnCallback(&pThis->a_PtrTnNm->a_CtxTagN.Asn1Core, "T" #a_uTag "." #a_CtxTagN, uDepth, pvUser); break
663#define RTASN1TMPL_END_PCHOICE() \
664 } \
665 RTASN1TMPL_END_COMMON()
666
667# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
668 RTASN1TMPL_BEGIN_COMMON(); \
669 for (uint32_t i = 0; i < pThis->cItems && rc == VINF_SUCCESS; i++) \
670 rc = pfnCallback(RT_CONCAT(a_ItemApi,_GetAsn1Core)(pThis->papItems[i]), "papItems[#]", uDepth, pvUser); \
671 RTASN1TMPL_END_COMMON()
672# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
673# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
674
675
676
677#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_CLONE
678/*
679 *
680 * Clone another instance of the type.
681 *
682 */
683# define RTASN1TMPL_BEGIN_COMMON() \
684RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Clone)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
685 RT_CONCAT(PC,RTASN1TMPL_TYPE) pSrc, \
686 PCRTASN1ALLOCATORVTABLE pAllocator) \
687{ \
688 RT_ZERO(*pThis); \
689 if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pSrc)) \
690 return VINF_SUCCESS; \
691
692# define RTASN1TMPL_END_COMMON() \
693 return rc; \
694} RTASN1TMPL_SEMICOLON_DUMMY()
695
696# define RTASN1TMPL_BEGIN_SEQCORE() \
697 RTASN1TMPL_BEGIN_COMMON(); \
698 int rc = RTAsn1SequenceCore_Clone(&pThis->SeqCore, &RT_CONCAT3(g_, RTASN1TMPL_INT_NAME, _Vtable), &pSrc->SeqCore)
699# define RTASN1TMPL_BEGIN_SETCORE() \
700 RTASN1TMPL_BEGIN_COMMON(); \
701 int rc = RTAsn1SetCore_Clone(&pThis->SetCore, &RT_CONCAT3(g_, RTASN1TMPL_INT_NAME, _Vtable), &pSrc->SetCore)
702
703# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
704 if (RT_SUCCESS(rc)) \
705 rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_Name, &pSrc->a_Name, pAllocator); \
706
707# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
708 if (RT_SUCCESS(rc)) \
709 { \
710 RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
711 pThis->a_enmMembNm = pSrc->a_enmMembNm; \
712 switch (pSrc->a_enmMembNm) \
713 { \
714 default: rc = VERR_INTERNAL_ERROR_3; break
715# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
716 case a_enmValue: \
717 rc = RTAsn1MemAllocZ(&pThis->a_Allocation, (void **)&pThis->a_UnionNm.a_PtrName, \
718 sizeof(*pThis->a_UnionNm.a_PtrName)); \
719 if (RT_SUCCESS(rc)) \
720 rc = RT_CONCAT(a_Api,_Clone)(pThis->a_UnionNm.a_PtrName, pSrc->a_UnionNm.a_PtrName, pAllocator); \
721 break
722# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
723 case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
724 } \
725 }
726
727/* Optional members and members with defaults are the same as a normal member when cloning. */
728# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, a_Constraints) \
729 RTASN1TMPL_MEMBER_OPT_EX(a_Name, RTASN1STRING, RTAsn1Utf8String, a_Constraints RT_NOTHING)
730# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
731 if (RTASN1CORE_IS_PRESENT(&pSrc->a_TnNm.a_CtxTagN.Asn1Core) && RT_SUCCESS(rc)) \
732 { \
733 rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Clone)(&pThis->a_TnNm.a_CtxTagN, &pSrc->a_TnNm.a_CtxTagN); \
734 if (RT_SUCCESS(rc)) \
735 rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_TnNm.a_Name, &pSrc->a_TnNm.a_Name, pAllocator); \
736 } do { } while (0)
737
738# define RTASN1TMPL_END_SEQCORE() \
739 if (RT_FAILURE(rc)) \
740 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
741 RTASN1TMPL_END_COMMON()
742# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_SEQCORE()
743
744
745# define RTASN1TMPL_BEGIN_PCHOICE() \
746 RTASN1TMPL_BEGIN_COMMON(); \
747 RTAsn1Dummy_InitEx(&pThis->Dummy); \
748 pThis->Dummy.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
749 RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
750 int rc; \
751 pThis->enmChoice = pSrc->enmChoice; \
752 switch (pSrc->enmChoice) \
753 { \
754 default: rc = VERR_INTERNAL_ERROR_3; break
755# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
756 case a_enmChoice: \
757 rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrName, sizeof(*pThis->a_PtrName)); \
758 if (RT_SUCCESS(rc)) \
759 rc = RT_CONCAT(a_Api,_Clone)(pThis->a_PtrName, pSrc->a_PtrName, pAllocator); \
760 break
761# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
762 case a_enmChoice: /* A bit of presence paranoia here, but better safe than sorry... */ \
763 rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrTnNm, sizeof(*pThis->a_PtrTnNm)); \
764 if (RT_SUCCESS(rc) && RTASN1CORE_IS_PRESENT(&pSrc->a_PtrTnNm->a_CtxTagN.Asn1Core)) \
765 { \
766 RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Clone)(&pThis->a_PtrTnNm->a_CtxTagN, &pSrc->a_PtrTnNm->a_CtxTagN); \
767 rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_PtrTnNm->a_Name, &pSrc->a_PtrTnNm->a_Name, pAllocator); \
768 } \
769 break
770#define RTASN1TMPL_END_PCHOICE() \
771 } \
772 if (RT_FAILURE(rc)) \
773 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
774 RTASN1TMPL_END_COMMON()
775
776
777# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, a_OfApi, a_OfMember) \
778 RTASN1TMPL_BEGIN_COMMON(); \
779 int rc = RT_CONCAT(a_OfApi,_Clone)(&pThis->a_OfMember, &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable), &pSrc->a_OfMember); \
780 if (RT_SUCCESS(rc)) \
781 { \
782 RTAsn1MemInitArrayAllocation(&pThis->Allocation, pAllocator, sizeof(a_ItemType)); \
783 uint32_t const cItems = pSrc->cItems; \
784 if (cItems > 0) \
785 { \
786 rc = RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, 0, cItems); \
787 if (RT_SUCCESS(rc)) \
788 { \
789 uint32_t i = 0; \
790 while (i < cItems) \
791 { \
792 rc = RT_CONCAT(a_ItemApi,_Clone)(pThis->papItems[i], pSrc->papItems[i], pAllocator); \
793 if (RT_SUCCESS(rc)) \
794 pThis->cItems = ++i; \
795 else \
796 { \
797 pThis->cItems = i; \
798 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); \
799 return rc; \
800 } \
801 } \
802 } \
803 else \
804 RT_ZERO(*pThis); \
805 } \
806 } \
807 RTASN1TMPL_END_COMMON()
808# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SeqOfCore, SeqCore)
809# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi, RTAsn1SetOfCore, SetCore)
810
811# define RTASN1TMPL_EXEC_CLONE(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
812
813
814
815#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_SETTERS_1
816/*
817 *
818 * Member setter helpers.
819 *
820 */
821# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
822# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
823#if 1 /** @todo later */
824# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
825#else
826# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
827 RTDECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RTASN1TMPL_TYPE *pThis, a_Type const *pValue, \
828 PCRTASN1ALLOCATORVTABLE pAllocator) \
829 { \
830 if (RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name)) \
831 RT_CONCAT(a_Api,_Delete)(&pThis->a_Name); \
832 return RT_CONCAT(a_Api,_Clone)(&pThis->a_Name, pValue, pAllocator, true /* fResetImplicit */); \
833 } RTASN1TMPL_SEMICOLON_DUMMY()
834#endif
835
836# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
837# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
838# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
839# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
840
841
842# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
843# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
844# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
845# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
846
847
848# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
849# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
850
851
852
853#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_SETTERS_2
854/*
855 *
856 * Member setters.
857 *
858 */
859# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
860# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
861# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
862# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
863
864# define RTASN1TMPL_MEMBER_DYN(a_UnionNm, a_PtrName, a_Name, a_Type, a_Api, a_Allocation, a_ObjIdMembNm, a_enmMembNm, a_enmValue, a_szObjId) \
865RTASN1TMPL_DECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
866 RT_CONCAT(PC,a_Type) pToClone,\
867 PCRTASN1ALLOCATORVTABLE pAllocator) \
868{ \
869 AssertPtr(pThis); AssertPtrNull(pToClone); Assert(!pToClone || RT_CONCAT(a_Api,_IsPresent)(pToClone)); \
870 AssertReturn(pThis->a_UnionNm.a_PtrName == NULL, VERR_INVALID_STATE); /* for now */ \
871 /* Set the type */ \
872 if (RTAsn1ObjId_IsPresent(&pThis->a_ObjIdMembNm)) \
873 RTAsn1ObjId_Delete(&pThis->a_ObjIdMembNm); \
874 int rc = RTAsn1ObjId_InitFromString(&pThis->a_ObjIdMembNm, a_szObjId, pAllocator); \
875 if (RT_SUCCESS(rc)) \
876 { \
877 pThis->a_enmMembNm = a_enmValue; \
878 \
879 /* Allocate memory for the structure we're targeting. */ \
880 rc = RTAsn1MemAllocZ(&pThis->a_Allocation, (void **)&pThis->a_UnionNm.a_PtrName, sizeof(*pThis->a_UnionNm.a_PtrName)); \
881 if (RT_SUCCESS(rc)) \
882 { \
883 if (pToClone) /* If nothing to clone, just initialize the structure. */ \
884 rc = RT_CONCAT(a_Api,_Clone)(pThis->a_UnionNm.a_PtrName, pToClone, pAllocator); \
885 else \
886 rc = RT_CONCAT(a_Api,_Init)(pThis->a_UnionNm.a_PtrName, pAllocator); \
887 } \
888 } \
889 return rc; \
890} RTASN1TMPL_SEMICOLON_DUMMY()
891
892
893
894# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
895# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
896# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
897
898# define RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_Constraints) \
899RTASN1TMPL_DECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
900 RT_CONCAT(PC,a_Type) pToClone,\
901 PCRTASN1ALLOCATORVTABLE pAllocator) \
902{ \
903 AssertPtr(pThis); AssertPtrNull(pToClone); Assert(!pToClone || RT_CONCAT(a_Api,_IsPresent)(pToClone)); \
904 if (RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name)) \
905 RT_CONCAT(a_Api,_Delete)(&pThis->a_Name); \
906 \
907 int rc; \
908 if (pToClone) \
909 rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_Name, pToClone, pAllocator); \
910 else \
911 rc = RT_CONCAT(a_Api,_Init)(&pThis->a_Name, pAllocator); \
912 if (RT_SUCCESS(rc)) \
913 { \
914 RTAsn1Core_ResetImplict(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name)); /* probably not needed */ \
915 rc = RTAsn1Core_SetTagAndFlags(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name), \
916 a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)); \
917 } \
918 return rc; \
919} RTASN1TMPL_SEMICOLON_DUMMY()
920
921# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
922RTASN1TMPL_DECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
923 RT_CONCAT(PC,a_Type) pToClone,\
924 PCRTASN1ALLOCATORVTABLE pAllocator) \
925{ \
926 AssertPtr(pThis); AssertPtrNull(pToClone); Assert(!pToClone || RT_CONCAT(a_Api,_IsPresent)(pToClone)); \
927 if (RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core)) \
928 RT_CONCAT(a_Api,_Delete)(&pThis->a_TnNm.a_Name); \
929 \
930 int rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Init)(&pThis->a_TnNm.a_CtxTagN, \
931 &RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Vtable), \
932 pAllocator); \
933 if (RT_SUCCESS(rc)) \
934 { \
935 if (pToClone) \
936 rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_TnNm.a_Name, pToClone, pAllocator); \
937 else \
938 rc = RT_CONCAT(a_Api,_Init)(&pThis->a_TnNm.a_Name, pAllocator); \
939 if (RT_SUCCESS(rc) && pToClone) \
940 RTAsn1Core_ResetImplict(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_TnNm.a_Name)); \
941 } \
942 return rc; \
943} RTASN1TMPL_SEMICOLON_DUMMY()
944
945# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
946
947# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
948RTASN1TMPL_DECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
949 RT_CONCAT(PC,a_Type) pToClone,\
950 PCRTASN1ALLOCATORVTABLE pAllocator) \
951{ \
952 AssertPtrNull(pToClone); AssertPtr(pThis); \
953 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); /* See _Init. */ \
954 RTAsn1Dummy_InitEx(&pThis->Dummy); \
955 pThis->Dummy.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
956 RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
957 pThis->enmChoice = a_enmChoice; \
958 int rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrName, sizeof(*pThis->a_PtrName)); \
959 if (RT_SUCCESS(rc)) \
960 { \
961 if (pToClone) \
962 rc = RT_CONCAT(a_Api,_Clone)(pThis->a_PtrName, pToClone, pAllocator); \
963 else \
964 rc = RT_CONCAT(a_Api,_Init)(pThis->a_PtrName, pAllocator); \
965 if (RT_SUCCESS(rc)) \
966 { \
967 if (pToClone) \
968 RTAsn1Core_ResetImplict(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName)); \
969 rc = RTAsn1Core_SetTagAndFlags(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName), \
970 a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue)); \
971 } \
972 } \
973 return rc; \
974} RTASN1TMPL_SEMICOLON_DUMMY()
975
976# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
977RTASN1TMPL_DECL(int) RT_CONCAT3(RTASN1TMPL_EXT_NAME,_Set,a_Name)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, \
978 RT_CONCAT(PC,a_Type) pToClone,\
979 PCRTASN1ALLOCATORVTABLE pAllocator) \
980{ \
981 AssertPtr(pThis); AssertPtrNull(pToClone); Assert(!pToClone || RT_CONCAT(a_Api,_IsPresent)(pToClone)); \
982 RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(pThis); /* See _Init. */ \
983 RTAsn1Dummy_InitEx(&pThis->Dummy); \
984 pThis->Dummy.Asn1Core.pOps = &RT_CONCAT3(g_,RTASN1TMPL_INT_NAME,_Vtable); \
985 RTAsn1MemInitAllocation(&pThis->Allocation, pAllocator); \
986 pThis->enmChoice = a_enmChoice; \
987 int rc = RTAsn1MemAllocZ(&pThis->Allocation, (void **)&pThis->a_PtrTnNm, sizeof(*pThis->a_PtrTnNm)); \
988 if (RT_SUCCESS(rc)) \
989 { \
990 rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Init)(&pThis->a_PtrTnNm->a_CtxTagN, \
991 &RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable), \
992 pAllocator); \
993 if (RT_SUCCESS(rc)) \
994 { \
995 if (pToClone) \
996 rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_PtrTnNm->a_Name, pToClone, pAllocator); \
997 else \
998 rc = RT_CONCAT(a_Api,_Init)(&pThis->a_PtrTnNm->a_Name, pAllocator); \
999 if (RT_SUCCESS(rc) && pToClone) \
1000 RTAsn1Core_ResetImplict(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_PtrTnNm->a_Name)); \
1001 } \
1002 } \
1003 return rc; \
1004} RTASN1TMPL_SEMICOLON_DUMMY()
1005
1006# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
1007
1008
1009# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
1010# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SEMICOLON_DUMMY()
1011
1012
1013#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_ARRAY
1014/*
1015 *
1016 * Array operations.
1017 *
1018 */
1019# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
1020# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
1021# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) RTASN1TMPL_SEMICOLON_DUMMY()
1022# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
1023# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) RTASN1TMPL_SEMICOLON_DUMMY()
1024# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_SEMICOLON_DUMMY()
1025# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_SEMICOLON_DUMMY()
1026# define RTASN1TMPL_BEGIN_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
1027# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
1028 RTASN1TMPL_SEMICOLON_DUMMY()
1029# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
1030 RTASN1TMPL_SEMICOLON_DUMMY()
1031# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
1032
1033# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
1034 RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Erase)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, uint32_t iPosition) \
1035 { \
1036 /* Check and adjust iPosition. */ \
1037 uint32_t const cItems = pThis->cItems; \
1038 if (iPosition < cItems) \
1039 { /* likely */ } \
1040 else \
1041 { \
1042 AssertReturn(iPosition == UINT32_MAX, VERR_OUT_OF_RANGE); \
1043 AssertReturn(cItems > 0, VERR_OUT_OF_RANGE); \
1044 iPosition = cItems - 1; \
1045 } \
1046 \
1047 /* Delete the entry instance. */ \
1048 RT_CONCAT(P, a_ItemType) pErased = pThis->papItems[iPosition]; \
1049 if (RT_CONCAT(a_ItemApi,_IsPresent)(pErased)) \
1050 RT_CONCAT(a_ItemApi,_Delete)(pErased); \
1051 \
1052 /* If not the final entry, shift the other entries up and place the erased on at the end. */ \
1053 if (iPosition < cItems - 1) \
1054 { \
1055 memmove(&pThis->papItems[iPosition], &pThis->papItems[iPosition + 1], (cItems - iPosition - 1) * sizeof(void *)); \
1056 pThis->papItems[cItems - 1] = pErased; \
1057 } \
1058 /* Commit the new array size. */ \
1059 pThis->cItems = cItems - 1; \
1060 \
1061 /* Call the allocator to resize the array (ignore return). */ \
1062 RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, cItems - 1, cItems); \
1063 return VINF_SUCCESS; \
1064 } \
1065 \
1066 RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_InsertEx)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, uint32_t iPosition, \
1067 RT_CONCAT(PC, a_ItemType) pToClone, \
1068 PCRTASN1ALLOCATORVTABLE pAllocator, uint32_t *piActualPos) \
1069 { \
1070 /* Check and adjust iPosition. */ \
1071 uint32_t const cItems = pThis->cItems; \
1072 if (iPosition <= cItems) \
1073 { /* likely */ } \
1074 else \
1075 { \
1076 AssertReturn(iPosition == UINT32_MAX, VERR_OUT_OF_RANGE); \
1077 iPosition = cItems; \
1078 } \
1079 \
1080 /* Ensure we've got space in the array. */ \
1081 int rc = RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, cItems, cItems + 1); \
1082 if (RT_SUCCESS(rc)) \
1083 { \
1084 /* Initialize the new entry (which is currently at the end of the array) either with defaults or as a clone. */ \
1085 RT_CONCAT(P,a_ItemType) pInserted = pThis->papItems[cItems]; \
1086 if (RT_CONCAT(a_ItemApi,_IsPresent)(pToClone)) \
1087 rc = RT_CONCAT(a_ItemApi,_Clone)(pInserted, pToClone, pAllocator); \
1088 else \
1089 rc = RT_CONCAT(a_ItemApi,_Init)(pInserted, pAllocator); \
1090 if (RT_SUCCESS(rc)) \
1091 { \
1092 pThis->cItems = cItems + 1; \
1093 \
1094 /* If not inserting at the end of the array, shift existing items out of the way and insert the new as req. */ \
1095 if (iPosition != cItems) \
1096 { \
1097 memmove(&pThis->papItems[iPosition + 1], &pThis->papItems[iPosition], (cItems - iPosition) * sizeof(void *)); \
1098 pThis->papItems[iPosition] = pInserted; \
1099 } \
1100 \
1101 /* Done! */ \
1102 if (piActualPos) \
1103 *piActualPos = iPosition; \
1104 return VINF_SUCCESS; \
1105 } \
1106 RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, cItems + 1, cItems); \
1107 } \
1108 return rc; \
1109 } RTASN1TMPL_SEMICOLON_DUMMY()
1110
1111# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1112# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1113
1114
1115#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_COMPARE
1116/*
1117 *
1118 * Compare two instances of the type.
1119 *
1120 */
1121# define RTASN1TMPL_BEGIN_COMMON() \
1122RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Compare)(RT_CONCAT(PC,RTASN1TMPL_TYPE) pLeft, \
1123 RT_CONCAT(PC,RTASN1TMPL_TYPE) pRight) \
1124{ \
1125 if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pLeft)) \
1126 return 0 - (int)RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pRight); \
1127 if (!RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pRight)) \
1128 return -1; \
1129 int iDiff = 0
1130
1131# define RTASN1TMPL_END_COMMON() \
1132 return iDiff; \
1133} RTASN1TMPL_SEMICOLON_DUMMY()
1134
1135# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
1136# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
1137# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
1138 if (!iDiff) \
1139 iDiff = RT_CONCAT(a_Api,_Compare)(&pLeft->a_Name, &pRight->a_Name)
1140# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
1141 if (!iDiff && pLeft->a_enmMembNm != pRight->a_enmMembNm) \
1142 iDiff = pLeft->a_enmMembNm < pRight->a_enmMembNm ? -1 : 1; \
1143 else if (!iDiff) \
1144 switch (pLeft->a_enmMembNm) \
1145 { \
1146 default: break
1147# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
1148 case a_enmValue: iDiff = RT_CONCAT(a_Api,_Compare)(pLeft->a_UnionNm.a_PtrName, pRight->a_UnionNm.a_PtrName); break
1149# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
1150 case RT_CONCAT(a_enmType,_NOT_PRESENT): break; \
1151 }
1152# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
1153 if (!iDiff) \
1154 { \
1155 if (RTASN1CORE_IS_PRESENT(&pLeft->a_TnNm.a_CtxTagN.Asn1Core)) \
1156 { \
1157 if (RTASN1CORE_IS_PRESENT(&pRight->a_TnNm.a_CtxTagN.Asn1Core)) \
1158 iDiff = RT_CONCAT(a_Api,_Compare)(&pLeft->a_TnNm.a_Name, &pRight->a_TnNm.a_Name); \
1159 else \
1160 iDiff = -1; \
1161 } \
1162 else \
1163 iDiff = 0 - (int)RTASN1CORE_IS_PRESENT(&pRight->a_TnNm.a_CtxTagN.Asn1Core); \
1164 } do { } while (0)
1165# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
1166# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
1167
1168# define RTASN1TMPL_BEGIN_PCHOICE() \
1169 RTASN1TMPL_BEGIN_COMMON(); \
1170 if (pLeft->enmChoice != pRight->enmChoice) \
1171 return pLeft->enmChoice < pRight->enmChoice ? -1 : 1; \
1172 switch (pLeft->enmChoice) \
1173 { \
1174 default: break
1175# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
1176 case a_enmChoice: iDiff = RT_CONCAT(a_Api,_Compare)(pLeft->a_PtrName, pRight->a_PtrName); break
1177# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
1178 case a_enmChoice: iDiff = RT_CONCAT(a_Api,_Compare)(&pLeft->a_PtrTnNm->a_Name, &pRight->a_PtrTnNm->a_Name); break
1179#define RTASN1TMPL_END_PCHOICE() \
1180 } \
1181 RTASN1TMPL_END_COMMON()
1182
1183
1184# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
1185 RTASN1TMPL_BEGIN_COMMON(); \
1186 uint32_t cItems = pLeft->cItems; \
1187 if (cItems == pRight->cItems) \
1188 for (uint32_t i = 0; iDiff == 0 && i < cItems; i++) \
1189 iDiff = RT_CONCAT(a_ItemApi,_Compare)(pLeft->papItems[i], pRight->papItems[i]); \
1190 else \
1191 iDiff = cItems < pRight->cItems ? -1 : 1; \
1192 RTASN1TMPL_END_COMMON()
1193# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1194# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1195
1196
1197
1198#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_CHECK_SANITY
1199/*
1200 *
1201 * Checks the sanity of the type.
1202 *
1203 */
1204# ifndef RTASN1TMPL_SANITY_CHECK_EXPR
1205# define RTASN1TMPL_SANITY_CHECK_EXPR() VINF_SUCCESS
1206# endif
1207# define RTASN1TMPL_BEGIN_COMMON() \
1208RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_CheckSanity)(RT_CONCAT(PC,RTASN1TMPL_TYPE) pThis, uint32_t fFlags, \
1209 PRTERRINFO pErrInfo, const char *pszErrorTag) \
1210{ \
1211 if (RT_LIKELY(RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis))) \
1212 { /* likely */ } \
1213 else \
1214 return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s: Missing (%s).", pszErrorTag, RT_XSTR(RTASN1TMPL_TYPE)); \
1215 int rc = VINF_SUCCESS
1216
1217# define RTASN1TMPL_END_COMMON() \
1218 if (RT_SUCCESS(rc)) \
1219 rc = (RTASN1TMPL_SANITY_CHECK_EXPR()); \
1220 return rc; \
1221} RTASN1TMPL_SEMICOLON_DUMMY()
1222
1223# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
1224# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
1225# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) \
1226 if (RT_SUCCESS(rc)) \
1227 { \
1228 if (RT_LIKELY(RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name))) \
1229 { \
1230 rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
1231 pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
1232 { a_Constraints } \
1233 } \
1234 else \
1235 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s: Missing member %s (%s).", \
1236 pszErrorTag, #a_Name, RT_XSTR(RTASN1TMPL_TYPE)); \
1237 } do {} while (0)
1238# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
1239 if (RT_SUCCESS(rc)) \
1240 switch (pThis->a_enmMembNm) \
1241 { \
1242 default: \
1243 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1244 "%s: Invalid " #a_enmMembNm " value: %d", pszErrorTag, pThis->a_enmMembNm); \
1245 break
1246# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
1247 case a_enmValue: \
1248 rc = RT_CONCAT(a_Api,_CheckSanity)(pThis->a_UnionNm.a_PtrName, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
1249 pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_UnionNm "." #a_PtrName); \
1250 break
1251# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
1252 case RT_CONCAT(a_enmType,_NOT_PRESENT): \
1253 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1254 "%s: Invalid " #a_enmMembNm " value: " #a_enmType "_NOT_PRESENT", pszErrorTag); \
1255 break; \
1256 }
1257# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
1258 if (RT_SUCCESS(rc) && RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name)) \
1259 { \
1260 rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
1261 pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
1262 { a_Constraints } \
1263 }
1264# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
1265 if (RT_SUCCESS(rc)) \
1266 { \
1267 bool const fOuterPresent = RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core); \
1268 bool const fInnerPresent = RT_CONCAT(a_Api,_IsPresent)(&pThis->a_TnNm.a_Name); \
1269 if (fOuterPresent && fInnerPresent) \
1270 { \
1271 rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_TnNm.a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
1272 pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
1273 { a_Constraints } \
1274 } \
1275 else if (RT_LIKELY(RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core) == fInnerPresent)) \
1276 { /* likely */ } \
1277 else \
1278 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1279 "%s::" #a_TnNm "." #a_Name ": Explict tag precense mixup; " #a_CtxTagN "=%d " #a_Name "=%d.", \
1280 pszErrorTag, fOuterPresent, fInnerPresent); \
1281 } do { } while (0)
1282# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
1283# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
1284
1285
1286# define RTASN1TMPL_BEGIN_PCHOICE() \
1287 RTASN1TMPL_BEGIN_COMMON(); \
1288 switch (pThis->enmChoice) \
1289 { \
1290 default: \
1291 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1292 "%s: Invalid enmChoice value: %d", pszErrorTag, pThis->enmChoice); \
1293 break
1294# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
1295 case a_enmChoice: \
1296 if (pThis->a_PtrName && RT_CONCAT(a_Api,_IsPresent)(pThis->a_PtrName)) \
1297 { \
1298 PCRTASN1CORE pCore = RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName); \
1299 if (pCore->uTag == a_uTag && pCore->fClass == RTASN1TMPL_ITAG_F_EXPAND(a_fClue)) \
1300 { \
1301 rc = RT_CONCAT(a_Api,_CheckSanity)(pThis->a_PtrName, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
1302 pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
1303 { a_Constraints } \
1304 } \
1305 else \
1306 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1307 "%s::" #a_Name ": Tag/class mismatch: expected %#x/%#x, actual %#x/%x.", \
1308 pszErrorTag, a_uTag, RTASN1TMPL_ITAG_F_EXPAND(a_fClue), pCore->uTag, pCore->fClass); \
1309 } \
1310 else \
1311 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Not present.", pszErrorTag); \
1312 break
1313# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
1314 case a_enmChoice: \
1315 if ( pThis->a_PtrTnNm \
1316 && RTASN1CORE_IS_PRESENT(&(pThis->a_PtrTnNm->a_CtxTagN.Asn1Core)) \
1317 && RT_CONCAT(a_Api,_IsPresent)(&pThis->a_PtrTnNm->a_Name) ) \
1318 { \
1319 rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_PtrTnNm->a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
1320 pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
1321 { a_Constraints } \
1322 } \
1323 else \
1324 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Not present.", pszErrorTag); \
1325 break
1326#define RTASN1TMPL_END_PCHOICE() \
1327 } \
1328 RTASN1TMPL_END_COMMON()
1329
1330
1331# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
1332 RTASN1TMPL_BEGIN_COMMON(); \
1333 for (uint32_t i = 0; RT_SUCCESS(rc) && i < pThis->cItems; i++) \
1334 rc = RT_CONCAT(a_ItemApi,_CheckSanity)(pThis->papItems[i], fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
1335 pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::papItems[#]"); \
1336 if (RT_SUCCESS(rc)) { RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY(); } \
1337 RTASN1TMPL_END_COMMON()
1338# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1339# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1340
1341/* The constraints. */
1342# define RTASN1TMPL_MEMBER_CONSTR_MIN_MAX(a_Name, a_Type, a_Api, cbMin, cbMax, a_MoreConstraints) \
1343 if (RT_SUCCESS(rc) && ((cbMin) != 0 || (cbMax) != UINT32_MAX)) \
1344 { \
1345 PCRTASN1CORE pCore = RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_Name); \
1346 if (RT_LIKELY(pCore->cb >= (cbMin) && pCore->cb <= (cbMax))) \
1347 { /* likely */ } \
1348 else \
1349 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1350 "%s::" #a_Name ": Content size is out of range: %#x not in {%#x..%#x}", \
1351 pszErrorTag, pCore->cb, cbMin, cbMax); \
1352 } \
1353 { a_MoreConstraints }
1354
1355# define RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, cMinBits, cMaxBits, a_MoreConstraints) \
1356 if (RT_SUCCESS(rc) && ((cMinBits) != 0 || (cMaxBits) != UINT32_MAX)) \
1357 { \
1358 if (RT_LIKELY( ((cMinBits) == 0 ? true : pThis->a_Name.cBits + 1U >= (cMinBits) + 1U /* warning avoiding */) \
1359 && ((cMaxBits) == UINT32_MAX ? true : pThis->a_Name.cBits + 1U <= (cMaxBits) + 1U /* ditto */) ) ) \
1360 { /* likely */ } \
1361 else \
1362 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1363 "%s::" #a_Name ": Bit size is out of range: %#x not in {%#x..%#x}", \
1364 pszErrorTag, pThis->a_Name.cBits, cMinBits, cMaxBits); \
1365 } \
1366 { a_MoreConstraints }
1367
1368# define RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX(a_Name, uMin, uMax, a_MoreConstraints) \
1369 if (RT_SUCCESS(rc)) \
1370 { \
1371 if (RT_LIKELY( RTAsn1Integer_UnsignedCompareWithU64(&pThis->a_Name, uMin) >= 0 \
1372 && RTAsn1Integer_UnsignedCompareWithU64(&pThis->a_Name, uMax) <= 0) ) \
1373 { /* likely */ } \
1374 else \
1375 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
1376 "%s::" #a_Name ": Out of range: %#x not in {%#llx..%#llx}", \
1377 pszErrorTag, pThis->a_Name.Asn1Core.cb > 8 ? UINT64_MAX : pThis->a_Name.uValue.u, \
1378 (uint64_t)(uMin), (uint64_t)(uMax)); \
1379 } \
1380 { a_MoreConstraints }
1381
1382# define RTASN1TMPL_MEMBER_CONSTR_PRESENT(a_Name, a_Api, a_MoreConstraints) \
1383 if (RT_SUCCESS(rc)) \
1384 { \
1385 if (RT_LIKELY(RT_CONCAT(a_Api,_IsPresent)(&pThis->a_Name))) \
1386 { /* likely */ } \
1387 else \
1388 rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, "%s::" #a_Name ": Missing.", pszErrorTag); \
1389 } \
1390 { a_MoreConstraints }
1391
1392
1393
1394# define RTASN1TMPL_EXEC_CHECK_SANITY(a_Expr) if (RT_SUCCESS(rc)) { a_Expr; }
1395
1396
1397#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_DELETE
1398/*
1399 *
1400 * Delete wrappers.
1401 *
1402 */
1403# define RTASN1TMPL_BEGIN_COMMON() \
1404RTASN1TMPL_DECL(void) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Delete)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis) \
1405{ \
1406 if (RT_CONCAT(RTASN1TMPL_EXT_NAME,_IsPresent)(pThis)) \
1407 { do { } while (0)
1408
1409# define RTASN1TMPL_END_COMMON() \
1410 } \
1411 RT_ZERO(*pThis); \
1412} RTASN1TMPL_SEMICOLON_DUMMY()
1413
1414# define RTASN1TMPL_BEGIN_SEQCORE() RTASN1TMPL_BEGIN_COMMON()
1415# define RTASN1TMPL_BEGIN_SETCORE() RTASN1TMPL_BEGIN_COMMON()
1416# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints) RT_CONCAT(a_Api,_Delete)(&pThis->a_Name)
1417# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
1418 switch (pThis->a_enmMembNm) \
1419 { \
1420 default: break
1421# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
1422 case a_enmValue: \
1423 if (pThis->a_UnionNm.a_PtrName) \
1424 { \
1425 RT_CONCAT(a_Api,_Delete)(pThis->a_UnionNm.a_PtrName); \
1426 RTAsn1MemFree(&pThis->Allocation, pThis->a_UnionNm.a_PtrName); \
1427 pThis->a_UnionNm.a_PtrName = NULL; \
1428 } \
1429 break
1430# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) \
1431 }
1432# define RTASN1TMPL_END_SEQCORE() RTASN1TMPL_END_COMMON()
1433# define RTASN1TMPL_END_SETCORE() RTASN1TMPL_END_COMMON()
1434
1435
1436# define RTASN1TMPL_BEGIN_PCHOICE() \
1437 RTASN1TMPL_BEGIN_COMMON(); \
1438 switch (pThis->enmChoice) \
1439 { \
1440 default: break
1441# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
1442 case a_enmChoice: \
1443 if (pThis->a_PtrName) \
1444 { \
1445 RT_CONCAT(a_Api,_Delete)(pThis->a_PtrName); \
1446 RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrName); \
1447 pThis->a_PtrName = NULL; \
1448 } \
1449 break
1450# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
1451 case a_enmChoice: \
1452 if (pThis->a_PtrTnNm) \
1453 { \
1454 RT_CONCAT(a_Api,_Delete)(&pThis->a_PtrTnNm->a_Name); \
1455 RTAsn1MemFree(&pThis->Allocation, pThis->a_PtrTnNm); \
1456 pThis->a_PtrTnNm = NULL; \
1457 } \
1458 break
1459# define RTASN1TMPL_END_PCHOICE() \
1460 } \
1461 RTASN1TMPL_END_COMMON()
1462
1463
1464# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
1465 RTASN1TMPL_BEGIN_COMMON(); \
1466 uint32_t i = pThis->cItems; \
1467 while (i-- > 0) \
1468 RT_CONCAT(a_ItemApi,_Delete)(pThis->papItems[i]); \
1469 RTAsn1MemFreeArray(&pThis->Allocation, (void **)pThis->papItems); \
1470 pThis->papItems = NULL; \
1471 pThis->cItems = 0; \
1472 RTASN1TMPL_END_COMMON()
1473# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1474# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi) RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
1475
1476
1477#else
1478# error "Invalid/missing RTASN1TMPL_PASS value."
1479#endif
1480
1481
1482
1483/*
1484 * Default aliases for simplified versions of macros if no specialization
1485 * was required above.
1486 */
1487/* Non-optional members. */
1488#ifndef RTASN1TMPL_MEMBER
1489# define RTASN1TMPL_MEMBER(a_Name, a_Type, a_Api) \
1490 RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, RT_NOTHING)
1491#endif
1492
1493#ifndef RTASN1TMPL_MEMBER_UTF8_STRING_MIN_MAX
1494# define RTASN1TMPL_MEMBER_UTF8_STRING_MIN_MAX(a_Name) \
1495 RTASN1TMPL_MEMBER(a_Name, RTASN1STRING, RTAsn1String)
1496#endif
1497#ifndef RTASN1TMPL_MEMBER_UTF8_STRING
1498# define RTASN1TMPL_MEMBER_UTF8_STRING(a_Name) \
1499 RTASN1TMPL_MEMBER_UTF8_STRING_MIN_MAX(a_Name, 0, UINT32_MAX)
1500#endif
1501
1502#ifndef RTASN1TMPL_MEMBER_STRING_MIN_MAX
1503# define RTASN1TMPL_MEMBER_STRING_MIN_MAX(a_Name, a_cbMin, a_cbMax) \
1504 RTASN1TMPL_MEMBER(a_Name, RTASN1STRING, RTAsn1String)
1505#endif
1506#ifndef RTASN1TMPL_MEMBER_STRING
1507# define RTASN1TMPL_MEMBER_STRING(a_Name) \
1508 RTASN1TMPL_MEMBER_STRING_MIN_MAX(a_Name, 0, UINT32_MAX)
1509#endif
1510#ifndef RTASN1TMPL_MEMBER_XTAG_EX
1511# define RTASN1TMPL_MEMBER_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
1512 RTASN1TMPL_MEMBER_EX(a_TnNm.a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
1513#endif
1514
1515/* Any/dynamic members. */
1516#ifndef RTASN1TMPL_MEMBER_DYN_BEGIN
1517# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) do { } while (0)
1518#endif
1519#ifndef RTASN1TMPL_MEMBER_DYN_END
1520# define RTASN1TMPL_MEMBER_DYN_END(a_ObjIdMembNm, a_enmType, a_enmMembNm, a_Allocation) do { } while (0)
1521#endif
1522#ifndef RTASN1TMPL_MEMBER_DYN_COMMON
1523# define RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, a_IfStmt) \
1524 RTASN1TMPL_MEMBER(a_UnionNm.a_PtrName, a_Type, a_Api)
1525#endif
1526#ifndef RTASN1TMPL_MEMBER_DYN
1527# define RTASN1TMPL_MEMBER_DYN(a_UnionNm, a_PtrName, a_Name, a_Type, a_Api, a_Allocation, a_ObjIdMembNm, a_enmMembNm, a_enmValue, a_szObjId) \
1528 RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, if (RTAsn1ObjId_CompareWithString(&pThis->a_ObjIdMembNm, a_szObjId) == 0))
1529#endif
1530#ifndef RTASN1TMPL_MEMBER_DYN_DEFAULT
1531# define RTASN1TMPL_MEMBER_DYN_DEFAULT(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_ObjIdMembNm, a_enmMembNm, a_enmValue) \
1532 RTASN1TMPL_MEMBER_DYN_COMMON(a_UnionNm, a_PtrName, a_Type, a_Api, a_Allocation, a_enmMembNm, a_enmValue, RT_NOTHING)
1533#endif
1534
1535/* Optional members. */
1536#ifndef RTASN1TMPL_MEMBER_OPT_EX
1537# define RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints) \
1538 RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
1539#endif
1540#ifndef RTASN1TMPL_MEMBER_OPT
1541# define RTASN1TMPL_MEMBER_OPT(a_Name, a_Type, a_Api) \
1542 RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, RT_NOTHING)
1543#endif
1544
1545#ifndef RTASN1TMPL_MEMBER_OPT_XTAG_EX
1546# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
1547 RTASN1TMPL_MEMBER_OPT_EX(a_TnNm.a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
1548#endif
1549#ifndef RTASN1TMPL_MEMBER_OPT_XTAG
1550# define RTASN1TMPL_MEMBER_OPT_XTAG(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag) \
1551 RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, RT_NOTHING)
1552#endif
1553
1554#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_EX
1555# define RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_Constraints) \
1556 RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, a_Constraints RT_NOTHING)
1557#endif
1558#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_UP
1559# define RTASN1TMPL_MEMBER_OPT_ITAG_UP(a_Name, a_Type, a_Api, a_uTag) \
1560 RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_UP, RT_NOTHING)
1561#endif
1562#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_UC
1563# define RTASN1TMPL_MEMBER_OPT_ITAG_UC(a_Name, a_Type, a_Api, a_uTag) \
1564 RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_UC, RT_NOTHING)
1565#endif
1566#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_CP
1567# define RTASN1TMPL_MEMBER_OPT_ITAG_CP(a_Name, a_Type, a_Api, a_uTag) \
1568 RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_CP, RT_NOTHING)
1569#endif
1570#ifndef RTASN1TMPL_MEMBER_OPT_ITAG
1571# define RTASN1TMPL_MEMBER_OPT_ITAG(a_Name, a_Type, a_Api, a_uTag) \
1572 RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_CC, RT_NOTHING)
1573#endif
1574#ifndef RTASN1TMPL_MEMBER_OPT_ANY
1575# define RTASN1TMPL_MEMBER_OPT_ANY(a_Name, a_Type, a_Api) \
1576 RTASN1TMPL_MEMBER_OPT_EX(a_Name, a_Type, a_Api, RT_NOTHING)
1577#endif
1578
1579#ifndef RTASN1TMPL_MEMBER_DEF_ITAG_EX
1580# define RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_DefVal, a_Constraints) \
1581 RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, a_fClue, a_Constraints RT_NOTHING)
1582#endif
1583#ifndef RTASN1TMPL_MEMBER_DEF_ITAG_UP
1584# define RTASN1TMPL_MEMBER_DEF_ITAG_UP(a_Name, a_Type, a_Api, a_uTag, a_DefVal) \
1585 RTASN1TMPL_MEMBER_DEF_ITAG_EX(a_Name, a_Type, a_Api, a_uTag, RTASN1TMPL_ITAG_F_UP, a_DefVal, RT_NOTHING)
1586#endif
1587
1588#ifndef RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING
1589# define RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING(a_Name, a_cMaxBits, a_uTag) \
1590 RTASN1TMPL_MEMBER_OPT_ITAG_EX(a_Name, RTASN1BITSTRING, RTAsn1BitString, a_uTag, RTASN1TMPL_ITAG_F_CP, \
1591 RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, 0, a_cMaxBits, RT_NOTHING))
1592#endif
1593
1594#ifndef RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX
1595# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, a_Constraints) \
1596 RTASN1TMPL_MEMBER_OPT_EX(a_Name, RTASN1STRING, RTAsn1String, a_Constraints RT_NOTHING)
1597#endif
1598#ifndef RTASN1TMPL_MEMBER_OPT_UTF8_STRING
1599# define RTASN1TMPL_MEMBER_OPT_UTF8_STRING(a_Name) \
1600 RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX(a_Name, RT_NOTHING)
1601#endif
1602
1603#ifndef RTASN1TMPL_MEMBER_OPT_STRING_EX
1604# define RTASN1TMPL_MEMBER_OPT_STRING_EX(a_Name, a_Constraints) \
1605 RTASN1TMPL_MEMBER_OPT_EX(a_Name, RTASN1STRING, RTAsn1String, a_Constraints RT_NOTHING)
1606#endif
1607#ifndef RTASN1TMPL_MEMBER_OPT_STRING
1608# define RTASN1TMPL_MEMBER_OPT_STRING(a_Name) \
1609 RTASN1TMPL_MEMBER_OPT_STRING_EX(a_Name, RT_NOTHING)
1610#endif
1611
1612/* Pointer choices. */
1613#ifndef RTASN1TMPL_PCHOICE_ITAG_UP
1614# define RTASN1TMPL_PCHOICE_ITAG_UP(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
1615 RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_UP, RT_NOTHING)
1616#endif
1617#ifndef RTASN1TMPL_PCHOICE_ITAG_UC
1618# define RTASN1TMPL_PCHOICE_ITAG_UC(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
1619 RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_UC, RT_NOTHING)
1620#endif
1621#ifndef RTASN1TMPL_PCHOICE_ITAG_CP
1622# define RTASN1TMPL_PCHOICE_ITAG_CP(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
1623 RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_CP, RT_NOTHING)
1624#endif
1625#ifndef RTASN1TMPL_PCHOICE_ITAG
1626# define RTASN1TMPL_PCHOICE_ITAG(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api) \
1627 RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, RTASN1TMPL_ITAG_F_CC, RT_NOTHING)
1628#endif
1629
1630#ifndef RTASN1TMPL_PCHOICE_XTAG
1631# define RTASN1TMPL_PCHOICE_XTAG(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api) \
1632 RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, RT_NOTHING)
1633#endif
1634
1635
1636/*
1637 * Constraints are only used in the sanity check pass, so provide subs for the
1638 * others passes.
1639 */
1640#ifndef RTASN1TMPL_MEMBER_CONSTR_MIN_MAX
1641# define RTASN1TMPL_MEMBER_CONSTR_MIN_MAX(a_Name, a_Type, a_Api, cbMin, cbMax, a_MoreConstraints)
1642#endif
1643#ifndef RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX
1644# define RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX(a_Name, cMinBits, cMaxBits, a_MoreConstraints)
1645#endif
1646#ifndef RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX
1647# define RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX(a_Name, uMin, uMax, a_MoreConstraints)
1648#endif
1649#ifndef RTASN1TMPL_MEMBER_CONSTR_PRESENT
1650# define RTASN1TMPL_MEMBER_CONSTR_PRESENT(a_Name, a_Api, a_MoreConstraints)
1651#endif
1652
1653
1654/*
1655 * Stub exec hacks.
1656 */
1657#ifndef RTASN1TMPL_EXEC_DECODE
1658# define RTASN1TMPL_EXEC_DECODE(a_Expr) /* no semi colon allowed after this */
1659#endif
1660#ifndef RTASN1TMPL_EXEC_CLONE
1661# define RTASN1TMPL_EXEC_CLONE(a_Expr) /* no semi colon allowed after this */
1662#endif
1663#ifndef RTASN1TMPL_EXEC_CHECK_SANITY
1664# define RTASN1TMPL_EXEC_CHECK_SANITY(a_Expr) /* no semi colon allowed after this */
1665#endif
1666
1667#define RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY() do { } while (0)
1668
1669
1670/*
1671 * Generate the requested code.
1672 */
1673#ifndef RTASN1TMPL_TEMPLATE_FILE
1674# error "No template file (RTASN1TMPL_TEMPLATE_FILE) is specified."
1675#endif
1676#include RTASN1TMPL_TEMPLATE_FILE
1677
1678
1679
1680/*
1681 * Undo all the macros.
1682 */
1683#undef RTASN1TMPL_DECL
1684#undef RTASN1TMPL_TYPE
1685#undef RTASN1TMPL_EXT_NAME
1686#undef RTASN1TMPL_INT_NAME
1687
1688#undef RTASN1TMPL_PASS
1689
1690#undef RTASN1TMPL_BEGIN_COMMON
1691#undef RTASN1TMPL_END_COMMON
1692#undef RTASN1TMPL_BEGIN_SEQCORE
1693#undef RTASN1TMPL_BEGIN_SETCORE
1694#undef RTASN1TMPL_MEMBER
1695#undef RTASN1TMPL_MEMBER_EX
1696#undef RTASN1TMPL_MEMBER_DYN_BEGIN
1697#undef RTASN1TMPL_MEMBER_DYN
1698#undef RTASN1TMPL_MEMBER_DYN_DEFAULT
1699#undef RTASN1TMPL_MEMBER_DYN_COMMON
1700#undef RTASN1TMPL_MEMBER_DYN_END
1701#undef RTASN1TMPL_MEMBER_OPT
1702#undef RTASN1TMPL_MEMBER_OPT_EX
1703#undef RTASN1TMPL_MEMBER_OPT_ITAG
1704#undef RTASN1TMPL_MEMBER_OPT_ITAG_EX
1705#undef RTASN1TMPL_MEMBER_OPT_ITAG_CP
1706#undef RTASN1TMPL_MEMBER_OPT_ITAG_UC
1707#undef RTASN1TMPL_MEMBER_OPT_ITAG_UP
1708#undef RTASN1TMPL_MEMBER_OPT_ITAG_BITSTRING
1709#undef RTASN1TMPL_MEMBER_OPT_UTF8_STRING
1710#undef RTASN1TMPL_MEMBER_OPT_UTF8_STRING_EX
1711#undef RTASN1TMPL_MEMBER_OPT_XTAG
1712#undef RTASN1TMPL_MEMBER_OPT_XTAG_EX
1713#undef RTASN1TMPL_MEMBER_OPT_ANY
1714#undef RTASN1TMPL_MEMBER_DEF_ITAG_UP
1715#undef RTASN1TMPL_MEMBER_DEF_ITAG_EX
1716#undef RTASN1TMPL_END_SEQCORE
1717#undef RTASN1TMPL_END_SETCORE
1718
1719#undef RTASN1TMPL_BEGIN_PCHOICE
1720#undef RTASN1TMPL_PCHOICE_ITAG
1721#undef RTASN1TMPL_PCHOICE_ITAG_UP
1722#undef RTASN1TMPL_PCHOICE_ITAG_CP
1723#undef RTASN1TMPL_PCHOICE_ITAG_EX
1724#undef RTASN1TMPL_PCHOICE_XTAG
1725#undef RTASN1TMPL_PCHOICE_XTAG_EX
1726#undef RTASN1TMPL_END_PCHOICE
1727
1728#undef RTASN1TMPL_SET_SEQ_OF_COMMON
1729#undef RTASN1TMPL_SEQ_OF
1730#undef RTASN1TMPL_SET_OF
1731
1732#undef RTASN1TMPL_VTABLE_FN_ENCODE_PREP
1733#undef RTASN1TMPL_VTABLE_FN_ENCODE_WRITE
1734
1735#undef RTASN1TMPL_MEMBER_CONSTR_MIN_MAX
1736#undef RTASN1TMPL_MEMBER_CONSTR_BITSTRING_MIN_MAX
1737#undef RTASN1TMPL_MEMBER_CONSTR_U64_MIN_MAX
1738#undef RTASN1TMPL_MEMBER_CONSTR_PRESENT
1739
1740#undef RTASN1TMPL_SANITY_CHECK_EXPR
1741
1742#undef RTASN1TMPL_EXEC_DECODE
1743#undef RTASN1TMPL_EXEC_CLONE
1744#undef RTASN1TMPL_EXEC_CHECK_SANITY
1745
1746#undef RTASN1TMPL_SET_SEQ_EXEC_CHECK_SANITY
1747
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette