📄 rtffplin.cpp
字号:
AddRef(); *ppvObj = (IHXFileMimeMapperResponse*)this; return HXR_OK; } else if (IsEqualIID(riid, IID_IHXFileViewSource)) { CRTViewSource* pVsrc = new CRTViewSource(m_pContext, (IUnknown*)(IHXPlugin*)this); if ( pVsrc == NULL ) { return HXR_FAIL; } return pVsrc->QueryInterface(riid, ppvObj); } *ppvObj = NULL; return HXR_NOINTERFACE;}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::AddRef// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) CRealTextFileFormat::AddRef(){ return InterlockedIncrement(&m_lRefCount);}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::Release// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) CRealTextFileFormat::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}// *** IHXFileFormatObject methods ***STDMETHODIMP CRealTextFileFormat::InitFileFormat( IHXRequest* /*IN*/ pRequest, IHXFormatResponse* /*IN*/ pFormatResponse, IHXFileObject* /*IN*/ pFileObject){ m_pRequest = pRequest; BOOL bIsBeta1Player = ::IsBeta1Player(m_pRequest); SetIsBeta1Player(bIsBeta1Player); m_pFFResponse = pFormatResponse; m_pFileObject = pFileObject; m_pRequest->AddRef(); m_pFFResponse->AddRef(); m_pFileObject->AddRef(); // This file format is not a container type, so it only supports one // stream and therefore one header, but before we do that, we want to // make sure the file object is initialized; we can't actually return // the header count until the file init is done... (See InitDone). m_state = InitPending; // Note, we need to pass ourself to the FileObject, because this is its // first oppurtunity to know that we implement the IHXFileResponse // interface it will call for completed pending operations //killed this per Joe R and set the flag to HX_FILE_READ: // m_pFileObject->SetURL(m_pURL); return m_pFileObject->Init( HX_FILE_READ | HX_FILE_BINARY, this);} STDMETHODIMP CRealTextFileFormat::Close(){ if (m_pContext) { m_pContext->Release(); m_pContext = 0; } if (m_pRegistry) { m_pRegistry->Release(); m_pRegistry = 0; } if (m_pErrorMessages) { m_pErrorMessages->Release(); m_pErrorMessages = 0; } if (m_pFileObject) { m_pFileObject->Close(); m_pFileObject->Release(); m_pFileObject = 0; } if (m_pFFResponse) { m_pFFResponse->Release(); m_pFFResponse = 0; } if (m_pRequest) { m_pRequest->Release(); m_pRequest = NULL; } if (m_pSavedDataFromLastRead) { m_pSavedDataFromLastRead->Release(); m_pSavedDataFromLastRead = NULL; }#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile) { if(m_txtWin.getDebugFlags()&RT_FF_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"\nCRealTextFileFormat::Close()\n"); } fclose(m_logfile); m_logfile=NULL; }#endif#endif HX_RELEASE(m_pFileStatObj); m_ulTotalFileSizeInBytes = 0L; HX_VECTOR_DELETE(m_pszFileMimeType); return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::GetFileHeader// Purpose:// Called by controller to ask the file format for the number of// headers in the file. The file format should call the // IHXFileFormatSession::HeaderCountReady() for the IHXFileFormat-// Session object that was passed in during initialization, when the// header count is available.//STDMETHODIMP CRealTextFileFormat::GetFileHeader(){ // If we are not ready then something has gone wrong if (m_state != Ready) return HXR_UNEXPECTED; // Since this is asyncronous we need to note our state so we can // correctly respond to the seek complete response from the file // object. m_state = GetFileHeaderSeekPending; // Actually seek... m_pFileObject->Seek(HEADER_OFFSET, FALSE); // See SeekDone() for next "step" of the GetFileHeader process. return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::GetStreamHeader// Purpose:// Called by controller to ask the file format for the header for// a particular stream in the file. The file format should call // IHXFileFormatSession::StreamHeaderReady() for IHXFileFormatSession// object that was passed in during initialization, when the header// is available.//STDMETHODIMP CRealTextFileFormat::GetStreamHeader(UINT16 unStreamNumber){ // If we are not ready then something has gone wrong if (m_state != Ready) return HXR_UNEXPECTED; // If RealText is not licensed, log an error and return if (!m_bRealTextLicensed) { ReportError(IDS_ERR_RT_NOTLICENSED, HXR_NOT_LICENSED); m_pFFResponse->StreamHeaderReady(HXR_NOT_LICENSED, NULL); return HXR_OK; } // To give the header we need to be make sure the file is positioned // at the start of the file. We need to call the file object's // seek method. // Since this is asyncronous we need to note our state so we can // correctly respond to the seek complete response from the file // object. m_state = GetStreamHeaderSeekPending; // Actually seek... m_pFileObject->Seek(HEADER_OFFSET, FALSE); // See SeekDone() for next "step" of the GetStreamHeader process. return HXR_OK;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::GetPacket// Purpose:// Called by controller to ask the file format for the next packet// for a particular stream in the file. The file format should call // IHXFileFormatSession::PacketReady() for the IHXFileFormatSession// object that was passed in during initialization, when the packet// is available.//STDMETHODIMP CRealTextFileFormat::GetPacket(UINT16 unStreamNumber){ HX_RESULT result = HXR_OK; m_bCurPacketHasREQUIREDContents = FALSE; // If we are not ready then something has gone wrong if (m_state != Ready) return HXR_UNEXPECTED; if (!m_bHeaderSent) { result = HXR_UNEXPECTED; } else { // We are being asked to get the next packet and we have sent // the header, but we need to back up before we get the next // PACKET_SIZE bytes because the header varies in size and is // smaller than what was read. // Since this is asyncronous we need to note our state so we can // correctly respond to the seek complete response from the file // object. //If the next packet seek point is less than or equal to the last // byte parsed in the file, then we know we are seeking backwards // in time (and thus backwards into the file); the only exception // is if nothing has been parsed yet, i.e., last byte parsed==0 and // the next packet seek point is zero, i.e., there was no header // tag and the first text appears at byte zero. (Logically, this // exception case is equivalent to one OR the other var being !=0): if(m_ulNextPacketSeekPoint <= m_ulLastByteParsedInFile && (m_ulLastByteParsedInFile || m_ulNextPacketSeekPoint)) { m_state = GetPacketStillBackedUpSeekPending; //Calculate start and end byte of next packet: ULONG32 ulPktEndByte; ULONG32 ul_retval = 0L; if(m_pTextWindow->m_pTLList) { ul_retval = m_pTextWindow->m_pTLList-> makeReasonableSizedPacketFromTextLinesAtStartByte( m_ulNextPacketSeekPoint, &ulPktEndByte, &m_bCurPacketHasREQUIREDContents, &m_pCurTextLine); } HX_ASSERT(ul_retval); //this should never be zero here. if(!ul_retval) { //then there is nothing to send that's valid at time ulOffset // (or later since it gets later stuff if none is valid now), // so we've either read the whole file or need to read more: m_ulSizeOfNextReadAfterSeek = MAX_PACKET_SIZE; m_state = SeekSeekTooFarFwdPending; m_ulNextPacketSeekPoint = m_ulLastByteParsedInFile + 1L; m_pFileObject->Seek(m_ulNextPacketSeekPoint, FALSE); } else { // Note that the real time we are seeking to is not exactly // what was requested... //XXXEH- this should be set to the start time of pkt data // (which will always be less than or equal to ulOffset): HX_ASSERT_VALID_PTR(m_pCurTextLine); m_ulCurrentTime = (m_pCurTextLine!=NULL? m_pCurTextLine->getStartTime() : m_ulCurrentTime); m_ulSizeOfNextReadAfterSeek = 1L + ulPktEndByte - m_ulNextPacketSeekPoint;#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_FF_DEBUG_FLAGS_MASK) { fprintf(m_logfile, "GetPacket-Seek to %lu, " "GetPacketStillBackedUpSeekPending\n", m_ulNextPacketSeekPoint); fflush(m_logfile); }#endif#endif // Actually seek... m_pFileObject->Seek(HEADER_OFFSET+m_ulNextPacketSeekPoint, FALSE); // See SeekDone() for next "step" of the Seek() process. } } else {#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_FF_DEBUG_FLAGS_MASK) { fprintf(m_logfile, "GetPacket-Seek to %lu, GetPacketSeekPending\n", HEADER_OFFSET+m_ulNextPacketSeekPoint); fflush(m_logfile); }#endif#endif m_state = GetPacketSeekPending; m_pFileObject->Seek(HEADER_OFFSET+m_ulNextPacketSeekPoint,FALSE); } // See SeekDone() for next "step" of the GetPacket process. } return result;}/////////////////////////////////////////////////////////////////////////// Method:// IHXFileFormatObject::Seek// Purpose:// Called by controller to tell the file format to seek to the // nearest packet to the requested offset. The file format should // call IHXFileFormatSession::SeekDone() for the IHXFileFormat-// Session object that was passed in during initialization, when // the seek has completed.//STDMETHODIMP CRealTextFileFormat::Seek(ULONG32 ulOffset){ // If we are not ready then something has gone wrong // if (m_state != Ready) return HXR_UNEXPECTED; /* This was wrong. We can be waiting for a Read request to * complete when we get a Seek request. In which case, we should * drop whatever we were waiting for, and assume the filesystem * will do the same when it gets our seek request. */ // Notice that the seek is passed as time in milliseconds, we // need to convert this to our packet number and its offset // in the file... // To actually seek to the correct place in the time line, // we will seek in the file. We need to call the file object's // seek method. // /Fixes PR 95127 by removing the plain-text's ignoring of this Seek(); // if this is plain text, then go ahead and follow the same seek logic as // for RealText, noting that we're going to resend the whole file since // everything in the file has a begin of zero. // Since this is asyncronous we need to note our state so we can // correctly respond to the seek complete response from the file // object. m_state = SeekSeekPending; //Calculate start and end byte of next packet: ULONG32 ulPktStartByte, ulPktEndByte; ULONG32 ul_retval = 0L; m_ulStartTimeOfTextOfPriorPacket = 0L; if(m_pTextWindow->m_pTLList) { //XXXEH- change this function so it never makes a packet that's too // big; if it just makes a reasonable-sized one and there are still // some TextLines that need to be sent, we'll get called back with // GetPacket() until the time stamp of the packet is greater than // the seek time, so it WILL all get sent: ul_retval = m_pTextWindow->m_pTLList-> findBoundingStartAndEndBytesOfActiveTextLines( ulOffset, &ulPktStartByte, &ulPktEndByte, &m_pCurTextLine); } if(!ul_retval) { //then there is nothing to send that's valid at time ulOffset (or // later since it gets later stuff if none is valid now), // so we've either read the whole file or we need to read more: m_ulSizeOfNextReadAfterSeek = MAX_PACKET_SIZE; m_state = SeekSeekTooFarFwdPending; m_ulCurrentTime = ulOffset;#ifdef _DEBUG#if defined(RT_OUTPUT_LOGFILE) if(m_logfile && m_txtWin.getDebugFlags()&RT_FF_DEBUG_FLAGS_MASK) { fprintf(m_logfile,"Seek fwd to byte %lu in file at time: %lu\n", m_ulLastByteParsedInFile+1L, m_ulCurrentTime); fflush(m_logfile); }#endif#endif m_pFileObject->Seek(m_ulLastByteParsedInFile + 1L, FALSE); } else { // Note that the real time we are seeking to is not exactly what // was requested... //XXXEH- this should be set to the start time of pkt data (which // will always be less than or equal to ulOffset):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -