VirtualBox

Changeset 59665 in vbox for trunk/include/iprt


Ignore:
Timestamp:
Feb 14, 2016 11:57:30 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
105522
Message:

iprt/asn1: Fixed bug represnation of explicit tags that caused trouble doing encoding by piggypacking on the enumeration method. Added simple X.509 testcase.

Location:
trunk/include/iprt
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asn1-generator-core.h

    r56291 r59665  
    2828#include <iprt/string.h>
    2929
     30#define RTASN1TMPL_PASS                 RTASN1TMPL_PASS_XTAG
     31#include <iprt/asn1-generator-pass.h>
    3032#define RTASN1TMPL_PASS                 RTASN1TMPL_PASS_VTABLE
    3133#include <iprt/asn1-generator-pass.h>
  • trunk/include/iprt/asn1-generator-pass.h

    r57004 r59665  
    6666#define RTASN1TMPL_PASS_INTERNAL_HEADER 1
    6767
    68 #define RTASN1TMPL_PASS_VTABLE          2
    69 #define RTASN1TMPL_PASS_ENUM            3
    70 #define RTASN1TMPL_PASS_DELETE          4
    71 #define RTASN1TMPL_PASS_COMPARE         5
     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
    7273
    7374#define RTASN1TMPL_PASS_CHECK_SANITY    8
     
    112113# define RTASN1TMPL_BEGIN_SETCORE()                 RTASN1TMPL_BEGIN_COMMON()
    113114# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)                                 RTASN1TMPL_SEMICOLON_DUMMY()
     115# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
     116    extern "C" DECLHIDDEN(RTASN1COREVTABLE const)   RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Vtable)
     117
    114118# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)                          RTASN1TMPL_SEMICOLON_DUMMY()
    115119# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                            RTASN1TMPL_SEMICOLON_DUMMY()
     
    122126                                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
    123127# 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()
     128    extern "C" DECLHIDDEN(RTASN1COREVTABLE const)   RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable)
     129
    125130# define RTASN1TMPL_END_PCHOICE()                   RTASN1TMPL_SEMICOLON_DUMMY()
    126131
     
    128133# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_BEGIN_COMMON()
    129134# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_BEGIN_COMMON()
     135
     136
     137
     138#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_XTAG
     139/*
     140 *
     141 * Generate a vtable and associated methods for explicitly tagged items (XTAG).
     142 *
     143 * These turned out to be a little problematic during encoding since there are
     144 * two tags, the first encapsulating the second, thus the enumeration has to be
     145 * nested or we cannot calculate the size of the first tag.
     146 *
     147 *
     148 */
     149# define RTASN1TMPL_BEGIN_COMMON()                                                                  RTASN1TMPL_SEMICOLON_DUMMY()
     150# define RTASN1TMPL_BEGIN_SEQCORE()                                                                 RTASN1TMPL_SEMICOLON_DUMMY()
     151# define RTASN1TMPL_BEGIN_SETCORE()                                                                 RTASN1TMPL_SEMICOLON_DUMMY()
     152# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)                                 RTASN1TMPL_SEMICOLON_DUMMY()
     153# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)                          RTASN1TMPL_SEMICOLON_DUMMY()
     154# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                            RTASN1TMPL_SEMICOLON_DUMMY()
     155# define RTASN1TMPL_MEMBER_OPT_XTAG_EX(a_TnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_uTag, a_Constraints) \
     156    /* This is the method we need to make it work. */ \
     157    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Enum)(PRTASN1CORE pThisCore, \
     158                                                                                 PFNRTASN1ENUMCALLBACK pfnCallback, \
     159                                                                                 uint32_t uDepth, void *pvUser) \
     160    { \
     161        RTASN1TMPL_TYPE *pThis = RT_FROM_MEMBER(pThisCore, RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
     162        if (RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core)) \
     163            return pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&pThis->a_TnNm.a_Name), #a_TnNm "." #a_Name, uDepth + 1, pvUser); \
     164        return VINF_SUCCESS; \
     165    } \
     166    /* The delete method shouldn't normally be used. */ \
     167    static DECLCALLBACK(void) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Delete)(PRTASN1CORE pThisCore) \
     168    { \
     169        RTASN1TMPL_TYPE *pThis = RT_FROM_MEMBER(pThisCore, RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
     170        RT_CONCAT(a_Api,_Delete)(&pThis->a_TnNm.a_Name); \
     171    } \
     172    /* The clone method shouldn't normally be used. */ \
     173    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Clone)(PRTASN1CORE pThisCore, PCRTASN1CORE pSrcCore, \
     174                                                                                  PCRTASN1ALLOCATORVTABLE pAllocator) \
     175    {\
     176        RTASN1TMPL_TYPE *pThis = RT_FROM_MEMBER(pThisCore, RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
     177        RTASN1TMPL_TYPE *pSrc  = RT_FROM_MEMBER(pSrcCore,  RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
     178        int              rc    = VINF_SUCCESS; \
     179        if (RTASN1CORE_IS_PRESENT(&pSrc->a_TnNm.a_CtxTagN.Asn1Core)) \
     180        { \
     181            rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Clone)(&pThis->a_TnNm.a_CtxTagN, &pSrc->a_TnNm.a_CtxTagN); \
     182            if (RT_SUCCESS(rc)) \
     183                rc = RT_CONCAT(a_Api,_Clone)(&pThis->a_TnNm.a_Name, &pSrc->a_TnNm.a_Name, pAllocator); \
     184        } \
     185        return rc; \
     186    } \
     187    /* The compare method shouldn't normally be used. */ \
     188    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Compare)(PCRTASN1CORE pLeftCore, \
     189                                                                                    PCRTASN1CORE pRightCore) \
     190    { \
     191        RTASN1TMPL_TYPE *pLeft  = RT_FROM_MEMBER(pLeftCore,  RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
     192        RTASN1TMPL_TYPE *pRight = RT_FROM_MEMBER(pRightCore, RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
     193        if (RTASN1CORE_IS_PRESENT(&pLeft->a_TnNm.a_CtxTagN.Asn1Core)) \
     194        { \
     195            if (RTASN1CORE_IS_PRESENT(&pRight->a_TnNm.a_CtxTagN.Asn1Core)) \
     196                return RT_CONCAT(a_Api,_Compare)(&pLeft->a_TnNm.a_Name, &pRight->a_TnNm.a_Name); \
     197            return -1; \
     198        } \
     199        return 0 - (int)RTASN1CORE_IS_PRESENT(&pRight->a_TnNm.a_CtxTagN.Asn1Core); \
     200    } \
     201    /* The sanity check method shouldn't normally be used. */ \
     202    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_CheckSanity)(PCRTASN1CORE pThisCore, uint32_t fFlags, \
     203                                                                                        PRTERRINFO pErrInfo, const char *pszErrorTag) \
     204    { \
     205        RTASN1TMPL_TYPE *pThis = RT_FROM_MEMBER(pThisCore, RTASN1TMPL_TYPE, a_TnNm.a_CtxTagN); \
     206        bool const fOuterPresent = RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core); \
     207        bool const fInnerPresent = RT_CONCAT(a_Api,_IsPresent)(&pThis->a_TnNm.a_Name); \
     208        int rc; \
     209        if (fOuterPresent && fInnerPresent) \
     210        { \
     211            rc = RT_CONCAT(a_Api,_CheckSanity)(&pThis->a_TnNm.a_Name, fFlags & RTASN1_CHECK_SANITY_F_COMMON_MASK, \
     212                                               pErrInfo, RT_XSTR(RTASN1TMPL_TYPE) "::" #a_Name); \
     213            { a_Constraints } \
     214        } \
     215        else if (RT_LIKELY(RTASN1CORE_IS_PRESENT(&pThis->a_TnNm.a_CtxTagN.Asn1Core) == fInnerPresent)) \
     216            rc = VINF_SUCCESS; /* Likely */ \
     217        else \
     218            rc = RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE, \
     219                               "%s::" #a_TnNm "." #a_Name ": Explict tag precense mixup; " #a_CtxTagN "=%d " #a_Name "=%d.", \
     220                               pszErrorTag, fOuterPresent, fInnerPresent); \
     221        return rc; \
     222    } \
     223    DECL_HIDDEN_CONST(RTASN1COREVTABLE const) RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Vtable) = \
     224    { \
     225        /* When the Asn1Core is at the start of the structure, we can reuse the _Delete and _Enum APIs here. */ \
     226        /* .pszName = */        RT_XSTR(RTASN1TMPL_INT_NAME) "_XTAG_" RT_XSTR(a_Name), \
     227        /* .cb = */             RT_SIZEOFMEMB(RTASN1TMPL_TYPE, a_TnNm), \
     228        /* .uDefaultTag = */    a_uTag, \
     229        /* .fDefaultClass = */  ASN1_TAGCLASS_CONTEXT, \
     230        /* .uReserved = */      0, \
     231        RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Delete), \
     232        RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Enum), \
     233        RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Clone), \
     234        RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Compare), \
     235        RT_CONCAT4(RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_CheckSanity), \
     236        /*.pfnEncodePrep */ NULL, \
     237        /*.pfnEncodeWrite */ NULL \
     238    }
     239
     240
     241# define RTASN1TMPL_END_SEQCORE()                                                                   RTASN1TMPL_SEMICOLON_DUMMY()
     242# define RTASN1TMPL_END_SETCORE()                                                                   RTASN1TMPL_SEMICOLON_DUMMY()
     243# define RTASN1TMPL_BEGIN_PCHOICE()                                                                 RTASN1TMPL_SEMICOLON_DUMMY()
     244# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
     245                                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
     246# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
     247    /* This is the method we need to make it work. */ \
     248    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Enum)(PRTASN1CORE pThisCore, \
     249                                                                                    PFNRTASN1ENUMCALLBACK pfnCallback, \
     250                                                                                    uint32_t uDepth, void *pvUser) \
     251    { \
     252        if (RTASN1CORE_IS_PRESENT(pThisCore)) \
     253        { \
     254            /** @todo optimize this one day, possibly change the PCHOICE+XTAG representation. */ \
     255            RTASN1TMPL_TYPE Tmp; \
     256            *(PRTASN1CORE *)&Tmp.a_PtrTnNm = pThisCore; \
     257            Assert(&Tmp.a_PtrTnNm->a_CtxTagN.Asn1Core == pThisCore); \
     258            return pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(&Tmp.a_PtrTnNm->a_Name), "T" #a_uTag "." #a_Name, uDepth + 1, pvUser); \
     259        } \
     260        return VINF_SUCCESS; \
     261    } \
     262    /* The reminder of the methods shouldn't normally be needed, just stub them. */ \
     263    static DECLCALLBACK(void) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Delete)(PRTASN1CORE pThisCore) \
     264    { AssertFailed(); } \
     265    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Clone)(PRTASN1CORE pThisCore, PCRTASN1CORE pSrcCore, \
     266                                                                                     PCRTASN1ALLOCATORVTABLE pAllocator) \
     267    { AssertFailed(); return VERR_INTERNAL_ERROR_3; } \
     268    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Compare)(PCRTASN1CORE pLeftCore, \
     269                                                                                       PCRTASN1CORE pRightCore) \
     270    { AssertFailed(); return VERR_INTERNAL_ERROR_3; } \
     271    static DECLCALLBACK(int) RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_CheckSanity)(PCRTASN1CORE pThisCore, uint32_t fFlags, \
     272                                                                                           PRTERRINFO pErrInfo, const char *pszErrorTag) \
     273    { AssertFailed(); return VERR_INTERNAL_ERROR_3; } \
     274    DECL_HIDDEN_CONST(RTASN1COREVTABLE const) RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable) = \
     275    { \
     276        /* When the Asn1Core is at the start of the structure, we can reuse the _Delete and _Enum APIs here. */ \
     277        /* .pszName = */        RT_XSTR(RTASN1TMPL_INT_NAME) "_PCHOICE_XTAG_" RT_XSTR(a_Name), \
     278        /* .cb = */             sizeof(*((RTASN1TMPL_TYPE *)(void *)0)->a_PtrTnNm), \
     279        /* .uDefaultTag = */    a_uTag, \
     280        /* .fDefaultClass = */  ASN1_TAGCLASS_CONTEXT, \
     281        /* .uReserved = */      0, \
     282        RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Delete), \
     283        RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Enum), \
     284        RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Clone), \
     285        RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_Compare), \
     286        RT_CONCAT4(RTASN1TMPL_INT_NAME,_PC_XTAG_,a_Name,_CheckSanity), \
     287        /*.pfnEncodePrep */ NULL, \
     288        /*.pfnEncodeWrite */ NULL \
     289    }
     290
     291
     292
     293# define RTASN1TMPL_END_PCHOICE()                                                                   RTASN1TMPL_SEMICOLON_DUMMY()
     294# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi)                                                   RTASN1TMPL_SEMICOLON_DUMMY()
     295# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi)                                                   RTASN1TMPL_SEMICOLON_DUMMY()
    130296
    131297
     
    349515    { \
    350516        RTASN1CURSOR CtxCursor; \
    351         rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, &pThis->a_TnNm.a_CtxTagN, &CtxCursor, #a_TnNm); \
     517        rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, \
     518                                                                 &RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_XTAG_,a_Name,_Vtable), \
     519                                                                 &pThis->a_TnNm.a_CtxTagN, &CtxCursor, #a_TnNm); \
    352520        if (RT_SUCCESS(rc)) \
    353521        { \
     
    399567            { \
    400568                RTASN1CURSOR CtxCursor; \
    401                 rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, &pThis->a_PtrTnNm->a_CtxTagN, \
    402                                                                          &CtxCursor, "T" #a_uTag); \
     569                rc = RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(pCursor, 0, \
     570                                                                         &RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable), \
     571                                                                         &pThis->a_PtrTnNm->a_CtxTagN, &CtxCursor, "T" #a_uTag); \
    403572                if (RT_SUCCESS(rc)) \
    404573                    rc = RT_CONCAT(a_Api,_DecodeAsn1)(&CtxCursor, RTASN1CURSOR_GET_F_IMPLICIT, \
     
    514683        { \
    515684            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); \
    518685        } do {} while (0)
    519686# define RTASN1TMPL_END_SEQCORE()   RTASN1TMPL_END_COMMON()
     
    529696        case a_enmChoice: rc = pfnCallback(RT_CONCAT(a_Api,_GetAsn1Core)(pThis->a_PtrName), #a_PtrName, uDepth, pvUser); break
    530697# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
    531         case a_enmChoice: \
    532             rc = pfnCallback(&pThis->a_PtrTnNm->a_CtxTagN.Asn1Core, "T" #a_uTag "." #a_CtxTagN, uDepth, pvUser); \
    533             if (rc == VINF_SUCCESS) \
    534                 rc = pfnCallback(RT_CONCAT(a_Api, _GetAsn1Core)(&pThis->a_PtrTnNm->a_Name), \
    535                                  "T" #a_uTag "." #a_Name, uDepth + 1, pvUser); \
    536             break
     698        case a_enmChoice: rc = pfnCallback(&pThis->a_PtrTnNm->a_CtxTagN.Asn1Core, "T" #a_uTag "." #a_CtxTagN, uDepth, pvUser); break
    537699#define RTASN1TMPL_END_PCHOICE() \
    538700    } \
     
    775937    if (RT_SUCCESS(rc)) \
    776938    { \
    777         rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Init)(&pThis->a_PtrTnNm->a_CtxTagN, pAllocator); \
     939        rc = RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Init)(&pThis->a_PtrTnNm->a_CtxTagN, \
     940                                                       &RT_CONCAT5(g_,RTASN1TMPL_INT_NAME,_PCHOICE_XTAG_,a_Name,_Vtable), \
     941                                                       pAllocator); \
    778942        if (RT_SUCCESS(rc)) \
    779943        { \
  • trunk/include/iprt/asn1.h

    r59663 r59665  
    11921192 * making it a little more type safe, there's a set of typedefs for the most
    11931193 * commonly used tag values defined.  These typedefs have are identical to
    1194  * RTASN1CONTEXTTAG, except from the C++ type system of view.
    1195  * tag values.  These
     1194 * RTASN1CONTEXTTAG, except from the C++ type system point of view.
    11961195 */
    11971196typedef struct RTASN1CONTEXTTAG
     
    12051204typedef RTASN1CONTEXTTAG const *PCRTASN1CONTEXTTAG;
    12061205
    1207 RTDECL(int) RTAsn1ContextTagN_Init(PRTASN1CONTEXTTAG pThis, uint32_t uTag);
     1206RTDECL(int) RTAsn1ContextTagN_Init(PRTASN1CONTEXTTAG pThis, uint32_t uTag, PCRTASN1COREVTABLE pVtable);
    12081207RTDECL(int) RTAsn1ContextTagN_Clone(PRTASN1CONTEXTTAG pThis, PCRTASN1CONTEXTTAG pSrc, uint32_t uTag);
    12091208
     
    12141213    typedef RT_CONCAT(RTASN1CONTEXTTAG,a_uTag) *RT_CONCAT(PRTASN1CONTEXTTAG,a_uTag); \
    12151214    DECLINLINE(int) RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Init)(RT_CONCAT(PRTASN1CONTEXTTAG,a_uTag) pThis, \
    1216                                                               PCRTASN1ALLOCATORVTABLE pAllocator) \
     1215                                                              PCRTASN1COREVTABLE pVtable, PCRTASN1ALLOCATORVTABLE pAllocator) \
    12171216    { \
    12181217        NOREF(pAllocator); \
    1219         return RTAsn1ContextTagN_Init((PRTASN1CONTEXTTAG)pThis, a_uTag); \
     1218        return RTAsn1ContextTagN_Init((PRTASN1CONTEXTTAG)pThis, a_uTag, pVtable); \
    12201219    } \
    12211220    DECLINLINE(int) RT_CONCAT3(RTAsn1ContextTag,a_uTag,_Clone)(RT_CONCAT(PRTASN1CONTEXTTAG,a_uTag) pThis, \
     
    19371936 * @param   fFlags              RTASN1CURSOR_GET_F_XXX.
    19381937 * @param   uExpectedTag        The expected tag.
     1938 * @param   pVtable             The vtable for the context tag node (see
     1939 *                              RTASN1TMPL_PASS_XTAG).
    19391940 * @param   pCtxTag             The output context tag object.
    19401941 * @param   pCtxTagCursor       The output cursor for the context tag content.
     
    19471948 */
    19481949RTDECL(int) RTAsn1CursorGetContextTagNCursor(PRTASN1CURSOR pCursor, uint32_t fFlags, uint32_t uExpectedTag,
    1949                                              PRTASN1CONTEXTTAG pCtxTag, PRTASN1CURSOR pCtxTagCursor, const char *pszErrorTag);
     1950                                             PCRTASN1COREVTABLE pVtable, PRTASN1CONTEXTTAG pCtxTag, PRTASN1CURSOR pCtxTagCursor,
     1951                                             const char *pszErrorTag);
    19501952
    19511953/**
     
    19841986#define RTASN1CONTEXTTAG_IMPL_CURSOR_INLINES(a_uTag) \
    19851987    DECLINLINE(int) RT_CONCAT3(RTAsn1CursorGetContextTag,a_uTag,Cursor)(PRTASN1CURSOR pCursor, uint32_t fFlags, \
     1988                                                                        PCRTASN1COREVTABLE pVtable, \
    19861989                                                                        RT_CONCAT(PRTASN1CONTEXTTAG,a_uTag) pCtxTag, \
    19871990                                                                        PRTASN1CURSOR pCtxTagCursor, const char *pszErrorTag) \
    19881991    { /* Constructed is automatically implied if you need a cursor to it. */ \
    1989         return RTAsn1CursorGetContextTagNCursor(pCursor, fFlags, a_uTag, (PRTASN1CONTEXTTAG)pCtxTag, pCtxTagCursor, pszErrorTag); \
     1992        return RTAsn1CursorGetContextTagNCursor(pCursor, fFlags, a_uTag, pVtable, (PRTASN1CONTEXTTAG)pCtxTag, pCtxTagCursor, pszErrorTag); \
    19901993    } \
    19911994    DECLINLINE(int) RT_CONCAT3(RTAsn1ContextTag,a_uTag,InitDefault)(RT_CONCAT(PRTASN1CONTEXTTAG,a_uTag) pCtxTag) \
Note: See TracChangeset for help on using the changeset viewer.

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