📄 smplfsys.cpp
字号:
// said it did not expect a failure here. Also,
// we have not retried our maximum number of attempts
// yet, so we will retry the read.
//
// Can we callback asynchronously?
if (m_bAsyncAccess)
{
// Set the flag saying we failed due to
// progressive download
rbProgFail = TRUE;
// Schedule the callback
return FinishDoReadWithCallback(actual);
}
else
{
// Try synchronously
return FinishDoReadWithoutCallback(actual);
}
}
else
{
// Either:
// a) the fileformat either didn't have the Advise interface;
// b) the fileformat did have the interface and said it
// was expecting a failure; or
// c) the fileformat had the Advise interface and said it
// wasn't expecting a failure, but we've retried all the
// times we can.
//
// Clear the progressive download failure flag
rbProgFail = FALSE;
// Finish the DoRead
return FinishDoRead(actual, pBuffer);
}
}
} /* if (m_pProgDownMon->HasBeenProgressive()) else */
}
else /* if (actual < ulCount) */
{
// The read succeeded
//
// Reset the not progressive retry count
m_pProgDownMon->ResetNotProgressiveRetryCount();
// Clear the progressive download failure flag
rbProgFail = FALSE;
// Finish the DoRead
return FinishDoRead(actual, pBuffer);
}
}
else /* if (m_pProgDownMon) */
#endif /* #if defined(HELIX_FEATURE_PROGDOWN) */
{
// Clear the progressive download failure flag
rbProgFail = FALSE;
// Finish the DoRead
return FinishDoRead(actual, pBuffer);
}
#else /* #ifndef _MACINTOSH */
BOOL bAtInterrupt = FALSE;
if (m_pInterruptState)
{
bAtInterrupt = m_pInterruptState->AtInterruptTime();
}
m_bAsyncReadPending = TRUE;
theErr = m_pDataFile->SafeRead(ulCount, bAtInterrupt);
#endif /* #ifndef _MACINTOSH #else */
return theErr;
}
/************************************************************************
* Method:
* IHXFileObject::Write
* Purpose:
* Writes a buffer of data to the file and asynchronously notifies
* the caller via the IHXFileResponse interface passed in to Init,
* of the completeness of the operation.
*/
STDMETHODIMP CSimpleFileObject::Write(IHXBuffer* pBuffer)
{
if (m_nFd == -1 || !(m_ulFlags & HX_FILE_WRITE))
{
return HXR_UNEXPECTED;
}
pBuffer->AddRef();
#ifdef _MACINTOSH
BOOL bAtInterrupt = FALSE;
if (m_pInterruptState)
{
bAtInterrupt = m_pInterruptState->AtInterruptTime();
}
UINT32 actual = m_pDataFile->SafeWrite(pBuffer, bAtInterrupt);
#else
UINT32 actual = m_pDataFile->Write(pBuffer);
#endif
pBuffer->Release();
if (actual > 0)
{
m_ulPos += actual;
}
if(actual == pBuffer->GetSize())
m_pFileResponse->WriteDone(HXR_OK);
else
m_pFileResponse->WriteDone(HXR_FAILED);
return HXR_OK;
}
/************************************************************************
* Method:
* IHXFileObject::Seek
* Purpose:
* Seeks to an offset in the file and asynchronously notifies
* the caller via the IHXFileResponse interface passed in to Init,
* of the completeness of the operation.
*/
STDMETHODIMP CSimpleFileObject::Seek(ULONG32 ulOffset, BOOL bRelative)
{
MLOG_GEN(NULL, "CSimpleFileObject::Seek(%lu,%lu) this=0x%08x tick=%lu\n",
ulOffset, bRelative, this, HX_GET_BETTERTICKCOUNT());
HX_LOG_BLOCK( "CSimpleFileObject::Seek" );
if((m_nFd == -1) && m_bCanBeReOpened)
{
DPRINTF(0x5d000000, ("CSFO::Seek() -- _OpenFile()\n"));
_OpenFile(m_ulFlags);
}
if (m_nFd != -1)
{
/* remove any pending callbacks */
if (m_pStackCallback) m_pStackCallback->Cancel(m_pScheduler);
#if defined(HELIX_FEATURE_PROGDOWN)
// Seeks can interrupt other seeks, and cancel them
// out. Therefore, if we had scheduled a callback to
// handle a failed seek or a failed read, then we need
// to cancel that callback.
if (m_pProgDownMon && m_pProgDownMon->IsCallbackPending())
{
m_pProgDownMon->CancelCallback();
}
#endif /* #if defined(HELIX_FEATURE_PROGDOWN) */
AddRef(); // Make sure we do not destruct on possible ReadDone
/*
* Seek cancels pending Reads.
*/
if (m_bReadPending)
{
ActualAsyncReadDone(HXR_CANCELLED, NULL);
}
int whence = SEEK_SET;
if(bRelative)
whence = SEEK_CUR;
#ifndef _MACINTOSH
// Save the pending seek parameters
m_ulPendingSeekOffset = ulOffset;
m_usPendingSeekWhence = (UINT16) whence;
// Do the seek
HX_RESULT seekDoneResult = HXR_OK;
HX_RESULT result = DoSeek(seekDoneResult);
// Undo the AddRef();
Release();
return ((result == HXR_OK) ? seekDoneResult : result);
#else
BOOL bAtInterrupt = FALSE;
if (m_pInterruptState)
{
bAtInterrupt = m_pInterruptState->AtInterruptTime();
}
m_eSeekReason = EXTERNAL_SEEK;
HX_RESULT seekDoneResult = m_pDataFile->SafeSeek(ulOffset, whence, bAtInterrupt);
Release();
return seekDoneResult;
#endif
}
return HXR_UNEXPECTED;
}
HX_RESULT CSimpleFileObject::DoSeek(REF(HX_RESULT) rSeekDoneResult)
{
MLOG_PD(NULL, "CSimpleFileObject::DoSeek() this=0x%08x tick=%lu offset=%lu whence=%u\n",
this, HX_GET_BETTERTICKCOUNT(), m_ulPendingSeekOffset, m_usPendingSeekWhence);
HX_RESULT result = m_pDataFile->Seek(m_ulPendingSeekOffset,
m_usPendingSeekWhence);
if (result == HXR_OK)
{
if (m_usPendingSeekWhence == SEEK_SET)
{
m_ulPos = m_ulPendingSeekOffset;
}
else
{
m_ulPos += m_ulPendingSeekOffset;
}
}
#if defined(HELIX_FEATURE_PROGDOWN)
// For the purposes of progressive download, we
// will assume that seeking never fails. We will
// add the assert below to catch anytime it does.
// If we are finding that this assert is tripping,
// then we need to add equivalent support in DoSeek()
// for progressive download that we have in DoRead().
HX_ASSERT(SUCCEEDED(result));
#endif /* #if defined(HELIX_FEATURE_PROGDOWN) */
rSeekDoneResult = ActualAsyncSeekDone(result);
return result;
}
void CSimpleFileObject::SeekBackwards(UINT32 ulNumBytes)
{
if (m_pDataFile && ulNumBytes)
{
// Get the current offset
UINT32 ulCurOffset = m_pDataFile->Tell();
// Make sure the number of bytes we
// are supposed to back up is not greater
// than the current offset
if (ulNumBytes > ulCurOffset) ulNumBytes = ulCurOffset;
// Compute the new absolute offset
UINT32 ulNewOffset = ulCurOffset - ulNumBytes;
// Seek the data file to this offset
m_pDataFile->Seek(ulNewOffset, SEEK_SET);
}
}
HX_RESULT CSimpleFileObject::FinishDoRead(UINT32 actual, REF(IHXBuffer*) pBuffer)
{
/*
* If they get to the end of the file, then close it and reset.
*/
if (actual > 0 && pBuffer)
{
m_ulPos += actual;
}
#if defined(HELIX_FEATURE_PROGDOWN)
if (m_ulSize && (!m_bProgDownEnabled || (m_pProgDownMon && !m_pProgDownMon->HasBeenProgressive())))
#else
if (m_ulSize)
#endif
{
if(m_ulPos >= m_ulSize)
{
DPRINTF(0x5d000000, ("CSFO::Read() -- m_pDataFile->Close()\n"));
m_pDataFile->Close();
m_nFd = -1;
if (m_pDescriptorReg)
{
m_pDescriptorReg->UnRegisterDescriptors(1);
}
m_bCanBeReOpened = 1;
}
}
/* ignore return value from readdone! */
ActualAsyncReadDone((actual > 0 && pBuffer) ? HXR_OK : HXR_FAILED, pBuffer);
// Release our reference on the buffer!
HX_RELEASE(pBuffer);
return HXR_OK;
}
STDMETHODIMP CSimpleFileObject::InitDirHandler
(
IHXDirHandlerResponse* /*IN*/ pDirResponse
)
{
m_pDirResponse = pDirResponse;
m_pDirResponse->AddRef();
m_pDirResponse->InitDirHandlerDone(HXR_OK);
return HXR_OK;
}
STDMETHODIMP CSimpleFileObject::CloseDirHandler()
{
// Members must not be accessed after async ...Done() response
if (m_pDirResponse)
{
IHXDirHandlerResponse *pTmpDirResponse = m_pDirResponse;
m_pDirResponse = NULL;
pTmpDirResponse->CloseDirHandlerDone(HXR_OK);
pTmpDirResponse->Release();
}
return HXR_OK;
}
STDMETHODIMP CSimpleFileObject::MakeDir()
{
CHXString strFileName;
HX_RESULT retVal = HXR_OK;
UpdateFileNameMember();
GetFullPathname(m_pFilename, &strFileName);
#if defined (_WINDOWS ) || defined (_WIN32)
if (CreateDirectory(OS_STRING((const char*) strFileName), 0) == 0)
{
retVal = HXR_FAIL;
}
#elif defined (_UNIX)
if (mkdir((const char*) strFileName, 0755) < 0)
{
retVal = HXR_FAIL;
}
#elif defined (_MACINTOSH)
//XXXGH...don't know how to do this on Mac
retVal = HXR_FAIL;
#else
XHXDirectory* pHXDirectory = XHXDirectory::Construct(&m_pFileSystem->m_pCommonObj);
retVal = HXR_OUTOFMEMORY;
if (pHXDirectory)
{
retVal = HXR_FAIL;
pHXDirectory->SetPath((const char*) strFileName);
if (pHXDirectory->Create())
{
retVal = HXR_OK;
}
delete pHXDirectory;
}
#endif
m_pDirResponse->MakeDirDone(retVal);
return HXR_OK;
}
STDMETHODIMP CSimpleFileObject::ReadDir()
{
const char* pDirname = 0;
if (!m_pDirList)
{
CHXString strFileName;
UpdateFileNameMember();
GetFullPathname(m_pFilename, &strFileName);
m_pDirList =
CFindFile::CreateFindFile((const char*)strFileName, 0, "*");
if (!m_pDirList)
{
m_pDirResponse->ReadDirDone(HXR_FAIL, 0);
return HXR_OK;
}
pDirname = m_pDirList->FindFirst();
}
else
{
pDirname = m_pDirList->FindNext();
}
if (!pDirname)
{
delete m_pDirList;
m_pDirList = 0;
m_pDirResponse->ReadDirDone(HXR_FILE_NOT_FOUND, 0);
return HXR_OK;
}
HX_RESULT result;
if (!m_pCommonClassFactory)
{
result = m_pContext->QueryInterface(IID_IHXCommonClassFactory,
(void **)&m_pCommonClassFactory);
if (HXR_OK != result)
{
return result;
}
}
IHXBuffer* pBuffer = 0;
result = m_pCommonClassFactory->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::Stat
* Purpose:
* Collects information about the file that is returned to the
* caller in an IHXStat object
*/
STDMETHODIMP CSimpleFileObject::Stat(IHXFileStatResponse* pFileStatResponse)
{
MLOG_GEN(NULL, "CSimpleFileObject::Stat(0x%08x) this=0x%08x\n", pFileStatResponse, this);
HX_LOG_BLOCK( "CSimpleFileObject::Stat" );
struct stat StatBuffer;
CHXString strFileName;
#ifdef _MACINTOSH
// if fstat fails
#ifdef _MAC_MACHO
GetFullPathname(m_pFilename, &strFileName);
int res = stat(strFileName, &StatBuffer);
#else
int res = stat(m_pFilename, &StatBuffer);
#endif
if ( res != 0 )
{
// return failure code
return HXR_FAIL;
}
#else
if(m_nFd == -1)
{
CHXString strURL;
UpdateFileNameMember();
strURL = m_pFilename;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -