STDMETHODIMP RegMeta::EnumGenericParamConstraints( HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. mdGenericParam tkOwner, // [IN] GenericParam whose constraints are requested mdGenericParamConstraint rTokens[], // [OUT] Put GenericParamConstraints here. ULONG cMaxTokens, // [IN] Max GenericParamConstraints to put. ULONG *pcTokens) // [OUT] Put # of tokens here. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum); ULONG ridStart; ULONG ridEnd; HENUMInternal *pEnum; GenericParamConstraintRec *pRec; ULONG index; CMiniMdRW *pMiniMd = NULL; LOG((LOGMD, "RegMeta::EnumGenericParamConstraints(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", phEnum, tkOwner, rTokens, cMaxTokens, pcTokens)); START_MD_PERF(); LOCKREAD(); pMiniMd = &(m_pStgdb->m_MiniMd); if(TypeFromToken(tkOwner) != mdtGenericParam) IfFailGo(META_E_BAD_INPUT_PARAMETER); // See if this version of the metadata can do Generics if (!pMiniMd->SupportsGenerics()) { if (pcTokens) *pcTokens = 0; hr = S_FALSE; goto ErrExit; } if ( *ppmdEnum == 0 ) { // instantiating a new ENUM //<TODO> GENERICS: review this. Are we expecting a sorted table or not? </TODO> if ( pMiniMd->IsSorted( TBL_GenericParamConstraint ) ) { IfFailGo(pMiniMd->getGenericParamConstraintsForGenericParam(RidFromToken(tkOwner), &ridEnd, &ridStart)); IfFailGo( HENUMInternal::CreateSimpleEnum(mdtGenericParamConstraint, ridStart, ridEnd, &pEnum) ); } else { // table is not sorted so we have to create dynamic array // create the dynamic enumerator // ridStart = 1; ridEnd = pMiniMd->getCountGenericParamConstraints() + 1; IfFailGo( HENUMInternal::CreateDynamicArrayEnum(mdtGenericParamConstraint, &pEnum)); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(pMiniMd->GetGenericParamConstraintRecord(index, &pRec)); if ( tkOwner == pMiniMd->getOwnerOfGenericParamConstraint(pRec)) { IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(index, mdtGenericParamConstraint))); } } } // set the output parameter *ppmdEnum = pEnum; } else { pEnum = *ppmdEnum; } // fill the output token buffer hr = HENUMInternal::EnumWithCount(pEnum, cMaxTokens, rTokens, pcTokens); ErrExit: HENUMInternal::DestroyEnumIfEmpty(ppmdEnum); STOP_MD_PERF(EnumGenericParamConstraints); END_ENTRYPOINT_NOTHROW; return hr; }
//***************************************************************************** // Enumerate Sym.InterfaceImpl where Coclass == td //***************************************************************************** STDMETHODIMP RegMeta::EnumInterfaceImpls( HCORENUM *phEnum, // Pointer to the enum. mdTypeDef td, // TypeDef to scope the enumeration. mdInterfaceImpl rImpls[], // Put InterfaceImpls here. ULONG cMax, // Max InterfaceImpls to put. ULONG *pcImpls) // Put # put here. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum); ULONG ridStart; ULONG ridEnd; HENUMInternal *pEnum; InterfaceImplRec *pRec; ULONG index; LOG((LOGMD, "RegMeta::EnumInterfaceImpls(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", phEnum, td, rImpls, cMax, pcImpls)); START_MD_PERF(); LOCKREAD(); _ASSERTE(TypeFromToken(td) == mdtTypeDef); if ( *ppmdEnum == 0 ) { // instantiating a new ENUM CMiniMdRW *pMiniMd = &(m_pStgdb->m_MiniMd); if ( pMiniMd->IsSorted( TBL_InterfaceImpl ) ) { IfFailGo(pMiniMd->getInterfaceImplsForTypeDef(RidFromToken(td), &ridEnd, &ridStart)); IfFailGo( HENUMInternal::CreateSimpleEnum( mdtInterfaceImpl, ridStart, ridEnd, &pEnum) ); } else { // table is not sorted so we have to create dynmaic array // create the dynamic enumerator // ridStart = 1; ridEnd = pMiniMd->getCountInterfaceImpls() + 1; IfFailGo( HENUMInternal::CreateDynamicArrayEnum( mdtInterfaceImpl, &pEnum) ); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(pMiniMd->GetInterfaceImplRecord(index, &pRec)); if ( td == pMiniMd->getClassOfInterfaceImpl(pRec) ) { IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(index, mdtInterfaceImpl) ) ); } } } // set the output parameter *ppmdEnum = pEnum; } else { pEnum = *ppmdEnum; } // fill the output token buffer hr = HENUMInternal::EnumWithCount(pEnum, cMax, rImpls, pcImpls); ErrExit: HENUMInternal::DestroyEnumIfEmpty(ppmdEnum); STOP_MD_PERF(EnumInterfaceImpls); END_ENTRYPOINT_NOTHROW; return hr; } // RegMeta::EnumInterfaceImpls
STDMETHODIMP RegMeta::EnumMethodSpecs( HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. mdToken tkOwner, // [IN] MethodDef or MemberRef whose MethodSpecs are requested mdMethodSpec rTokens[], // [OUT] Put MethodSpecs here. ULONG cMaxTokens, // [IN] Max tokens to put. ULONG *pcTokens) // [OUT] Put actual count here. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum); ULONG ridStart; ULONG ridEnd; HENUMInternal *pEnum; MethodSpecRec *pRec; ULONG index; CMiniMdRW *pMiniMd = NULL; LOG((LOGMD, "RegMeta::EnumMethodSpecs(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", phEnum, tkOwner, rTokens, cMaxTokens, pcTokens)); START_MD_PERF(); LOCKREAD(); pMiniMd = &(m_pStgdb->m_MiniMd); // See if this version of the metadata can do Generics if (!pMiniMd->SupportsGenerics()) { if (pcTokens) *pcTokens = 0; hr = S_FALSE; goto ErrExit; } _ASSERTE(RidFromToken(tkOwner)==0 || TypeFromToken(tkOwner) == mdtMethodDef || TypeFromToken(tkOwner) == mdtMemberRef); if ( *ppmdEnum == 0 ) { // instantiating a new ENUM if(RidFromToken(tkOwner)==0) // enumerate all MethodSpecs { ridStart = 1; ridEnd = pMiniMd->getCountMethodSpecs() + 1; IfFailGo( HENUMInternal::CreateSimpleEnum( mdtMethodSpec, ridStart, ridEnd, &pEnum) ); } else { //@todo GENERICS: review this. Are we expecting a sorted table or not? if ( pMiniMd->IsSorted( TBL_MethodSpec ) ) { if (TypeFromToken(tkOwner) == mdtMemberRef) { IfFailGo(pMiniMd->getMethodSpecsForMemberRef(RidFromToken(tkOwner), &ridEnd, &ridStart)); } else { IfFailGo(pMiniMd->getMethodSpecsForMethodDef(RidFromToken(tkOwner), &ridEnd, &ridStart)); } IfFailGo( HENUMInternal::CreateSimpleEnum(mdtMethodSpec, ridStart, ridEnd, &pEnum) ); } else { // table is not sorted so we have to create dynamic array // create the dynamic enumerator // ridStart = 1; ridEnd = pMiniMd->getCountMethodSpecs() + 1; IfFailGo( HENUMInternal::CreateDynamicArrayEnum(mdtMethodSpec, &pEnum) ); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(pMiniMd->GetMethodSpecRecord(index, &pRec)); if ( tkOwner == pMiniMd->getMethodOfMethodSpec(pRec) ) { IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(index, mdtMethodSpec) ) ); } } } } // set the output parameter *ppmdEnum = pEnum; } else { pEnum = *ppmdEnum; } // fill the output token buffer hr = HENUMInternal::EnumWithCount(pEnum, cMaxTokens, rTokens, pcTokens); ErrExit: HENUMInternal::DestroyEnumIfEmpty(ppmdEnum); STOP_MD_PERF(EnumMethodSpecs); END_ENTRYPOINT_NOTHROW; return hr; } // STDMETHODIMP RegMeta::EnumMethodSpecs()
//***************************************************************************** // Enumerate the CustomAttributes for a given token. //***************************************************************************** STDMETHODIMP RegMeta::EnumCustomAttributes( HCORENUM *phEnum, // Pointer to the enum. mdToken tk, // Token to scope the enumeration. mdToken tkType, // Type to limit the enumeration. mdCustomAttribute rCustomAttributes[], // Put CustomAttributes here. ULONG cMax, // Max CustomAttributes to put. ULONG *pcCustomAttributes) // Put # tokens returned here. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum); ULONG ridStart; ULONG ridEnd; HENUMInternal *pEnum = *ppmdEnum; CustomAttributeRec *pRec; ULONG index; LOG((LOGMD, "RegMeta::EnumCustomAttributes(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", phEnum, tk, tkType, rCustomAttributes, cMax, pcCustomAttributes)); START_MD_PERF(); LOCKREAD(); if ( pEnum == 0 ) { // instantiating a new ENUM CMiniMdRW *pMiniMd = &(m_pStgdb->m_MiniMd); CLookUpHash *pHashTable = pMiniMd->m_pLookUpHashs[TBL_CustomAttribute]; // Does caller want all custom Values? if (IsNilToken(tk)) { IfFailGo( HENUMInternal::CreateSimpleEnum(mdtCustomAttribute, 1, pMiniMd->getCountCustomAttributes()+1, &pEnum) ); } else { // Scope by some object. if ( pMiniMd->IsSorted( TBL_CustomAttribute ) ) { // Get CustomAttributes for the object. IfFailGo(pMiniMd->getCustomAttributeForToken(tk, &ridEnd, &ridStart)); if (IsNilToken(tkType)) { // Simple enumerator for object's entire list. IfFailGo( HENUMInternal::CreateSimpleEnum( mdtCustomAttribute, ridStart, ridEnd, &pEnum) ); } else { // Dynamic enumerator for subsetted list. IfFailGo( HENUMInternal::CreateDynamicArrayEnum( mdtCustomAttribute, &pEnum) ); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(pMiniMd->GetCustomAttributeRecord(index, &pRec)); if (tkType == pMiniMd->getTypeOfCustomAttribute(pRec)) { IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(index, mdtCustomAttribute) ) ); } } } } else { if (pHashTable) { // table is not sorted but hash is built // We want to create dynmaic array to hold the dynamic enumerator. TOKENHASHENTRY *p; ULONG iHash; int pos; mdToken tkParentTmp; mdToken tkTypeTmp; // Hash the data. iHash = pMiniMd->HashCustomAttribute(tk); IfFailGo( HENUMInternal::CreateDynamicArrayEnum( mdtCustomAttribute, &pEnum) ); // Go through every entry in the hash chain looking for ours. for (p = pHashTable->FindFirst(iHash, pos); p; p = pHashTable->FindNext(pos)) { CustomAttributeRec *pCustomAttribute; IfFailGo(pMiniMd->GetCustomAttributeRecord(RidFromToken(p->tok), &pCustomAttribute)); tkParentTmp = pMiniMd->getParentOfCustomAttribute(pCustomAttribute); tkTypeTmp = pMiniMd->getTypeOfCustomAttribute(pCustomAttribute); if (tkParentTmp == tk) { if (IsNilToken(tkType) || tkType == tkTypeTmp) { // compare the blob value IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(p->tok, mdtCustomAttribute )) ); } } } } else { // table is not sorted and hash is not built so we have to create dynmaic array // create the dynamic enumerator and loop through CA table linearly // ridStart = 1; ridEnd = pMiniMd->getCountCustomAttributes() + 1; IfFailGo( HENUMInternal::CreateDynamicArrayEnum( mdtCustomAttribute, &pEnum) ); for (index = ridStart; index < ridEnd; index ++ ) { IfFailGo(pMiniMd->GetCustomAttributeRecord(index, &pRec)); if ( tk == pMiniMd->getParentOfCustomAttribute(pRec) && (tkType == pMiniMd->getTypeOfCustomAttribute(pRec) || IsNilToken(tkType))) { IfFailGo( HENUMInternal::AddElementToEnum(pEnum, TokenFromRid(index, mdtCustomAttribute) ) ); } } } } } // set the output parameter *ppmdEnum = pEnum; } // fill the output token buffer hr = HENUMInternal::EnumWithCount(pEnum, cMax, rCustomAttributes, pcCustomAttributes); ErrExit: HENUMInternal::DestroyEnumIfEmpty(ppmdEnum); STOP_MD_PERF(EnumCustomAttributes); END_ENTRYPOINT_NOTHROW; return hr; } // STDMETHODIMP RegMeta::EnumCustomAttributes()