Runtime.
Both functions are executed BEFORE the data is stored. They're used to gather information used in storing the data. GetSize is called first to check the actual size of the data. Then GetDataType is called to attain the type the data is. Those two values are stored in a struct when saving the value.
There are no post-checks after retrieving the data, but I guess I will need to do that. But I won't use those functions for that because there's no runtime data after retrieving stored data. I could post the entire saving function, but it's pretty long. But here it is anyway, if you want to have a look at it:
Code:
template<typename T> void CSyncClass::SetValue(CString strName, T tData, UINT32 nSize)
{
cSync.Lock();
nSize = GetSize(tData); // Get data size
CBufferValueInfo* pValue = NULL;
// Does a value of this type already exist?
m_LookupMap.Lookup(strName, (void*&)pValue);
if (pValue != NULL)
{
// There exists a value with this name already. Check size. If size is equal, then go ahead and replace it. If not...
if (pValue->nSize == nSize) goto AssignValue;
if (pValue->nSize < nSize)
{
// The existing block isn't large enough to hold our data! Let's free it and find a new block.
pValue->bAllocated = false;
pValue->strValueName = "";
pValue = NULL;
UINT32 nOffset = 0;
for(;;)
{
// Loop for finding a new block
m_BlockLookupMap.Lookup(nOffset, pValue);
if (pValue == NULL)
{
// The map is empty or we found the end of the map! Create a new block and continue.
pValue = new CBufferValueInfo;
pValue->nOffset = nOffset;
goto AssignValue;
}
else
{
// We found an existing block. If it's allocated already, ignore it. If it's free, check if it's big enough.
if (pValue->bAllocated)
{
nOffset += pValue->nSize; // Jump ahead to the beginning of the next block.
continue;
}
else
{
// Block is empty, but is it large enough?
if (pValue->nSize == nSize)
{
// Block is exactly the right size to hold our data, so go ahead and assign the data!
pValue = new CBufferValueInfo;
pValue->nOffset = nOffset;
goto AssignValue;
}
if (pValue->nSize > nSize)
{
// Block is bigger than the data it needs to hold, so let's split it.
CBufferValueInfo* pTemp = new CBufferValueInfo;
pTemp->nOffset = pValue->nOffset + nSize;
pTemp->nSize = pValue->nSize - nSize;
pTemp->bAllocated = false;
m_BlockLookupMap.SetAt(pTemp->nOffset, pTemp);
pTemp = NULL;
pValue->nSize = nSize;
goto AssignValue;
}
if (pValue->nSize < nSize)
{
// Block isn't large enough to hold our data! So let's check if there's another free block ahead we can use as well. If not, we'll continue searching.
CBufferValueInfo* pTemp = NULL;
m_BlockLookupMap.Lookup(pValue->nOffset + pValue->nSize, pTemp);
if (pTemp == NULL)
{
// There's no more blocks available. Extend the size of this one and continue with the assigning process!
pValue->nSize = nSize;
goto AssignValue;
}
else
{
// There's another block here! Let's examine it.
if (pTemp->bAllocated)
{
// No luck. Block is already taken.
nOffset += pValue->nSize;
continue;
}
else
{
// Block is free! Let's merge these two and continue the search!
pValue->nSize += pTemp->nSize;
m_BlockLookupMap.RemoveKey(pTemp->nOffset);
continue;
}
}
}
}
}
}
}
if (pValue->nSize > nSize)
{
// Block is large enough to hold our data - in fact, it's a little too big. We need to split the block and free the memory we don't need.
CBufferValueInfo* pTemp = new CBufferValueInfo;
pTemp->nOffset = pValue->nOffset + nSize;
pTemp->nSize = pValue->nSize - nSize;
pTemp->bAllocated = false;
pValue->nSize = nSize;
m_BlockLookupMap.SetAt(pTemp->nOffset, pTemp);
goto AssignValue;
}
}
// Find a free block, or if none such exist, create one
AssignValue:
// Let's create out index and store it in the maps
pValue->nSize = nSize;
pValue->strValueName = strName;
pValue->bAllocated = true;
pValue->DataType = GetDataType(tData);
m_LookupMap.SetAt(strName, (void*)pValue);
m_BlockLookupMap.SetAt(pValue->nOffset, pValue);
// Is the offset of the data larger than our current buffer size? If so, then we need to resize it!
if (pValue->nOffset > m_nBufferSize)
{
m_nBufferSize = pValue->nOffset - m_nBufferSize + 100;
m_pBuffer.Resize(m_nBufferSize);
}
// Everything set then? Let's copy the data to our buffer!
//if ( typeid(tData) ==
memcpy_s(m_pBuffer[pValue->nOffset], m_nBufferSize - pValue->nOffset, tData, nSize);
cSync.Unlock();
}