📄 minifileobj.cpp
字号:
// 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 + -