📄 riff.cpp
字号:
m_levelInfo[m_ulLevel].m_nextChunkOffset -= m_ulSizeDiff; m_ulChunkType = m_ulFindChunkId; if ( m_ulFindChunkId == LIST_CHUNK_ID ) { m_state = RS_GetListTypePending; 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;}STDMETHODIMPCRIFFReader::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_RESULTCRIFFReader::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);}UINT32CRIFFReader::IsThreadSafe(){ return HX_THREADSAFE_METHOD_FSR_READDONE;}HX_RESULTCRIFFReader::FileSeek(UINT32 offset){ m_ulSeekOffset = offset; m_state = RS_UserSeekPending; return m_pFileObject->Seek(m_ulSeekOffset, FALSE);}HX_RESULTCRIFFReader::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_RESULTCRIFFReader::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;}STDMETHODIMPCRIFFReader::CloseDone(HX_RESULT status){ return HXR_OK;}STDMETHODIMPCRIFFReader::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. */STDMETHODIMPCRIFFReader::FileObjectReady(HX_RESULT status,IHXFileObject* pFileObject){ return HXR_OK;}HX_RESULTCRIFFReader::InternalClose(){ return HXR_OK;}HX_RESULTCRIFFReader::Read(UINT32 len){ // Read from the file on our owner's behalf m_state = RS_DataReadPending; return m_pFileObject->Read(len);}UINT32CRIFFReader::GetListType(){ return m_ulChunkSubType;}UINT32CRIFFReader::GetOffset(){ return m_ulCurOffset;}UINT32CRIFFReader::FileType(){ return m_ulFileType;}UINT32CRIFFReader::FileSubtype(){ return m_ulSubFileType;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -