📄 minifileobj.cpp
字号:
// this with a caching buffer system, this issue goes away. if( result == HXR_OK ) { result = m_pFileResponse->ReadDone(readResult, pBuffer); } m_bInReadDone = FALSE; // Release our handle on the buffer HX_RELEASE(pBuffer); } } } else { result = HXR_OUTOFMEMORY; } } return result;}/**************************************************************************** * IHXFileObject::Write * * This routine writes a block of data to the file. When writing has * completed, the caller is asynchronously notified via the File Response * object associated with this File Object. This method called by the File * Format plug-in when it needs to write to the file. */STDMETHODIMP CHXMiniFileObject::Write(IHXBuffer* pDataToWrite){ DPRINTF(D_MINI_FO, ("CHXMiniFO::Write()\n")); UINT32 byteCount = pDataToWrite->GetSize(); UINT32 actualCount = fwrite(pDataToWrite->GetBuffer(), sizeof(UCHAR), byteCount, m_pFile); // Notify the caller that the write is done HX_RESULT writeResult = (actualCount == byteCount) ? HXR_OK : HXR_FAILED; m_pFileResponse->WriteDone(writeResult); return HXR_OK;}/**************************************************************************** * IHXFileObject::Seek * * This routine moves to a given position in the file. The move can be * either from the beginning of the file (absolute), or relative to the * current file position. When seeking has completed, the caller is * asynchronously notified via the File Response object associated with this * File Object. This method called by the File Format plug-in when it needs * to seek to a location within the file. */STDMETHODIMP CHXMiniFileObject::Seek( UINT32 offset, BOOL bIsRelative ){ DPRINTF(D_MINI_FO, ("CHXMiniFO::Seek()\n")); // Cancel any pending reads HX_RELEASE(m_pPendingReadBuf); int fromWhere = SEEK_SET; // absolute if (bIsRelative == TRUE) { fromWhere = SEEK_CUR; // relative } int seekResult = HXR_FAIL; if (m_pFile) seekResult = fseek(m_pFile, offset, fromWhere); // Notify the caller that the seek is done HX_RESULT result = !seekResult ? HXR_OK : HXR_FAILED; HX_RESULT retVal = m_pFileResponse->SeekDone(result); // Memory allocations can be attempted in the execution of SeekDone, and we // want to catch these if they fail. if( retVal != HXR_OUTOFMEMORY ) { retVal = result; } return (retVal);}/**************************************************************************** * IHXFileObject::Advise * * This routine is passed information about the intended usage of this * object. The useage will indicate whether sequential or random requests * for information will be made. This may be useful, for example, in * developing a caching scheme. */STDMETHODIMP CHXMiniFileObject::Advise(UINT32 ui/* useage */){ DPRINTF(D_MINI_FO, ("CHXMiniFO::Advise()\n")); return HXR_UNEXPECTED;}/**************************************************************************** * IHXFileObject::Close * * This routine closes the file resource and releases all resources * associated with the object. This routine is crucial and must be called * before the File Object is destroyed. */STDMETHODIMP CHXMiniFileObject::Close(void){ DPRINTF(D_MINI_FO, ("CHXMiniFO::Close()\n")); if (m_pFile != NULL) { fclose(m_pFile); m_pFile = NULL; } if (m_pRequest != NULL) { m_pRequest->Release(); m_pRequest = NULL; }#if defined (_WINDOWS ) && defined (_WIN32) if (m_hFileHandle) { ::FindClose( m_hFileHandle ); m_hFileHandle = 0; }#endif /* * Store this in temp so that if calling CloseDone * causes our descructor to get called we will * have pCallCloseDone on the stack to safely release. */ IHXFileResponse* pCallCloseDone = m_pFileResponse; if (m_pFileResponse != NULL) { m_pFileResponse = NULL; pCallCloseDone->CloseDone(HXR_OK); pCallCloseDone->Release(); } return HXR_OK;}// IHXRequestHandler Interface Methods/**************************************************************************** * IHXRequestHandler::SetRequest * * This routine associates this File Object with the file Request object * passed to it from the Helix core. This Request object is primarily used to * obtain the requested URL. This method is called just after the File * Object is created. */STDMETHODIMP CHXMiniFileObject::SetRequest(IHXRequest* pRequest){ HX_RESULT res = HXR_FAIL; DPRINTF(D_MINI_FO, ("CHXMiniFO::SetRequest()\n")); // Reset the current request object and associated filename HX_RELEASE(m_pRequest); m_pRequest = pRequest; HX_VECTOR_DELETE(m_pFilename); if (m_pRequest) { m_pRequest->AddRef(); const char* pURL; if (m_pRequest->GetURL(pURL) == HXR_OK && pURL) { // Ensure that we are working with an unescaped URL INT32 cchEscaped = strlen(pURL); // Unescaped URL is at most same size or smaller char* pUnescaped = new char [cchEscaped + 1]; if( pUnescaped) { INT32 cchNew = URLUnescapeBuffer(pURL, cchEscaped, pUnescaped); if(cchNew > 0) { pUnescaped[cchNew] = '\0'; res = ConvertToPlatformPath(m_pFilename, pUnescaped); } delete[] pUnescaped; } } } return res;}/**************************************************************************** * IHXRequestHandler::GetRequest * * This routine retrieves the Request object associated with this File * Object. It is called just after the SetRequest() method. */STDMETHODIMP CHXMiniFileObject::GetRequest(REF(IHXRequest*) pRequest){ DPRINTF(D_MINI_FO, ("CHXMiniFO::GetRequest()\n")); pRequest = m_pRequest; if (pRequest != NULL) { pRequest->AddRef(); } return HXR_OK;}/**************************************************************************** * IHXFileExists::DoesExist * * This routine determines if the given file exists, and notifies the File * Response object. It is called by the server after the File Object has * been created to determine if the requested file does actually exist. If * it does the File Object is handed off to the File Format object. */STDMETHODIMP CHXMiniFileObject::DoesExist( const char* pFilePath, IHXFileExistsResponse* pFileResponse ){ DPRINTF(D_MINI_FO, ("CHXMiniFO::DoesExist()\n")); BOOL bDoesExist = FALSE; char* pFilePathPlatform = NULL; // Convert file path to platform specific file path HX_RESULT result = ConvertToPlatformPath(pFilePathPlatform, pFilePath); // Determine if the file can be opened if (result == HXR_OK) { struct stat statbuf; if (stat(pFilePathPlatform, &statbuf) == 0) { bDoesExist = TRUE; } } // Notify the caller if the file exists pFileResponse->DoesExistDone(bDoesExist); if (pFilePathPlatform != NULL) { delete [] pFilePathPlatform; } return HXR_OK;}// IUnknown COM Interface Methods/**************************************************************************** * IUnknown::AddRef * * This routine increases the object reference count in a thread safe * manner. The reference count is used to manage the lifetime of an object. * This method must be explicitly called by the user whenever a new * reference to an object is used. */STDMETHODIMP_(UINT32) CHXMiniFileObject::AddRef(void){ return InterlockedIncrement(&m_RefCount);}/**************************************************************************** * IUnknown::Release * * This routine decreases the object reference count in a thread safe * manner, and deletes the object if no more references to it exist. It must * be called explicitly by the user whenever an object is no longer needed. */STDMETHODIMP_(UINT32) CHXMiniFileObject::Release(void){ if (InterlockedDecrement(&m_RefCount) > 0) { return m_RefCount; } delete this; return 0;}/**************************************************************************** * IUnknown::QueryInterface * * This routine indicates which interfaces this object supports. If a given * interface is supported, the object's reference count is incremented, and * a reference to that interface is returned. Otherwise a NULL object and * error code are returned. This method is called by other objects to * discover the functionality of this object. */STDMETHODIMP CHXMiniFileObject::QueryInterface(REFIID interfaceID, void** ppInterfaceObj){ QInterfaceList qiList[] = { { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXFileObject*)this }, { GET_IIDHANDLE(IID_IHXFileObject), (IHXFileObject*) this }, { GET_IIDHANDLE(IID_IHXDirHandler), (IHXDirHandler*) this }, { GET_IIDHANDLE(IID_IHXRequestHandler), (IHXRequestHandler*) this }, { GET_IIDHANDLE(IID_IHXFileExists), (IHXFileExists*) this }, { GET_IIDHANDLE(IID_IHXFileStat), (IHXFileStat*) this }, { GET_IIDHANDLE(IID_IHXGetFileFromSamePool), (IHXGetFileFromSamePool*) this }, }; return ::QIFind(qiList, QILISTSIZE(qiList), interfaceID, ppInterfaceObj);}/************************************************************************ * Method: * IHXFileObject::Stat * Purpose: * Collects information about the file that is returned to the * caller in an IHXStat object */STDMETHODIMP CHXMiniFileObject::Stat(IHXFileStatResponse* pFileStatResponse){ DPRINTF(D_MINI_FO, ("CHXMiniFO::Stat()\n")); struct stat StatBuffer; if((m_pFile && fstat((int)fileno(m_pFile), &StatBuffer) == 0) || stat(m_pFilename, &StatBuffer) == 0) { pFileStatResponse->StatDone(HXR_OK, StatBuffer.st_size, StatBuffer.st_ctime, StatBuffer.st_atime, StatBuffer.st_mtime, StatBuffer.st_mode); return HXR_OK; } return HXR_FAIL;}STDMETHODIMP CHXMiniFileObject::InitDirHandler( IHXDirHandlerResponse* pDirResponse ){ DPRINTF(D_MINI_FO, ("CHXMiniFO::InitDirHandler()\n")); m_pDirResponse = pDirResponse; m_pDirResponse->AddRef(); m_pDirResponse->InitDirHandlerDone(HXR_OK); return HXR_OK;}STDMETHODIMP CHXMiniFileObject::CloseDirHandler(){ DPRINTF(D_MINI_FO, ("CHXMiniFO::CloseDirHandler()\n")); m_pDirResponse->CloseDirHandlerDone(HXR_OK); m_pDirResponse->Release(); m_pDirResponse = NULL; return HXR_OK;}STDMETHODIMP CHXMiniFileObject::MakeDir(){ DPRINTF(D_MINI_FO, ("CHXMiniFO::MakeDir()\n"));#if defined (_WINDOWS ) || defined (_WIN32) USES_CONVERSION; if( ::CreateDirectory(A2T(m_pFilename), NULL) == 0 ) return HXR_FAIL;#elif defined UNIX if(mkdir(m_pFilename, 0x644) < 0) return HXR_FAIL;#else //XXXGH...don't know how to do this on Mac return HXR_FAIL;#endif m_pDirResponse->MakeDirDone(HXR_OK); return HXR_OK;}STDMETHODIMP CHXMiniFileObject::ReadDir(){ DPRINTF(D_MINI_FO, ("CHXMiniFO::ReadDir()\n")); char pDirname[1024];#if defined (_WINDOWS ) && defined (_WIN32) USES_CONVERSION; if (!m_hFileHandle) { strcpy(pDirname, m_pFilename); strcat(pDirname, "\\*"); m_hFileHandle = ::FindFirstFile( A2T(pDirname), &m_FileInfo ); if ( INVALID_HANDLE_VALUE == m_hFileHandle ) { m_hFileHandle = 0; return HXR_FAILED; } } else { if ( ::FindNextFile(m_hFileHandle, &m_FileInfo) == 0 ) { ::FindClose( m_hFileHandle ); m_hFileHandle = 0; m_pDirResponse->ReadDirDone(HXR_FILE_NOT_FOUND, 0); return HXR_OK; } } strcpy( pDirname, T2A(m_FileInfo.cFileName) );#else return HXR_FAIL;#endif HX_RESULT result; IHXBuffer* pBuffer = 0; result = m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&pBuffer); if (HXR_OK != result) { return result; } pBuffer->Set( (Byte*) pDirname, strlen(pDirname) + 1 ); m_pDirResponse->ReadDirDone(HXR_OK, pBuffer); pBuffer->Release(); return HXR_OK;}/************************************************************************ * Method: * IHXFileObject::GetFileObjectFromPool * Purpose: * To get another FileObject from the same pool. */STDMETHODIMP CHXMiniFileObject::GetFileObjectFromPool( IHXGetFileFromSamePoolResponse* response ){ DPRINTF(D_MINI_FO, ("CHXMiniFO::GetFileObjectFromPool()\n")); HX_RESULT lReturnVal = HXR_OUTOFMEMORY; if ( m_pFilename ) { delete [] m_pBasePath; m_pBasePath = new char[strlen(m_pFilename) + 1]; if (m_pBasePath) { // Chop off the current path to create a base path. strcpy(m_pBasePath, m_pFilename); char* pLastSeparator = strrchr(m_pBasePath, OS_SEPARATOR_CHAR); *pLastSeparator = '\0'; CHXMiniFileObject* pFileObject = new CHXMiniFileObject(m_pClassFactory, m_pBasePath); if (pFileObject) { IUnknown* pUnknown = 0; lReturnVal = pFileObject->QueryInterface(IID_IUnknown, (void**)&pUnknown); response->FileObjectReady((lReturnVal == HXR_OK) ? HXR_OK : HXR_FAILED, pUnknown); HX_RELEASE(pUnknown); } } } return lReturnVal;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -