📄 memmap.cpp
字号:
ASSERT ( m_pMappedViews );
ASSERT ( uPage );
ASSERT ( lpOffset );
LPBYTE lpBytePos = *lpOffset;
LPBYTE lpDebugView = (LPBYTE)m_pMappedViews[*uPage]; // enable the watch view
// Check if we need to span the page
UINT uAvailable = ((UINT)m_pMappedViews[*uPage] + MMF_PAGESIZE) - (UINT)*lpOffset;
if ( uLen > uAvailable ) {
// calc how many more pages we need
UINT uNeeded = uLen - uAvailable;
uNeeded = UPPER_BOUNDARY(uNeeded);
uNeeded /= MMF_PAGESIZE;
// Check if we need to create a page
// (maybe user defined a size or strings were deleted)
if ( *uPage == m_uPageCount-1 )
if ( Grow(uNeeded) != ERROR_SUCCESS )
throw _T("Unable to grow");
// copy the data block by block
LPBYTE lpBufPos = (LPBYTE)lpIn;
// fill the remainder of this page
memcpy(lpBytePos,lpBufPos,uAvailable);
lpBufPos += uAvailable;
// loop through filling the pages
for (UINT i=*uPage+1; i<*uPage+uNeeded; i++) {
lpBytePos = (LPBYTE)m_pMappedViews[i];
memcpy(lpBytePos,lpBufPos,MMF_PAGESIZE);
lpBufPos += MMF_PAGESIZE;
}
// calc size of the remainder
UINT uRemaining = (uLen - uAvailable) % MMF_PAGESIZE;
// copy the remainder
lpBytePos = (LPBYTE)m_pMappedViews[i];
memcpy(lpBytePos,lpBufPos,uRemaining);
// set the new pointer
*uPage = i;
*lpOffset = lpBytePos + uRemaining;
}
else {
// write directly to the file
memcpy(lpBytePos,lpIn,uLen);
*lpOffset += uLen;
}
}
LPBYTE CMemMap::Read(UINT *uPage, LPBYTE *lpOffset, UINT uLen, LPVOID lpOut)
{
/*************************************************************
* Read uLen of lpOffset into lpOut
* lpOffset may be spanned
* Always return a pointer to the start of the written data
* Returned value must be sequencial
* Set lpOffset and uPage to the end of the read data
* If lpOut is NULL only seek
**************************************************************/
ASSERT ( m_pMappedViews );
ASSERT ( uPage );
ASSERT ( lpOffset );
LPBYTE lpBytePos = *lpOffset;
// Check if spanned
UINT uRemaining = ((UINT)m_pMappedViews[*uPage] + MMF_PAGESIZE) - (UINT)*lpOffset;
if ( uLen > uRemaining ) {
// Calc how many pages are spanned
UINT pages = uLen - uRemaining;
pages = UPPER_BOUNDARY(pages);
pages /= MMF_PAGESIZE;
// find the last page
pages += *uPage;
// Check if last page is within bounds
if ( pages >= m_uPageCount ) {
// Try to open the page
UINT uGrowBy = pages - m_uPageCount;
DWORD dw = Grow(uGrowBy);
if ( dw != ERROR_ALREADY_EXISTS ) {
// We have a serious problem
// roll back
Shrink(uGrowBy);
// throw an exception
throw _T("Error, page out of bounds");
}
}
// calc size of the remainder
UINT uSize = (uLen - uRemaining) % MMF_PAGESIZE;
if ( lpOut ) {
// delete previous buffer if used
if ( m_lpDataBuffer )
delete [] m_lpDataBuffer;
// allocate new buffer
m_lpDataBuffer = new BYTE [uLen];
// copy the data block by block
LPBYTE lpBufPos = m_lpDataBuffer;
// fill the remainder of this page
memcpy(lpBufPos,lpBytePos,uRemaining);
lpBufPos += uRemaining;
// loop through filling the pages
for (UINT i=*uPage+1; i<pages; i++) {
lpBytePos = (LPBYTE)m_pMappedViews[i];
memcpy(lpBufPos,lpBytePos,MMF_PAGESIZE);
lpBufPos += MMF_PAGESIZE;
}
// copy the remainder
lpBytePos = (LPBYTE)m_pMappedViews[i];
memcpy(lpBufPos,lpBytePos,uSize);
// copy the pointer
lpBufPos = m_lpDataBuffer;
// Copy to lpOut
memcpy(lpOut,lpBufPos,uLen);
// update the pointers
*uPage = pages;
*lpOffset = (LPBYTE)m_pMappedViews[pages] + uSize;
return lpBufPos;
}
// Copy the pointer
*uPage = pages;
*lpOffset = (LPBYTE)m_pMappedViews[pages] + uSize;
return (LPBYTE)lpOut;
}
else {
// just read and return
if ( lpOut )
memcpy(lpOut,lpBytePos,uLen);
*lpOffset += uLen;
return lpBytePos;
}
// We shouldn't be here
ASSERT ( 1 );
return NULL;
}
BOOL CMemMap::UpdateBinary(LPVOID lpBin, UINT uSize, UINT uId)
{
/*******************************************************
* Check if string exists already and if the same length
* Convert binary to string and add as a string
*******************************************************/
ASSERT ( lpBin );
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return FALSE;
LPBYTE lpBytePos = 0;
UINT uPage = 0;
UINT uBuf = 1;
// Check if the id already exists
if ( FindID(uId,&uPage,&lpBytePos) == FALSE )
return AddBinary(lpBin,uSize,uId);
// skip the id
Read(&uPage,&lpBytePos,4,&uBuf); // read the id
// Get the string length
Read(&uPage,&lpBytePos,4,&uBuf); // read the size
// Check if can overwrite existing
if ( uBuf == uSize + 1) {
// overwrite
Write(&uPage,&lpBytePos,uSize,lpBin);
return TRUE;
}
// Delete the exisiting
DeleteID(uId);
// Add the new
return AddBinary(lpBin,uSize,uId);
}
BOOL CMemMap::AddBinary(LPVOID lpBin, UINT uSize, UINT uId)
{
/*******************************************************
* Convert to and add as a byte array
*******************************************************/
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return FALSE;
LPBYTE lpBytePos = 0;
UINT uPage = 0;
LPBYTE lpDebugView = (LPBYTE)m_pMappedViews[uPage]; // enable the watch view
// Check if the id already exists
if ( FindID(uId,&uPage,&lpBytePos) == TRUE )
return FALSE;
// Copy the binary to a buffer and null terminate
LPBYTE lpTmp = new BYTE [uSize + 1];
memcpy(lpTmp,lpBin,uSize);
lpTmp[uSize] = 0;
uSize++;
// write tha data
Write(&uPage,&lpBytePos,4, &uId);
Write(&uPage,&lpBytePos,4, &uSize);
Write(&uPage,&lpBytePos,uSize, lpTmp);
Write(&uPage,&lpBytePos,4, DOUBLE_NULL);
delete [] lpTmp;
return TRUE;
}
UINT CMemMap::GetBinary(LPVOID lpBin, UINT uSize, UINT uId)
{
/*******************************************************
* Check if data stream exists
* if lpBin is NULL, return the size
* copy data to lpBin
*******************************************************/
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return FALSE;
LPBYTE lpBytePos = 0;
UINT uPage = 0;
UINT uLen = 0;
// Check if the id exists
if ( FindID(uId,&uPage,&lpBytePos) == FALSE )
return 0;
Read(&uPage,&lpBytePos,4/*id*/, NULL);
Read(&uPage,&lpBytePos,4/*strlen*/, &uLen);
uLen -= 1/*null*/;
if ( ! lpBin )
return uLen;
if ( uLen > uSize )
uLen = uSize;
// Read the data
Read(&uPage,&lpBytePos,uLen,lpBin);
// return the size
return uLen;
}
LPVOID CMemMap::GetBinary(UINT uId)
{
/*******************************************************
* Check if data stream exists
* Convert data stream to binary
*******************************************************/
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return FALSE;
LPBYTE lpBytePos = 0;
UINT uPage = 0;
UINT ulen = 0;
// Check if the id exists
if ( FindID(uId,&uPage,&lpBytePos) == FALSE )
return 0;
ulen = GetLength(uPage,lpBytePos);
ulen -= 1/*null*/;
// set pointer to the data
Read(&uPage,&lpBytePos,8/*id & strlen*/,NULL);
// Create a return Buffer
if ( m_lpReturnBuffer )
delete [] m_lpReturnBuffer;
m_lpReturnBuffer = new BYTE [ulen];
// Read the data
Read(&uPage,&lpBytePos,ulen,m_lpReturnBuffer);
// return the buffer
return (LPVOID)*m_lpReturnBuffer;
}
BOOL CMemMap::AddString(LPCTSTR szString, UINT uId)
{
ASSERT ( szString );
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return FALSE;
LPBYTE lpBytePos = 0;
UINT uPage = 0;
// Check if the id already exists
if ( FindID(uId,&uPage,&lpBytePos) == TRUE )
return FALSE;
LPBYTE lpDebugView = (LPBYTE)m_pMappedViews[uPage];
// Calc how many bytes we need
UINT uStrlen = (_tcslen(szString) + 1 ) * sizeof(TCHAR);
Write(&uPage, &lpBytePos, 4, &uId);
Write(&uPage, &lpBytePos, 4, &uStrlen);
Write(&uPage, &lpBytePos, uStrlen, (LPVOID)szString);
Write(&uPage, &lpBytePos, 4, DOUBLE_NULL);
return TRUE;
}
UINT CMemMap::GetStringLength(UINT uId)
{
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return 0;
LPBYTE lpBytePos = 0;
UINT uPage = 0;
UINT uLen = 0;
// Check if the id already exists
if ( FindID(uId,&uPage,&lpBytePos) == FALSE )
return 0;
// Get the string length
uLen = GetLength(uPage,lpBytePos);
return uLen - sizeof(TCHAR);
}
UINT CMemMap::GetString(LPCTSTR szString, UINT uLen, UINT uId)
{
/********************************************************
* If szString then copy to there
* return length of string or copied data
********************************************************/
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return NULL;
LPTSTR lpString = NULL; // The string to return
LPBYTE lpBytePos = 0; // a navigation pointer
UINT uPage = 0;
// Check if the id already exists
if ( FindID(uId,&uPage,&lpBytePos) == FALSE )
return 0;
UINT _uLen = 0;
Read(&uPage,&lpBytePos,4,NULL);
Read(&uPage,&lpBytePos,4,&_uLen);
if ( ! szString )
return _uLen;
if ( _uLen > uLen )
_uLen = uLen;
Read(&uPage,&lpBytePos,_uLen,(LPBYTE)szString);
return _uLen;
}
LPCTSTR CMemMap::GetString(UINT uId)
{
/********************************************************
* Return a pointer to the string
********************************************************/
ASSERT ( m_pMappedViews );
CheckForNewPages();
// Validate the ID
if ( uId == 0xFFFFFFFF || uId == 0xFFFFFF00 )
return NULL;
LPTSTR lpString = NULL; // The string to return
LPBYTE lpBytePos = 0; // a navigation pointer
UINT uPage = 0;
// Check if the id already exists
if ( FindID(uId,&uPage,&lpBytePos) == FALSE )
return NULL;
UINT uLen = 0;
Read(&uPage,&lpBytePos,4,NULL);
Read(&uPage,&lpBytePos,4,&uLen);
// Check if the string is spanned
UINT uRemaining = ((UINT)m_pMappedViews[uPage] + MMF_PAGESIZE) - (UINT)lpBytePos;
if ( uLen > uRemaining ) {
try
{
// delete previous buffer if used
if ( m_lpReturnBuffer )
delete [] m_lpReturnBuffer;
// allocate new buffer
m_lpReturnBuffer = new BYTE [uLen];
}
catch (...)
{
TRACE ( _T("Buffer allocation failed in GetString") );
}
return (LPTSTR)Read(&uPage,&lpBytePos,uLen,m_lpReturnBuffer);
}
else
return (LPTSTR)Read(&uPage,&lpBytePos,uLen,NULL);
}
VOID CMemMap::NextID(UINT *uPage, LPBYTE *lpOffset)
{
/********************************************************
* Move the pointer to the next ID location
* Pointer should be pointing to an ID before calling
********************************************************/
ASSERT( lpOffset );
ASSERT( uPage );
if ( ! m_pMappedViews )
return;
LPBYTE lpCurPos = *lpOffset; // a navigation pointer
UINT uCurPage = *uPage;
UINT iLen = 0;
// Get the string length
iLen = GetLength(uCurPage,lpCurPos);
iLen += 8;
Read(&uCurPage,&lpCurPos,iLen,NULL);
// Update the pointer
*uPage = uCurPage;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -