📄 mmapdatf.cpp
字号:
/* * 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 */STDMETHODIMPMemoryMapDataFile::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. */STDMETHODIMPMemoryMapDataFile::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. */STDMETHODIMPMemoryMapDataFile::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 */STDMETHODIMPMemoryMapDataFile::Flush(){ StopMmap(); return HXR_NOTIMPL;}/* * Return info about the data file such as permissions, time of creation * size in bytes, etc. */STDMETHODIMPMemoryMapDataFile::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 */STDMETHODIMPMemoryMapDataFile::GetLastError(){ return m_ulLastError;}/* GetLastError returns the platform specific file error in * string form. */STDMETHODIMP_(void)MemoryMapDataFile::GetLastError(REF(IHXBuffer*) err){ err = 0; return;}BOOLMemoryMapDataFile::_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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -