Exemplo n.º 1
0
//*****************************************************************************
// Called by the meta data engine when a token is remapped to a new location.
// This value is recorded in the m_rgMap array based on type and rid of the
// from token value.
//*****************************************************************************
HRESULT STDMETHODCALLTYPE CeeGenTokenMapper::Map(
    mdToken     tkFrom, 
    mdToken     tkTo)
{
    HRESULT hr = S_OK;
    mdToken *pToken = NULL;
    ULONG ridFrom = 0;
    TOKENMAP *pMap = NULL;

    BEGIN_ENTRYPOINT_NOTHROW;

    if ( IndexForType(tkFrom) == -1 )
    {
        // It is a type that we are not tracking, such as mdtProperty or mdtEvent,
        // just return S_OK.
        goto ErrExit;
    }

    _ASSERTE(IndexForType(tkFrom) < GetMaxMapSize());
    _ASSERTE(IndexForType(tkTo) != -1 && IndexForType(tkTo) < GetMaxMapSize());

    // If there is another token mapper that the user wants called, go
    // ahead and call it now.
    if (m_pIMapToken)
        m_pIMapToken->Map(tkFrom, tkTo);
    
    ridFrom = RidFromToken(tkFrom);
    pMap = &m_rgMap[IndexForType(tkFrom)];

    // If there isn't enough entries, fill out array up to the count
    // and mark the token to nil so we know there is no valid data yet.
    if ((ULONG) pMap->Count() <= ridFrom)
    {
        for (int i=ridFrom - pMap->Count() + 1;  i;  i--) 
        {
            pToken = pMap->Append();
            if (!pToken)
                break;
            *pToken = mdTokenNil;
        }
        _ASSERTE(!pToken || pMap->Get(ridFrom) == pToken);
    }
    else
        pToken = pMap->Get(ridFrom);

    IfNullGo(pToken);
    
    *pToken = tkTo;

ErrExit:
    END_ENTRYPOINT_NOTHROW;
    
    return hr;
}