📄 riff.cpp
字号:
m_pFileObject->Read(sizeof(UINT32));
}
else
{
m_state = RS_Ready;
m_pResponse->RIFFFindChunkDone(status,
m_ulChunkBodyLen - m_ulSizeDiff);
}
return status;
}
else
{
// Didn't find it, go to the next chunk.
m_state = RS_ChunkBodySeekPending;
m_ulSeekOffset = m_ulCurOffset + GetLong(&buf[4]);
/* Are we at the end of .rm file */
if ( m_ulSeekOffset == m_ulCurOffset &&
m_ulFileType != RIFF_FILE_MAGIC_NUMBER &&
m_ulFileType != IFF_FILE_MAGIC_NUMBER )
{
m_pResponse->RIFFFindChunkDone(HXR_FAILED, 0);
return HXR_OK;
}
if ( m_ulFileType == RIFF_FILE_MAGIC_NUMBER ||
m_ulFileType == IFF_FILE_MAGIC_NUMBER )
{
// Make sure the seek offset is aligned(2 bytes)
uRem = (UINT16)(m_ulSeekOffset % 2);
if ( uRem != 0 )
{
m_ulSeekOffset += 1;
}
}
m_ulSeekOffset -= m_ulSizeDiff;
if ( m_ulSeekOffset == m_ulCurOffset )
{
m_state = RS_ChunkHeaderReadPending;
return m_pFileObject->Read(sizeof(UINT32) * 2);
}
m_state = RS_ChunkBodySeekPending;
return m_pFileObject->Seek(m_ulSeekOffset, FALSE);
}
case RS_GetListTypePending:
if ( len != sizeof(UINT32) )
{
m_state = RS_Ready;
m_pResponse->RIFFFindChunkDone(HXR_FAILED, 0);
return HXR_UNEXPECTED;
}
m_ulChunkSubType = getlong(buf);
m_state = RS_Ready;
m_pResponse->RIFFFindChunkDone(status, m_ulChunkBodyLen);
return HXR_OK;
case RS_ReadChunkHeaderPending:
{
if ( HXR_OK != status )
{
m_state = RS_Ready;
m_pResponse->RIFFGetChunkDone(HXR_FAILED, 0, NULL);
return HXR_OK;
}
m_ulGetChunkType = (UINT32)getlong(buf);
m_state = RS_ReadChunkBodyPending;
LONG32 baseLen = GetLong(&buf[4]);
if ( (m_ulFileType == RIFF_FILE_MAGIC_NUMBER) &&
(m_ulGetChunkType == (UINT32)0) )
{
m_state = RS_Ready;
m_pResponse->RIFFGetChunkDone(HXR_FAILED, 0, NULL);
return HXR_OK;
}
if ( baseLen == 0 )
{
m_state = RS_Ready;
m_pResponse->RIFFGetChunkDone(HXR_OK, m_ulGetChunkType, NULL);
return HXR_OK;
}
HX_RESULT resultOfRead = HXR_OK;
#ifdef CHUNK_READ_SIZE_LIMIT
// If the chunk is greater than MAX_READ_SIZE, we break the
// read into smaller portions to improve performance under the
// Simple File System:
if (baseLen > MAX_READ_SIZE)
{
IHXCommonClassFactory* pClassFactory = NULL;
if (m_pContext && SUCCEEDED(m_pContext->QueryInterface(IID_IHXCommonClassFactory,
(void**) &pClassFactory)))
{
pClassFactory->CreateInstance(IID_IHXBuffer, (void**) &m_pReassemblyBuffer);
}
if (m_pReassemblyBuffer)
{
m_pReassemblyBuffer->SetSize(baseLen);
m_ulChunkBytesRead = 0;
m_ulChunkSize = baseLen;
// Here we munge baselen in the interests of code
// simplicity:
baseLen = MAX_READ_SIZE;
}
}
#endif // CHUNK_READ_SIZE_LIMIT
if ( m_ulFileType == RIFF_FILE_MAGIC_NUMBER ||
m_ulFileType == IFF_FILE_MAGIC_NUMBER )
{
// Make sure the chunk is aligned(2 bytes)
uRem = (UINT16)((baseLen) % 2);
//NOTE: if m_ulCurOffset is greater than 0x7FFFFFFF, GetLong
// returns a negative number. Any negative number % 2 (at
// least in Windows) returns 0 or -1, and ((UINT16)-1) == 0xFFFF
// so uRem thus can be one of the following: {0, 1, 0xFFFF}.
// The following if() conditional will, however, still work as
// expected:
if ( uRem != 0 )
{
m_ulFileSpecifiedReadSize = baseLen;
resultOfRead = m_pFileObject->Read(baseLen+1);
}
else
{
m_ulFileSpecifiedReadSize = baseLen;
resultOfRead = m_pFileObject->Read(baseLen);
}
}
else
{
m_ulFileSpecifiedReadSize = baseLen;
resultOfRead = m_pFileObject->Read(baseLen);
}
return resultOfRead;
}
case RS_ReadChunkBodyPending:
#ifdef CHUNK_READ_SIZE_LIMIT
if (m_pReassemblyBuffer)
{
BYTE* pAssemblyStart = m_pReassemblyBuffer->GetBuffer();
HX_ASSERT(pAssemblyStart);
HX_ASSERT(m_ulChunkSize - m_ulChunkBytesRead >= pBuffer->GetSize());
UINT32 ulBytesToCopy = pBuffer->GetSize();
if (pBuffer->GetSize() > m_ulChunkSize - m_ulChunkBytesRead)
ulBytesToCopy = m_ulChunkSize - m_ulChunkBytesRead;
memcpy(pAssemblyStart + m_ulChunkBytesRead, pBuffer->GetBuffer(), /* Flawfinder: ignore */
ulBytesToCopy);
m_ulChunkBytesRead += pBuffer->GetSize();
if (m_ulChunkBytesRead == m_ulChunkSize || FAILED(status) ||
pBuffer->GetSize() == 0)
{
m_state = RS_Ready;
IHXBuffer* pOldBuffer = m_pReassemblyBuffer;
m_pReassemblyBuffer = NULL;
m_pResponse->RIFFGetChunkDone(status, m_ulGetChunkType, pOldBuffer);
HX_RELEASE(pOldBuffer);
return HXR_OK;
}
else
{
UINT32 baseLen = m_ulChunkSize - m_ulChunkBytesRead;
if (baseLen > MAX_READ_SIZE)
{
baseLen = MAX_READ_SIZE;
}
HX_RESULT resultOfRead = HXR_OK;
if ( m_ulFileType == RIFF_FILE_MAGIC_NUMBER ||
m_ulFileType == IFF_FILE_MAGIC_NUMBER )
{
// Make sure the chunk is aligned(2 bytes)
uRem = (UINT16)((baseLen) % 2);
//NOTE: if m_ulCurOffset is greater than 0x7FFFFFFF, GetLong
// returns a negative number. Any negative number % 2 (at
// least in Windows) returns 0 or -1, and ((UINT16)-1) == 0xFFFF
// so uRem thus can be one of the following: {0, 1, 0xFFFF}.
// The following if() conditional will, however, still work as
// expected:
if ( uRem != 0 )
{
m_ulFileSpecifiedReadSize = baseLen;
resultOfRead = m_pFileObject->Read(baseLen+1);
}
else
{
m_ulFileSpecifiedReadSize = baseLen;
resultOfRead = m_pFileObject->Read(baseLen);
}
}
else
{
m_ulFileSpecifiedReadSize = baseLen;
resultOfRead = m_pFileObject->Read(baseLen);
}
return resultOfRead;
}
}
#endif // CHUNK_READ_SIZE_LIMIT
m_state = RS_Ready;
m_pResponse->RIFFGetChunkDone(status, m_ulGetChunkType, pBuffer);
return HXR_OK;
case RS_DataReadPending:
m_state = RS_Ready;
return m_pResponse->RIFFReadDone(status, pBuffer);
default:
//m_state = RS_Ready;
return HXR_UNEXPECTED;
}
return status;
}
STDMETHODIMP
CRIFFReader::SeekDone(HX_RESULT status)
{
/* This may happen in HTTP streaming when the file system
* is in still a seeking mode when the next seek is issued.
* The file system will then call SeekDone with a status of
* HXR_CANCELLED for the pending seek.
*/
if ( status == HXR_CANCELLED )
{
return HXR_OK;
}
if ( status == HXR_OK )
{
m_ulCurOffset = m_ulSeekOffset;
}
HX_RESULT result = HXR_OK;
switch ( m_state )
{
case RS_ChunkBodySeekPending:
m_state = RS_ChunkHeaderReadPending;
result = m_pFileObject->Read(sizeof(UINT32) + sizeof(UINT32));
return(HXR_OK == status? result:status);
case RS_FileStartSeekPending:
m_state = RS_ChunkHeaderReadPending;
result = m_pFileObject->Read(sizeof(UINT32) + sizeof(UINT32));
return(HXR_OK == status? result:status);
case RS_AscendSeekPending:
m_state = RS_Ready;
result = m_pResponse->RIFFAscendDone(status);
return(HXR_OK == status? result:status);
case RS_UserSeekPending:
m_state = RS_Ready;
result = m_pResponse->RIFFSeekDone(status);
return(HXR_OK == status? result:status);
default:
return HXR_UNEXPECTED;
}
}
HX_RESULT
CRIFFReader::Seek(UINT32 offset, BOOL bRelative)
{
m_ulSeekOffset = bRelative ?
m_ulCurOffset + offset :
m_ulThisChunkOffset + offset;
m_state = RS_UserSeekPending;
return m_pFileObject->Seek(m_ulSeekOffset, FALSE);
}
UINT32
CRIFFReader::IsThreadSafe()
{
return HX_THREADSAFE_METHOD_FSR_READDONE;
}
HX_RESULT
CRIFFReader::FileSeek(UINT32 offset)
{
m_ulSeekOffset = offset;
m_state = RS_UserSeekPending;
return m_pFileObject->Seek(m_ulSeekOffset, FALSE);
}
HX_RESULT
CRIFFReader::Descend()
{
if ( m_ulLevel > 0 && m_ulChunkType != LIST_CHUNK_ID )
{
m_pResponse->RIFFDescendDone(HXR_FAILED);
return HXR_UNEXPECTED;
}
m_ulLevel++;
m_levelInfo[m_ulLevel].m_startOffset = m_ulCurOffset;
m_levelInfo[m_ulLevel].started = FALSE;
return m_pResponse->RIFFDescendDone(HXR_OK);
}
HX_RESULT
CRIFFReader::Ascend()
{
m_ulLevel--;
m_state = RS_AscendSeekPending;
if ( m_ulLevel == 0 )
m_ulSeekOffset = 0;
else
{
m_ulSeekOffset = m_levelInfo[m_ulLevel].m_nextChunkOffset;
}
m_pFileObject->Seek(m_ulSeekOffset, FALSE);
return HXR_NOTIMPL;
}
STDMETHODIMP
CRIFFReader::CloseDone(HX_RESULT status)
{
return HXR_OK;
}
STDMETHODIMP
CRIFFReader::WriteDone(HX_RESULT status)
{
return HXR_NOTIMPL;
}
/************************************************************************
* Method:
* IHXFileResponse::FileObjectReady
* Purpose:
* Notification interface provided by users of the IHXFileObject
* interface. This method is called by the IHXFileObject when the
* requested FileObject is ready. It may return NULL with
* HX_RESULT_FAIL if the requested filename did not exist in the
* same pool.
*/
STDMETHODIMP
CRIFFReader::FileObjectReady
(
HX_RESULT status,
IHXFileObject* pFileObject)
{
return HXR_OK;
}
HX_RESULT
CRIFFReader::InternalClose()
{
return HXR_OK;
}
HX_RESULT
CRIFFReader::Read(UINT32 len)
{
// Read from the file on our owner's behalf
m_state = RS_DataReadPending;
return m_pFileObject->Read(len);
}
UINT32
CRIFFReader::GetListType()
{
return m_ulChunkSubType;
}
UINT32
CRIFFReader::GetOffset()
{
return m_ulCurOffset;
}
UINT32
CRIFFReader::FileType()
{
return m_ulFileType;
}
UINT32
CRIFFReader::FileSubtype()
{
return m_ulSubFileType;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -