mmapdatf.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 838 行 · 第 1/2 页
CPP
838 行
/*
* File may be mapped and we are trying to truncate it.
* It will only let us do that if we unmap the file NOW.
*
if (uOpenMode & HX_FILE_WRITE && dwCreate == CREATE_ALWAYS)
{
_AttemptUnmap();
/*
* We are now going to open the file, so make
* sure there is always a read mixed this this write.
*
dwFlags |= GENERIC_READ;
dwShare |= FILE_SHARE_READ;
}
/*
* Try and re-open the file. This will either be read only
* if we failed reading, in case it is a readonly file,
* of it could be another attempt at "w" after unampping
* the file. All vars are set up for either case.
*
m_hFile = CreateFile(m_pFilename,
dwFlags,
dwShare,
NULL,
dwCreate,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (m_hFile == INVALID_HANDLE_VALUE)
{
return HXR_FAIL;
}
}
m_ulPos = 0;
if (MmapHandle)
{
m_zpMMM->CloseMap(MmapHandle);
MmapHandle = 0;
}
MmapHandle = m_zpMMM->OpenMap(m_hFile, m_pContext);
return HXR_OK;
}
*/
/* Delete File */
STDMETHODIMP
MemoryMapDataFile::Delete()
{
Close();
if (!m_pFilename)
{
return HXR_UNEXPECTED;
}
if (DeleteFile(OS_STRING(m_pFilename)))
{
return HXR_OK;
}
else if (_AttemptUnmap())
{
if (DeleteFile(OS_STRING(m_pFilename)))
{
return HXR_OK;
}
}
return HXR_FAIL;
}
/* Close closes a file
* If the reference count on the IHXDataFile object is greater than 1,
* then the underlying file cannot be safely closed, so Close() becomes
* a noop in that case. Close it only when the object is destroyed.
* This would be safe, but could lead to a file descriptor leak.
*/
STDMETHODIMP
MemoryMapDataFile::Close()
{
m_ulLastError = HXR_OK;
if (m_hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(m_hFile);
m_hFile = INVALID_HANDLE_VALUE;
}
m_ulPos = -1;
if (MmapHandle)
{
m_zpMMM->CloseMap(MmapHandle);
MmapHandle = 0;
}
return HXR_OK;
}
/* Name returns the currently bound file name in FileName.
* and returns TRUE, if the a name has been bound. Otherwise
* FALSE is returned.
*/
STDMETHODIMP_(BOOL)
MemoryMapDataFile::Name(REF(IHXBuffer*) pFileName)
{
if (!m_pFilename)
{
return FALSE;
}
pFileName = new CHXBuffer();
pFileName->AddRef();
pFileName->Set((const unsigned char*)m_pFilename,
strlen(m_pFilename) + 1);
return TRUE;
}
/*
* IsOpen returns TRUE if file is open. Otherwise FALSE.
*/
STDMETHODIMP_(BOOL)
MemoryMapDataFile::IsOpen()
{
if (m_hFile != INVALID_HANDLE_VALUE)
{
return TRUE;
}
return FALSE;
}
/* Seek moves the current file position to the offset from the
* fromWhere specifier returns current position of file or -1 on
* error.
*/
STDMETHODIMP
MemoryMapDataFile::Seek(ULONG32 offset, UINT16 fromWhere)
{
LONG32 lHighOffset = 0;
m_ulLastError = HXR_OK;
DWORD fw = 0;
switch (fromWhere)
{
case SEEK_CUR:
fw = FILE_CURRENT;
m_ulPos += offset;
if (((LONG32) offset) < 0)
{
lHighOffset = -1;
}
break;
case SEEK_END:
fw = FILE_END;
if (offset > m_ulPos)
{
m_ulPos = 0;
}
else
{
m_ulPos -= offset;
}
break;
case SEEK_SET:
fw = FILE_BEGIN;
m_ulPos = offset;
break;
}
DWORD dwRet = SetFilePointer(m_hFile, offset, &lHighOffset, fw);
if (dwRet == -1)
{
if (GetLastError() != NO_ERROR)
{
m_ulPos = -1;
m_ulLastError = HXR_FAIL;
return HXR_FAIL;
}
}
return 0;
}
/* Tell returns the current file position in the file */
STDMETHODIMP_(ULONG32)
MemoryMapDataFile::Tell()
{
m_ulLastError = HXR_OK;
return m_ulPos;
}
void MemoryMapDataFile::StopMmap()
{
if (MmapHandle == NULL)
return;
m_zpMMM->CloseMap(MmapHandle);
MmapHandle = 0;
Seek(m_ulPos, SEEK_SET);
}
/* Read reads up to count bytes of data into buf.
* returns the number of bytes read, EOF, or -1 if the read failed
*/
STDMETHODIMP_(ULONG32)
MemoryMapDataFile::Read(REF(IHXBuffer*) pBuf,
ULONG32 count)
{
m_ulLastError = HXR_OK;
if (!(m_uOpenMode & HX_FILE_READ))
{
return 0;
}
UINT32 ulRead = 0;
if (MmapHandle)
{
ulRead = m_zpMMM->GetBlock(pBuf, MmapHandle, m_ulPos, count);
if (ulRead >= MMAP_EXCEPTION)
{
if (ulRead != MMAP_EOF_EXCEPTION)
{
StopMmap();
}
else
{
Seek(m_ulPos, SEEK_SET);
}
goto normal_read;
}
if (ulRead > 0)
{
m_ulPos += ulRead;
}
return ulRead;
}
normal_read:
if (m_hFile == INVALID_HANDLE_VALUE)
{
pBuf = NULL;
return 0;
}
pBuf = new CHXBuffer;
pBuf->AddRef();
pBuf->SetSize(count);
if (!ReadFile(m_hFile, (void*)pBuf->GetBuffer(), count, &ulRead, NULL))
{
m_ulLastError = HXR_FAIL;
}
m_ulPos += ulRead;
if (ulRead < count)
{
pBuf->SetSize(ulRead);
}
return ulRead;
}
/* Write writes up to count bytes of data from buf.
* returns the number of bytes written, or -1 if the write failed
*/
STDMETHODIMP_(ULONG32)
MemoryMapDataFile::Write(REF(IHXBuffer*) pBuf)
{
m_ulLastError = HXR_OK;
if (!(m_uOpenMode & HX_FILE_WRITE))
{
return 0;
}
StopMmap();
UINT32 ulWritten = 0;
if (m_hFile == INVALID_HANDLE_VALUE)
{
return 0;
}
if (!WriteFile(m_hFile, (void*)pBuf->GetBuffer(), pBuf->GetSize(),
&ulWritten, NULL))
{
m_ulLastError = HXR_FAIL;
}
return ulWritten;
}
/* Flush out the data in case of unbuffered I/O
*/
STDMETHODIMP
MemoryMapDataFile::Flush()
{
StopMmap();
return HXR_NOTIMPL;
}
/*
* Return info about the data file such as permissions, time of creation
* size in bytes, etc.
*/
STDMETHODIMP
MemoryMapDataFile::Stat(struct stat* buffer)
{
if (!m_pFilename)
{
return HXR_UNEXPECTED;
}
BOOL bClose = FALSE;
HANDLE hUse = m_hFile;
if (hUse == INVALID_HANDLE_VALUE)
{
bClose = TRUE;
hUse = CreateFile(OS_STRING(m_pFilename),
0, //query
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
}
if (hUse == INVALID_HANDLE_VALUE)
{
return HXR_FAIL;
}
BY_HANDLE_FILE_INFORMATION mss;
memset(buffer, 0, sizeof(*buffer));
buffer->st_nlink = 1;
HX_RESULT res;
if (GetFileInformationByHandle(hUse,
&mss))
{
buffer->st_atime = FileTimeTotime_t(&mss.ftLastAccessTime);
buffer->st_ctime = FileTimeTotime_t(&mss.ftCreationTime);
buffer->st_mtime = FileTimeTotime_t(&mss.ftLastWriteTime);
buffer->st_size = mss.nFileSizeLow;
res = HXR_OK;
}
else
{
res = HXR_FAIL;
}
if (bClose)
{
CloseHandle(hUse);
}
return res;
}
/* Return the file descriptor */
STDMETHODIMP_(INT16)
MemoryMapDataFile::GetFd()
{
if (m_hFile != INVALID_HANDLE_VALUE)
{
return 1;
}
return -1;
}
/* GetLastError returns the platform specific file error */
STDMETHODIMP
MemoryMapDataFile::GetLastError()
{
return m_ulLastError;
}
/* GetLastError returns the platform specific file error in
* string form.
*/
STDMETHODIMP_(void)
MemoryMapDataFile::GetLastError(REF(IHXBuffer*) err)
{
err = 0;
return;
}
BOOL
MemoryMapDataFile::_AttemptUnmap()
{
HANDLE hFile;
hFile = CreateFile(OS_STRING(m_pFilename),
GENERIC_READ,
FILE_SHARE_READ |
(g_NT ? FILE_SHARE_DELETE : 0),
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
void* pHandle = m_zpMMM->GetMMHandle(hFile);
CloseHandle(hFile);
if (!pHandle)
{
return FALSE;
}
m_zpMMM->AttemptCloseMapNow(pHandle);
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?