📄 memfsys.cpp
字号:
REF(const char*) /*OUT*/ pShortName, REF(const char*) /*OUT*/ pProtocol){ pShortName = zm_pShortName; pProtocol = zm_pProtocol; return HXR_OK;}STDMETHODIMPCMemoryFileSystem::InitFileSystem(IHXValues* options){ IHXBuffer* base_path_buf = 0; ULONG32 auth_flag = 0; HX_RELEASE(m_options); m_options = options; if (m_options) { m_options->AddRef(); if (HXR_OK == m_options->GetPropertyBuffer("BasePath", base_path_buf)) { m_base_path = CHXString((char*)base_path_buf->GetBuffer()); } } if (base_path_buf) { base_path_buf->Release(); } return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileSystemObject::CreateFile// Purpose:// TBD//STDMETHODIMP CMemoryFileSystem::CreateFile( IUnknown** /*OUT*/ ppFileObject){ CMemoryFileObject* pFileObj = new CMemoryFileObject(m_base_path, this, m_pContext); if (pFileObj) { if(HXR_OK == pFileObj->QueryInterface(IID_IUnknown, (void**)ppFileObject)) return HXR_OK; return HXR_UNEXPECTED; } return HXR_OUTOFMEMORY;}/////////////////////////////////////////////////////////////////////////// Method:// CMemoryFileSystem::CreateDir// Purpose:// TBD//STDMETHODIMP CMemoryFileSystem::CreateDir( IUnknown** /*OUT*/ ppDirObject){ return HXR_NOTIMPL;}/************************************************************************ * Method: * IHXMemoryFileSystem::Add * Purpose: * Add the specified URL to the file system and create a new * chunky res for it. */STDMETHODIMP CMemoryFileSystem::Add(const char* pURL, IHXMemoryFileContext* pContext, void* pID, const char* pMime){ return AddWithSize(pURL, pContext, pID, pMime, 0);}/************************************************************************ * Method: * IHXMemoryFileSystem::AddWithSize * Purpose: * Add the specified URL to the file system and create a new * chunky res for it. Specify the size in advance. */STDMETHODIMP CMemoryFileSystem::AddWithSize(const char* pURL, IHXMemoryFileContext* pContext, void* pID, const char* pMime, UINT32 uSize){ CChunkyRes* pRes = NULL; HX_ASSERT(g_pChunkyResMgr); CHXURL url(pURL); pURL = url.GetURL(); if (g_pChunkyResMgr->FindResource(pURL) == HXR_OK) { return HXR_FAIL; } if (g_pMapStreamToChunky->Lookup(pID, (void*&)pRes)) { return HXR_FAIL; } // Use the default context if we aren't given a specific one if (!pContext) { HX_ASSERT(z_pMemCtx); pContext = z_pMemCtx; } HX_RESULT theErr = g_pChunkyResMgr->OpenResource(&pRes, pURL); if (theErr == HXR_OK) { CMemoryFileStatus* pStatus = new CMemoryFileStatus(pContext, pID, pMime); if (!pStatus) { theErr = HXR_OUTOFMEMORY; } else { pStatus->AddRef(); pStatus->SetContentSize(uSize); g_pMapChunkyToStatus->SetAt(pRes, pStatus); g_pMapStreamToChunky->SetAt(pID, pRes); } } CancelRequest(pURL, HXR_OK); return theErr;}/************************************************************************ * Method: * IHXMemoryFileSystem::Remove * Purpose: * Remove the specified URL from the file system and discard its * chunky res. */STDMETHODIMP CMemoryFileSystem::Remove(void* pID){ CChunkyRes* pRes = NULL; HX_ASSERT(g_pChunkyResMgr); if (!g_pMapStreamToChunky->Lookup(pID, (void*&)pRes)) { return HXR_FAIL; } g_pMapStreamToChunky->RemoveKey(pID); HX_ASSERT(pRes); CMemoryFileStatus* pStatus = NULL; if (pRes && g_pMapChunkyToStatus->Lookup(pRes, (void*&)pStatus)) { // If no one else is using the file, we can close it if (!pStatus->Release()) { g_pMapChunkyToStatus->RemoveKey(pRes); HX_VERIFY(SUCCEEDED(g_pChunkyResMgr->CloseResource(pRes))); } } return HXR_OK;}/************************************************************************ * Method: * IHXMemoryFileSystem::Exists * Purpose: * Returns TRUE if the given URL exists in the file system and * FALSE if it doesn't. */STDMETHODIMP_(BOOL) CMemoryFileSystem::Exists(const char* pURL){ HX_ASSERT(g_pChunkyResMgr); CHXURL url(pURL); pURL = url.GetURL(); return g_pChunkyResMgr->FindResource(pURL) == HXR_OK;}/************************************************************************ * Method: * IHXMemoryFileSystem::Append * Purpose: * Appends data to the end of the specified memory file object. */STDMETHODIMP CMemoryFileSystem::Append(void* pID, unsigned char* pData, ULONG32 ulLen){ HX_RESULT theErr = HXR_FAIL; CChunkyRes* pRes = NULL; HX_ASSERT(g_pChunkyResMgr); if (g_pMapStreamToChunky->Lookup(pID, (void*&)pRes)) { HX_ASSERT(pRes); CMemoryFileStatus* pStatus = NULL; if (g_pMapChunkyToStatus->Lookup(pRes, (void*&)pStatus)) { HX_ASSERT(pStatus); ULONG32 ulPos = pStatus->GetSize(); theErr = pRes->SetData(ulPos, (const char*)pData, ulLen); if (theErr == HXR_OK) { pStatus->SetSize (ulPos + ulLen); } } } return theErr;}/************************************************************************ * Method: * IHXMemoryFileSystem::Finish * Purpose: * Marks a memory file as having been completely downloaded. */STDMETHODIMP CMemoryFileSystem::Finish(void* pID){ HX_RESULT theErr = HXR_FAIL; CChunkyRes* pRes = NULL; HX_ASSERT(g_pChunkyResMgr); if (g_pMapStreamToChunky->Lookup(pID, (void*&)pRes)) { HX_ASSERT(pRes); CMemoryFileStatus* pStatus = NULL; if (g_pMapChunkyToStatus->Lookup(pRes, (void*&)pStatus)) { theErr = HXR_OK; pStatus->SetDone(TRUE); } } return theErr;}/************************************************************************ * Method: * IHXMemoryFileSystem::Shutdown * Purpose: * Informs the memory file system that it is time to * release all of its members, if they have not * been released yet. */STDMETHODIMP CMemoryFileSystem::Shutdown (){ HX_ASSERT(g_pMapChunkyToStatus); CHXMapPtrToPtr::Iterator i; for(i = g_pMapChunkyToStatus->Begin(); i!= g_pMapChunkyToStatus->End(); ++i) { CMemoryFileStatus* pStatus = (CMemoryFileStatus*)*i; HX_ASSERT(pStatus); HX_RELEASE(pStatus); } g_pMapChunkyToStatus->RemoveAll(); HX_ASSERT(g_pMapStreamToChunky); HX_ASSERT(g_pChunkyResMgr); for (i = g_pMapStreamToChunky->Begin(); i != g_pMapStreamToChunky->End(); ++i) { CChunkyRes* pChunk = (CChunkyRes*)*i; HX_ASSERT(pChunk); HX_VERIFY(SUCCEEDED(g_pChunkyResMgr->CloseResource(pChunk))); } g_pMapStreamToChunky->RemoveAll(); return HXR_OK;}/************************************************************************ * Method: * IHXMemoryFileSystem::SetDefaultContext * Purpose: * Provides a default memory file system context for requesting * new file objects. */STDMETHODIMPCMemoryFileSystem::SetDefaultContext(IHXMemoryFileContext* pContext){ HX_RELEASE(z_pMemCtx); z_pMemCtx = pContext; z_pMemCtx->AddRef(); return HXR_OK;}/************************************************************************ * Method: * IHXMemoryFileSystem::RequestURL * Purpose: * Request that the memory file system ask the default context to * open the specified URL. */STDMETHODIMPCMemoryFileSystem::RequestURL(const char* pURL, IHXFileResponse* pFileResponse){ HX_RESULT theErr = HXR_FAIL; CHXURL url(pURL); pURL = url.GetURL(); // don't allow us to have multiple outstanding requests for the // same URL IHXFileResponse* pOldResponse; if (g_pMapURLToResponse->Lookup(pURL, (void*&)pOldResponse)) { return HXR_FAIL; } if (z_pMemCtx) { // Mark that we've requested this URL (we mark it before making the // request because some file systems are synchronous HX_ASSERT(pFileResponse); pFileResponse->AddRef(); g_pMapURLToResponse->SetAt(pURL, pFileResponse); theErr = z_pMemCtx->RequestOpen(pURL); // the request failed, cancel it internally so we don't wait forever if (FAILED(theErr)) { CancelRequest(pURL, theErr); } } return theErr;}/************************************************************************ * Method: * IHXMemoryFileSystem::CancelRequest * Purpose: * Cancels a pending URL request */STDMETHODIMPCMemoryFileSystem::CancelRequest(const char* pURL, HX_RESULT result){ CHXURL url(pURL); pURL = url.GetURL(); IHXFileResponse* pOldResponse; if (g_pMapURLToResponse->Lookup(pURL, (void*&)pOldResponse)) { HX_ASSERT(pOldResponse); if (pOldResponse) { pOldResponse->InitDone(result); } HX_RELEASE(pOldResponse); g_pMapURLToResponse->RemoveKey(pURL); } return HXR_OK;}CMemoryFileObject::CMemoryFileObject(CHXString& base_path, IHXFileSystemObject *pFS, IUnknown* pContext) : m_lRefCount(0) , m_ulFlags(0) , m_bLocalClose(FALSE) , m_pContext(pContext) , m_pCommonClassFactory(NULL) , m_pFileResponse(NULL) , m_pChunkyRes(NULL) , m_pFileSystem(pFS) , m_pFilename(NULL) , m_pRequest(0) , m_uRecursionCount(0) , m_bInReadDone(FALSE) , m_pScheduler(NULL) , m_pCallback(NULL) , m_ulPendingReadCount(0) , m_bReadCancelled(FALSE) , m_bSeekPending(FALSE) , m_ulPos(0) , m_bCanBeReOpened(0) , m_pStatus(NULL) , m_bAsynchInit(FALSE) , m_bClosed(FALSE){ g_nMemFSysRefCount++; m_base_path = base_path; int nLen = m_base_path.GetLength(); if (nLen > 0) { if (m_base_path.GetAt(nLen-1) != '/') { m_base_path += "/"; } } if (m_pFileSystem) { m_pFileSystem->AddRef(); } HX_ASSERT(m_pContext); if (m_pContext) { m_pContext->AddRef(); m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler); HX_ASSERT(m_pScheduler); } m_pCallback = new SMPLFileObjCallback(this); HX_ASSERT(m_pCallback); m_pCallback->AddRef();}CMemoryFileObject::~CMemoryFileObject(){ HX_ASSERT(g_nMemFSysRefCount > 0); g_nMemFSysRefCount--; m_bLocalClose = TRUE; Close();}// *** IUnknown methods ***/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::QueryInterface// Purpose:// Implement this to export the interfaces supported by your // object.//STDMETHODIMP CMemoryFileObject::QueryInterface(REFIID riid, void** ppvObj){ if (IsEqualIID(riid, IID_IUnknown)) { AddRef(); *ppvObj = this; return HXR_OK; } else if (IsEqualIID(riid, IID_IHXFileObject)) { AddRef(); *ppvObj = (IHXFileObject*)this; return HXR_OK; } else if (IsEqualIID(riid, IID_IHXFileStat)) { AddRef(); *ppvObj = (IHXFileStat*)this; return HXR_OK; } else if (IsEqualIID(riid, IID_IHXFileExists)) { AddRef(); *ppvObj = (IHXFileExists*)this; return HXR_OK; } else if (IsEqualIID(riid, IID_IHXGetFileFromSamePool)) { AddRef(); *ppvObj = (IHXGetFileFromSamePool*)this; return HXR_OK; } else if(IsEqualIID(riid, IID_IHXRequestHandler)) { AddRef(); *ppvObj = (IHXRequestHandler*)this; return HXR_OK; } else if(IsEqualIID(riid, IID_IHXFileMimeMapper)) { AddRef(); *ppvObj = (IHXFileMimeMapper*)this; return HXR_OK; } else if(IsEqualIID(riid, IID_IHXPendingStatus)) { AddRef(); *ppvObj = (IHXPendingStatus*)this; return HXR_OK; } else if(IsEqualIID(riid, IID_IHXFileResponse)) { AddRef(); *ppvObj = (IHXFileResponse*)this; return HXR_OK; } *ppvObj = NULL; return HXR_NOINTERFACE;}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::AddRef// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) CMemoryFileObject::AddRef(){ return InterlockedIncrement(&m_lRefCount);}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::Release// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) CMemoryFileObject::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}/************************************************************************ * Method: * IHXFileObject::Init * Purpose: * Associates a file object with the file response object it should * notify of operation completness. This method should also check * for validity of the object (for example by opening it if it is * a local file). */STDMETHODIMP CMemoryFileObject::Init( ULONG32 /*IN*/ ulFlags, IHXFileResponse* /*IN*/ pFileResponse){ HX_RESULT lReturnVal = HXR_OK; HX_RESULT resultInitDone = HXR_OK; IUnknown* pIUnknownUserContext = NULL; IHXRequestContext* pIHXRequestContextCurrent = NULL; BOOL bChoseAsynchInit = FALSE; if (!pFileResponse) return HXR_INVALID_PARAMETER; if (!m_pRequest) return HXR_INVALID_PARAMETER; /* Release any previous reponses */ if (m_pFileResponse) { m_pFileResponse->Release(); } m_pFileResponse = pFileResponse; m_pFileResponse->AddRef(); /* have we already opened/created a file */ if (m_pChunkyRes) { /* if flags are same, then we are all set and there * is no need to do anything further
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -