#include <typeinfo>
#include <string.h>
#include <mockcpp/mockcpp.h>
#if defined(_MSC_VER)
#include <mockcpp/MsvcRtti.h>
#endif
MOCKCPP_NS_START
namespace
{
#if defined(__GNUC__)
const unsigned int EXTRA_VTBL_SLOT = 2;
#elif defined(_MSC_VER)
const unsigned int EXTRA_VTBL_SLOT = 1;
#endif
const unsigned int SLOTS_PER_VTBL = MOCKCPP_MAX_VTBL_SIZE + EXTRA_VTBL_SLOT;
unsigned int times = 0;
}
void** createVtbls(unsigned int numberOfVptr)
{
void **p = new void*[numberOfVptr * SLOTS_PER_VTBL];
(void)memset(p, 0, sizeof(void *) * numberOfVptr * SLOTS_PER_VTBL);
return p;
}
void freeVtbls(void** vtbl, unsigned int numberOfVptr)
{
#if defined(_MSC_VER)
RTTIClassHierarchyDescriptor* desc = 0;
for(unsigned int i=0; i<numberOfVptr; i++)
{
int base = i*SLOTS_PER_VTBL;
if(vtbl[base] != 0)
{
RTTICompleteObjectLocator* rtti = (RTTICompleteObjectLocator*)vtbl[base];
desc = rtti->pClassDescriptor;
delete rtti;
}
}
if(desc != 0)
{
delete desc;
}
#endif
delete [] vtbl;
}
unsigned int getRealVtblIndex(unsigned int indexOfVptr, unsigned int indexOfVtbl)
{
return indexOfVptr * SLOTS_PER_VTBL + EXTRA_VTBL_SLOT + indexOfVtbl ;
}
void initializeVtbls(void** vptr, void**vtbl, unsigned int numberOfVptr, const std::type_info& info, bool hasRtti)
{
#if defined(_MSC_VER)
RTTIClassHierarchyDescriptor * desc = 0;
if(hasRtti)
{
desc = new RTTIClassHierarchyDescriptor(numberOfVptr > 1 ? true : false);
}
#endif
for(unsigned int i=0; i<numberOfVptr; i++)
{
int base = i*SLOTS_PER_VTBL;
#if defined(__GNUC__)
vtbl[base + 0] = (void*)(-1*(sizeof(void*)*i));
vtbl[base + 1] = (void*)&info;
#elif defined(_MSC_VER)
vtbl[base + 0] = hasRtti ? new RTTICompleteObjectLocator(i, info, desc) : 0;
#endif
vptr[i] = (void*)&vtbl[base + EXTRA_VTBL_SLOT];
}
}
MOCKCPP_NS_END