minifileobj.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:29k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- /****************************************************************************
- * Includes
- */
- #include "hxtypes.h"
- #include "hlxclib/stdio.h" /* FILE */
- #include "hlxclib/string.h" /* strcpy, etc. */
- #include "hlxclib/sys/stat.h" /* stat() */
- #if defined (_WINDOWS ) && defined (_WIN32)
- #include <atlbase.h>
- #ifndef _WINCE
- #include <direct.h> /* mkdir, etc. */
- #endif
- #elif defined (_MACINTOSH)
- #include <unix.h> /* fileno */
- #endif
- #include "hxcom.h" /* IUnknown */
- #include "hxcomm.h" /* IHXCommonClassFactory */
- #include "ihxpckts.h" /* IHXValues, IHXBuffers */
- #include "rtsputil.h"
- #include "minifilesys.h" /* FILE_SYS_PROTOCOL */
- #include "minifileobj.h" /* CHXMiniFileObject */
- #include "debug.h" /* DPRINTF */
- #include "hxdir.h" /* OS_SEPERATOR_STRING */
- #define D_MINI_FO 0x1000000
- // CHXMiniFileObject Class Methods
- /****************************************************************************
- * CHXMiniFileObject::CHXMiniFileObject
- *
- * Constructor
- */
- CHXMiniFileObject::CHXMiniFileObject(IHXCommonClassFactory* pClassFactory, const char* pBasePath): m_RefCount(0),
- m_pClassFactory (pClassFactory),
- m_pFileResponse (NULL),
- m_pFile (NULL),
- m_pFilename (NULL),
- m_pRequest (NULL),
- m_pBasePath (NULL),
- #if defined (_WINDOWS ) && defined (_WIN32)
- m_hFileHandle (0),
- #endif
- m_FileAccessMode (0),
- m_pDirResponse (NULL),
- m_bInReadDone(FALSE),
- m_pPendingReadBuf(NULL)
- {
- DPRINTF(D_MINI_FO, ("CHXMiniFO::CHXMiniFileObject()n"));
- // Signify that we need to keep a reference to this object
- if (m_pClassFactory != NULL)
- {
- m_pClassFactory->AddRef();
- }
- if (pBasePath)
- {
- m_pBasePath = new char[strlen(pBasePath) + 1];
- if (m_pBasePath)
- {
- strcpy(m_pBasePath, pBasePath);
- }
- }
- }
- /****************************************************************************
- * CHXMiniFileObject::~CHXMiniFileObject
- *
- * Destructor. It is essential to call the Close() routine before destroying
- * this object.
- */
- CHXMiniFileObject::~CHXMiniFileObject(void)
- {
- DPRINTF(D_MINI_FO, ("CHXMiniFO::~CHXMiniFileObject()n"));
- Close();
- delete [] m_pBasePath;
- m_pBasePath = 0;
- if (m_pFilename != NULL)
- {
- delete[] m_pFilename;
- m_pFilename = 0;
- }
- if (m_pClassFactory != NULL)
- {
- m_pClassFactory->Release();
- m_pClassFactory = NULL;
- }
- }
- /****************************************************************************
- * CHXMiniFileObject::OpenFile
- *
- * This routine opens a file according to the access mode given. It is
- * called while initializing the File Object.
- */
- STDMETHODIMP CHXMiniFileObject::OpenFile(UINT32 fileAccessMode)
- {
- HX_RESULT result = HXR_OK;
- // Construct the proper access mode string
- char modeStr[4];
- if (fileAccessMode & HX_FILE_READ)
- {
- strcpy(modeStr, "r");
- if (fileAccessMode & HX_FILE_WRITE)
- {
- strcat(modeStr, "+");
- }
- if (fileAccessMode & HX_FILE_BINARY)
- {
- strcat(modeStr, "b");
- }
- }
- else if (fileAccessMode & HX_FILE_WRITE)
- {
- strcpy(modeStr, "w");
- if (fileAccessMode & HX_FILE_BINARY)
- {
- strcat(modeStr, "b");
- }
- }
- else if (fileAccessMode == 0)
- {
- fileAccessMode = HX_FILE_READ | HX_FILE_BINARY;
- strcpy(modeStr, "rb");
- }
- else
- {
- result = HXR_INVALID_PARAMETER;
- }
- // Open the file with the proper access mode
- if (result == HXR_OK)
- {
- m_pFile = fopen(m_pFilename, modeStr);
- result = m_pFile ? HXR_OK : HXR_DOC_MISSING;
- }
- return result;
- }
- /****************************************************************************
- * CHXMiniFileObject::ConvertToPlatformPath
- *
- * This routine converts the given file path to a platform specific file
- * path based upon the naming conventions of that platform. The platform
- * specific path name is required to properly open the file.
- */
- STDMETHODIMP CHXMiniFileObject::ConvertToPlatformPath(REF(char*) pFilePathPlatform, const char* pFilePath)
- {
- HX_RESULT res = HXR_OUTOFMEMORY;
- pFilePathPlatform = 0;
- if (m_pBasePath && pFilePath)
- {
- // Create new string
- pFilePathPlatform =
- new char[ strlen(m_pBasePath) + strlen(pFilePath) + 2 ];
- }
- UINT32 length = strlen(FILE_SYS_PROTOCOL) + 1; // Add 1 for the colon
- char* pProtocolString = new char[length + 1];
- if (pFilePathPlatform && pProtocolString && m_pBasePath)
- {
- // Prepend base path, if any
- if (strlen(m_pBasePath) > 0)
- {
- strcpy(pFilePathPlatform, m_pBasePath);
- strcat(pFilePathPlatform, OS_SEPARATOR_STRING);
- strcat(pFilePathPlatform, pFilePath);
- }
- else
- {
- strcpy(pFilePathPlatform, pFilePath);
- }
- // Strip protocol string, if any
- strcpy(pProtocolString, FILE_SYS_PROTOCOL);
- strcat(pProtocolString, ":");
- if (strnicmp(pFilePathPlatform, pProtocolString, length) == 0)
- {
- //copy the rest of the string back onto itself.
- memmove( (void*) pFilePathPlatform,
- (void*) &pFilePathPlatform[length],
- (strlen( &pFilePathPlatform[length] )+1)*sizeof(char)
- );
- if ((pFilePathPlatform[0] == '/') &&
- (pFilePathPlatform[1] == '/'))
- {
- // "file://" forms
- // Find next '/'
- const char* pNext = strchr(pFilePathPlatform + 2, '/');
- if (pNext)
- {
- // "file://host/path" or "file:///path" form.
- // Copy everything after the third '/'
- memmove( (void*) pFilePathPlatform,
- (void*) (pNext+1),
- (strlen(pNext+1)+1)*sizeof(char)
- );
- pNext = 0;
- res = HXR_OK;
- }
- else
- {
- // Forms: file://c:file.ra
- // file://file.ra
- memmove( (void*) pFilePathPlatform,
- (void*) (pFilePathPlatform+2),
- (strlen(pFilePathPlatform+2)+1)*sizeof(char)
- );
- res = HXR_OK;
- }
- }
- else
- {
- res = HXR_OK;
- }
- if (HXR_OK == res)
- {
- // Replace path slashes with platform specific path separators
- // and watch for the parameter delimiter
- char* pCur = pFilePathPlatform;
- for (; *pCur && (*pCur != '?'); pCur++)
- {
- if (*pCur == '/')
- {
- *pCur = OS_SEPARATOR_CHAR;
- }
- }
- /*
- * Strip off the parameters
- */
- if (*pCur == '?')
- {
- *pCur = ' ';
- }
- }
- }
- else
- {
- if (NULL == strstr(pFilePathPlatform,"//"))
- res = HXR_OK; // allow path/file w/o file://
- else
- res = HXR_INVALID_PROTOCOL;
- }
- }
- delete [] pProtocolString;
- pProtocolString = 0;
- if (res != HXR_OK)
- {
- delete [] pFilePathPlatform;
- pFilePathPlatform = 0;
- }
- return res;
- }
- // IHXFileObject Interface Methods
- /****************************************************************************
- * IHXFileObject::Init
- *
- * This routine associates this File Object with a File Response object
- * which is notified when file operations (read, write, seek, etc.) are
- * complete. This method also checks the validity of the file by actually
- * opening it.
- */
- STDMETHODIMP CHXMiniFileObject::Init( UINT32 fileAccessMode, IHXFileResponse* pFileResponse )
- {
- /*
- * Associate this File Object with a File Response object for completion
- * notification.
- */
- DPRINTF(D_MINI_FO, ("CHXMiniFO::Init()n"));
- if (pFileResponse != NULL)
- {
- // Release any previous File Response objects
- if (m_pFileResponse != NULL)
- {
- m_pFileResponse->Release();
- }
- m_pFileResponse = pFileResponse;
- m_pFileResponse->AddRef();
- }
- else
- {
- return HXR_INVALID_PARAMETER;
- }
- /*
- * Open the file and notify File Response when complete
- */
- if (m_pFile != NULL) // File is already open
- {
- // Has requested access mode changed?
- if ((fileAccessMode == m_FileAccessMode) ||
- (fileAccessMode == 0))
- {
- // reset to start of file
- fseek(m_pFile, 0, SEEK_SET);
- // notify that file is ready
- m_pFileResponse->InitDone(HXR_OK);
- return HXR_OK;
- }
- else // Access mode has changed
- {
- fclose(m_pFile);
- m_pFile = NULL;
- }
- }
- m_FileAccessMode = fileAccessMode;
- HX_RESULT fileOpenResult = OpenFile(fileAccessMode);
- m_pFileResponse->InitDone(fileOpenResult);
- return fileOpenResult;
- }
- /****************************************************************************
- * IHXFileObject::GetFilename
- *
- * This routine returns the name of the requested file (without any path
- * information). This method may be called by the File Format plug-in if the
- * short name of the file is required.
- */
- STDMETHODIMP CHXMiniFileObject::GetFilename( REF(const char*) pFileName )
- {
- DPRINTF(D_MINI_FO, ("CHXMiniFO::GetFilename()n"));
- pFileName = NULL;
- HX_RESULT result = HXR_OK;
- // Find the separator character before the file name
- pFileName = ::strrchr(m_pFilename, OS_SEPARATOR_CHAR);
- if (pFileName != NULL) // Found
- {
- // File name starts after the separator charactor
- pFileName++;
- }
- else // Not found
- {
- pFileName = m_pFilename;
- }
- return result;
- }
- /****************************************************************************
- * IHXFileObject::Read
- *
- * This routine reads a block of data of the specified length from the file.
- * When reading has completed, the caller is asynchronously notified via the
- * File Response object associated with this File Object. This method is
- * called by the File Format plug-in when it needs to read from the file.
- */
- STDMETHODIMP CHXMiniFileObject::Read( UINT32 byteCount )
- {
- DPRINTF(D_MINI_FO, ("CHXMiniFO::Read(%u)n", byteCount));
- HX_RESULT result = HXR_UNEXPECTED;
- if ((m_pPendingReadBuf == NULL) && (m_pClassFactory != NULL))
- {
- if (byteCount > 0x000FFFFF)
- {
- m_bInReadDone = FALSE;
- m_pFileResponse->ReadDone(HXR_FAILED, NULL);
- return HXR_INVALID_PARAMETER;
- }
- m_pClassFactory->CreateInstance(CLSID_IHXBuffer, (void**)&m_pPendingReadBuf);
- if (m_pPendingReadBuf != NULL)
- {
- result = m_pPendingReadBuf->SetSize(byteCount);
- if (HXR_OK != result)
- {
- HX_RELEASE(m_pPendingReadBuf);
- }
- else if (!m_bInReadDone)
- {
- // We use a loop here so we can service Read() calls
- // occurred inside the ReadDone() callback
- while (m_pPendingReadBuf)
- {
- // Transfer ownership of the pending buffer to
- // this local variable. This prepares for the
- // possibility that Read() may be called from
- // ReadDone()
- IHXBuffer* pBuffer = m_pPendingReadBuf;
- m_pPendingReadBuf = NULL;
- // Read from the file directly into the buffer object
- UINT32 actualCount = fread(pBuffer->GetBuffer(),
- sizeof(UCHAR),
- pBuffer->GetSize(), m_pFile);
- result = pBuffer->SetSize(actualCount);
- // Notify the caller that the read is done
- HX_RESULT readResult = actualCount > 0 ? HXR_OK : HXR_FAILED;
- m_bInReadDone = TRUE;
- // If heap gets low, memory allocations for new file read
- // buffers is one of the first places we notice it, and
- // if we're not careful to report this error, we can get
- // into a state where the renderer is stuck trying to
- // rebuffer, but the front end can't get any new data
- // because we can't allocate any new buffers. If we replace
- // 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] = ' ';
- 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 = ' ';
- 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;
- }