示例#1
0
ALERROR CDataFile::DeleteEntry (int iEntry)

//	DeleteEntry
//
//	Does some stuff

	{
	ALERROR error;
	DWORD dwOldBlock;
	DWORD dwOldBlockCount;

	ASSERT(IsOpen());
	ASSERT(!m_fReadOnly);

	//	Make sure we're in bounds

	if (iEntry < 0 || iEntry >= m_iEntryTableCount)
		return ERR_FAIL;

	if (m_pEntryTable[iEntry].dwBlock == FREE_ENTRY)
		return ERR_FAIL;

	//	Delete it

	dwOldBlock = m_pEntryTable[iEntry].dwBlock;
	dwOldBlockCount = m_pEntryTable[iEntry].dwBlockCount;
	m_pEntryTable[iEntry].dwBlock = FREE_ENTRY;

	FreeBlockChain(dwOldBlock, dwOldBlockCount);

	//	Flush

	if ((error = Flush()))
		return error;

	return NOERROR;
	}
 void StormFixedBlockAllocator::FreeBlockChain(void * resolved_pointer, StormFixedBlockType::Index type)
 {
   FreeBlockChain(GetHandleForBlock(resolved_pointer), type);
 }
示例#3
0
ALERROR CDataFile::ResizeEntry (int iEntry, DWORD dwSize, DWORD *retdwBlockCount)

//	ResizeEntry
//
//	Changes the blocks associated with the given entry. Note that this
//	routine does not necessarily preserve the previous contents of
//	the entry

	{
	ALERROR error;
	DWORD dwBlockCount;

	//	Figure out how many blocks we need to hold the entry

	dwBlockCount = (dwSize / (DWORD)m_iBlockSize) + 1;

	//	If this is less than the number of blocks that we've
	//	got allocated, free some

	if (dwBlockCount < m_pEntryTable[iEntry].dwBlockCount)
		{
		DWORD dwFreeBlocks = m_pEntryTable[iEntry].dwBlockCount - dwBlockCount;

		m_pEntryTable[iEntry].dwBlockCount = dwBlockCount;
		if ((error = FreeBlockChain(m_pEntryTable[iEntry].dwBlock + dwBlockCount, dwFreeBlocks)))
			return error;
		}

	//	If this is more than the number of entries for this block
	//	then we need to grow the block chain.

	else if (dwBlockCount > m_pEntryTable[iEntry].dwBlockCount)
		{
		DWORD dwOldBlock = m_pEntryTable[iEntry].dwBlock;
		DWORD dwOldBlockCount = m_pEntryTable[iEntry].dwBlockCount;
		DWORD dwStartingBlock;

		//	Add a new entry

		if ((error = AllocBlockChain(dwBlockCount, &dwStartingBlock)))
			return error;

		//	Store the new entry data

		m_pEntryTable[iEntry].dwBlock = dwStartingBlock;
		m_pEntryTable[iEntry].dwBlockCount = dwBlockCount;

		//	Free the current block chain

		if ((error = FreeBlockChain(dwOldBlock, dwOldBlockCount)))
			return error;
		}

	//	Set data length

	m_pEntryTable[iEntry].dwSize = dwSize;
	m_fEntryTableModified = TRUE;

	//	Return the block count, if necessary

	if (retdwBlockCount)
		*retdwBlockCount = dwBlockCount;

	return NOERROR;
	}
示例#4
0
ALERROR CDataFile::AddEntry (const CString &sData, int *retiEntry)

//	AddEntry
//
//	Does some stuff

	{
	ALERROR error;
	int i, iEntry;
	DWORD dwStartingBlock;
	DWORD dwBlockCount;

	ASSERT(IsOpen());
	ASSERT(!m_fReadOnly);

	//	Look for a free entry

	for (i = 0; i < m_iEntryTableCount; i++)
		if (m_pEntryTable[i].dwBlock == FREE_ENTRY)
			break;

	//	If we could not find a free entry, grow the entry table

	if (i == m_iEntryTableCount)
		{
		if ((error = GrowEntryTable(&iEntry)))
			goto Fail;
		}
	else
		iEntry = i;

	//	Figure out how many blocks we need

	dwBlockCount = (sData.GetLength() / m_iBlockSize) + 1;

	//	Allocate a block chain large enough to contain the entry

	if ((error = AllocBlockChain(dwBlockCount, &dwStartingBlock)))
		goto Fail;

	//	Write the block chain

	if ((error = WriteBlockChain(dwStartingBlock, sData.GetPointer(), sData.GetLength())))
		{
		FreeBlockChain(dwStartingBlock, dwBlockCount);
		goto Fail;
		}

	//	Set the entry

	m_pEntryTable[iEntry].dwBlock = dwStartingBlock;
	m_pEntryTable[iEntry].dwBlockCount = dwBlockCount;
	m_pEntryTable[iEntry].dwSize = (DWORD)sData.GetLength();
	m_pEntryTable[iEntry].dwFlags = 0;
	m_fEntryTableModified = TRUE;

	//	Flush

	if ((error = Flush()))
		goto Fail;

	//	Done

	*retiEntry = iEntry;

	return NOERROR;

Fail:

	return error;
	}
示例#5
0
ALERROR CDataFile::DeleteEntry (int iEntry)

//	DeleteEntry
//
//	Does some stuff

	{
	ALERROR error;
	DWORD dwOldBlock;
	DWORD dwOldBlockCount;

	ASSERT(IsOpen());
	ASSERT(!m_fReadOnly);

	//	Make sure we're in bounds

	if (iEntry < 0 || iEntry >= m_iEntryTableCount)
		return ERR_FAIL;

	ENTRYSTRUCT *pEntry = &m_pEntryTable[iEntry];
	if (pEntry->dwBlock == FREE_ENTRY)
		return ERR_FAIL;

	//	Delete it the block that we own

	dwOldBlock = pEntry->dwBlock;
	dwOldBlockCount = pEntry->dwBlockCount;
	pEntry->dwBlock = FREE_ENTRY;

	FreeBlockChain(dwOldBlock, dwOldBlockCount);

	//	The entry array may have changed inside FreeBlockChain, so we refresh

	pEntry = &m_pEntryTable[iEntry];

	//	If we're the latest entry, then we delete just this version

	if (pEntry->dwLatestEntry == (DWORD)INVALID_ENTRY)
		{
		if (pEntry->dwPrevEntry != (DWORD)INVALID_ENTRY)
			{
			ENTRYSTRUCT *pPrevEntry = &m_pEntryTable[pEntry->dwPrevEntry];

			pEntry->dwBlock = pPrevEntry->dwBlock;
			pEntry->dwBlockCount = pPrevEntry->dwBlockCount;
			pEntry->dwSize = pPrevEntry->dwSize;
			pEntry->dwFlags = pPrevEntry->dwFlags;
			pEntry->dwVersion = pPrevEntry->dwVersion;
			pEntry->dwPrevEntry = pPrevEntry->dwPrevEntry;
			pEntry->dwLatestEntry = (DWORD)INVALID_ENTRY;

			pPrevEntry->dwBlock = FREE_ENTRY;
			}
		}

	//	If this is not the latest entry, then we need to
	//	fix up the chain

	else if (pEntry->dwLatestEntry != (DWORD)INVALID_ENTRY)
		{
		//	Look for the version after this one

		int iNextEntry = (int)pEntry->dwLatestEntry;
		while (iNextEntry != INVALID_ENTRY && m_pEntryTable[iNextEntry].dwPrevEntry != (DWORD)iEntry)
			iNextEntry = (int)m_pEntryTable[iNextEntry].dwPrevEntry;

		//	If we found it, then make the connection

		if (iNextEntry != INVALID_ENTRY)
			{
			ENTRYSTRUCT *pNextEntry = &m_pEntryTable[iNextEntry];
			pNextEntry->dwPrevEntry = pEntry->dwPrevEntry;
			}
		}

	//	Flush

	if (error = Flush())
		return error;

	return NOERROR;
	}
示例#6
0
void FMemArena::FreeAllBlocks()
{
	FreeBlockChain(TopBlock);
	FreeBlockChain(FreeBlocks);
}