⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smlffpln.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
STDMETHODIMP CSmilFileFormat::ReadDone
(
    HX_RESULT		status,
    IHXBuffer*		pBuffer
)
{
    HX_RESULT result = HXR_OK;

    if ( SUCCEEDED(status) )
    {
	HX_ASSERT(pBuffer);

	// /For determining what type file this is (via namespace URI), we'll
	// hold onto the first pBuffer for later when we handle stream header:
	if (!m_pStartOfFile)
	{
	    pBuffer->AddRef();
	    m_pStartOfFile = pBuffer;
	}

	BreakUpBuffer(pBuffer);
	// recurse...
	m_pFileObject->Read(FileChunkSize);
    }
    else
    {
	// check see if we have a packet that needs added to the array.
	if ( m_pCurrentPacketData )
	{
	    UCHAR* pCb = m_pCurrentPacketData->pBuffer->GetBuffer();
	    pCb[m_ulCurrentBufferPos++] = '\"';
	    pCb[m_ulCurrentBufferPos++] = ')';
	    pCb[m_ulCurrentBufferPos++] = '\0';
	    m_pCurrentPacketData->pBuffer->SetSize(m_ulCurrentBufferPos);
	    m_pArrayOfPackets->Add((void*)m_pCurrentPacketData);
	    m_pCurrentPacketData = NULL;
	    m_ulCurrentBufferPos = 0;
	}
	// finished reading, calculate the number of packets to send:
	m_ulPacketCount = m_ulCurrentPacket;
	m_ulCurrentPacket = 0;
	m_state = Ready;
	m_pFFResponse->InitDone(result);
    }
    return result;
}


/////////////////////////////////////////////////////////////////////////
//  Method:
//	GetSMILFileVersion
//  Purpose:
//	This Function will break the buffer into packets.
//
//	This function maintains a state, such that multiple buffers should
//	Be able to be passed into it at any point...
//
HX_RESULT 
CSmilFileFormat::GetSMILFileVersion()
{
    HX_RESULT pnreslt = HXR_OK;
    const char* pSmilTag = NULL;
    const char* pCloseOfSmilTag = NULL;
    const char* pXmlns = NULL;
    const char* pXmlnsOpenQuotationMark = NULL;
    const char* pBuf = NULL;
    ULONG32 ulBufLen = 0;
    const char* pEqualsSign = NULL;
    const char* pTmp = NULL;
    char* pTmp2 = NULL;
    char* pszStartOfFile = NULL;
    ULONG32 ulCount = 0;
    LONG32 lNumCommentsOpen = 0;

    if (!m_pStartOfFile)
    {
	pnreslt = HXR_BUFFERTOOSMALL;
	goto cleanup;
    }

    // /Fixes PR 59282: m_pStartOfFile is not necessarily NULL-terminated,
    // so we have to limit our access of it to the size of the buffer (duh!):
    ulBufLen = m_pStartOfFile->GetSize();

    pBuf = (const char*)m_pStartOfFile->GetBuffer();

    if (!pBuf  ||  !ulBufLen)
    {
	pnreslt = HXR_BUFFERTOOSMALL;
	goto cleanup;
    }

    pszStartOfFile = new char[ulBufLen+1];
    if (!pszStartOfFile)
    {
	pnreslt = HXR_OUTOFMEMORY;
	goto cleanup;
    }

    // /Now, walk through and copy each character from non-NULL terminated buf:
    pTmp = pBuf; 
    pTmp2 = pszStartOfFile;
    while (*pTmp  &&  ulCount<ulBufLen)
    {
	*pTmp2 = *pTmp;
	pTmp++;
	pTmp2++;
	ulCount++;
    }
    pszStartOfFile[ulCount] = '\0'; // /NULL-terminate it.

    // /Now, let's walk through the start of pszStartOfFile looking for
    // namespace declaration(s) inside the <smil ...> tag, and make sure that
    // the smil tag is NOT inside of a comment:
    pTmp = pszStartOfFile;
    while (*pTmp)
    {
	if (0==strncmp(pTmp, "<!--", 4) )
	{
	    lNumCommentsOpen++;
	    pTmp+=4;
	}
	else if (0==strncmp(pTmp, "-->", 3) )
	{
	    lNumCommentsOpen--;
	    pTmp+=3;
	}
	else if (lNumCommentsOpen<=0  &&  0==strncmp(pTmp, "<smil", 5) )
	{
	    pSmilTag = pTmp; // /We found the smil tag outside of a comment.
	    break;
	}
	else
	{
	    pTmp++;
	}
    }
    if (!pSmilTag  ||  ulBufLen-(pSmilTag-pszStartOfFile) < 6) // /6==min size: "<smil>"
    {
	// /There had better be a <smil...> tag!
	pnreslt = HXR_UNEXPECTED;
	goto cleanup;
    }

    pCloseOfSmilTag = strchr(pSmilTag, '>');
    // /Add 6 so that we don't allow "<smilxmlns ..." (which is invalid):
    pXmlns = strstr(pSmilTag+6, "xmlns");
    if (pXmlns  &&  isspace(*(pXmlns-1)) ) // /"xmlns" must follow a space.
    {
	pEqualsSign = strchr(pXmlns, '=');
	if (pEqualsSign)
	{
	    pXmlnsOpenQuotationMark = strchr(pXmlns, '\"');
	}
    }
    if (pXmlns  &&   pEqualsSign  &&  pXmlnsOpenQuotationMark  &&
	    (!pCloseOfSmilTag  ||  pXmlns<pCloseOfSmilTag))
    {
	BOOL bIsValidNamespaceDeclaration = TRUE;

	// /First, make sure there is nothing but whitespace between
	// the "xmlns" and the '=' as well as between the '=' and the
	// quotation mark:
	char* pTmp = (char*)(pXmlns + strlen("xmlns"));
	while (pTmp<pEqualsSign)
	{
	    if (!isspace(*pTmp))
	    {
		bIsValidNamespaceDeclaration = FALSE;
		break;
	    }
	    pTmp++;
	}
	pTmp = (char*)(pEqualsSign+1);
	while(pTmp<pXmlnsOpenQuotationMark)
	{
	    if (!isspace(*pTmp))
	    {
		bIsValidNamespaceDeclaration = FALSE;
		break;
	    }
	    pTmp++;
	}

	if (bIsValidNamespaceDeclaration)
	{
	    // /Note: SMIL 1.0 namespace is default and is:
	    // "http://www.w3.org/TR/REC-smil".  Note that if this is
	    // tagged (first) with a SMIL 1.0 namespace followed by
	    // another namespace, then this is a 1.0 file and we'll let
	    // the 1.0 renderer get it and do what it can with the 2.0
	    // stuff (namely ignore it):
	    const char* pSMIL10Namespace = strstr(pXmlnsOpenQuotationMark,
		    "http://www.w3.org/TR/REC-smil\"");

	    // /This in the final SMIL 2.0 rec:
	    const char* pSMIL20Namespace = strstr(pXmlnsOpenQuotationMark,
		    "http://www.w3.org/2001/SMIL20/Language\"");

	    const char* pSMIL20NamespaceCandidateRec = strstr(
		    pXmlnsOpenQuotationMark,
		    "http://www.w3.org/2000/SMIL20/CR/Language\"");

	    // /Fixes PR 55749: allow new PR namespace:
	    const char* pSMIL20NamespaceProposedRec = strstr(
		    pXmlnsOpenQuotationMark,
		    "http://www.w3.org/2001/SMIL20/PR/Language\"");

	    const char* pSMIL20NamespaceLastCall = strstr(
		    pXmlnsOpenQuotationMark,
		    "http://www.w3.org/TR/REC-smil/2000/SMIL20/LC/\"");

	    // /If the SMIL 1.0 namespace is declared prior to any other
	    // version of SMIL's namespace, then this is a SMIL 1.0 doc:
	    if (pSMIL10Namespace  &&  (!pSMIL20Namespace  ||
		    pSMIL10Namespace < pSMIL20Namespace)  &&
		    (!pSMIL20NamespaceCandidateRec  ||
		    pSMIL10Namespace < pSMIL20NamespaceCandidateRec)  &&
		    (!pSMIL20NamespaceProposedRec  ||
		    pSMIL10Namespace < pSMIL20NamespaceProposedRec)  &&
		    (!pSMIL20NamespaceLastCall  ||
		    pSMIL10Namespace < pSMIL20NamespaceLastCall) )
	    {
		m_smilFileVersion = SMILFileVersionSmil10Strict;
	    }
	    else if (pSMIL20NamespaceCandidateRec  &&  (!pSMIL20Namespace  ||
		    pSMIL20NamespaceCandidateRec < pSMIL20Namespace))
	    {
		m_smilFileVersion = SMILFileVersionSmil20PreRec;
	    }
	    else if (pSMIL20NamespaceProposedRec  &&  (!pSMIL20Namespace ||
		    pSMIL20NamespaceProposedRec < pSMIL20Namespace))
	    {
		m_smilFileVersion = SMILFileVersionSmil20PreRec;
	    }
	    // /Treat both LC (Last Call) and CR (Candidate Rec) as "PreRec":
	    else if (pSMIL20NamespaceLastCall  &&  (!pSMIL20Namespace  ||
		    pSMIL20NamespaceLastCall < pSMIL20Namespace))
	    {
		m_smilFileVersion = SMILFileVersionSmil20PreRec;
	    }
	    else if (pSMIL20Namespace)
	    {
		m_smilFileVersion = SMILFileVersionSmil20;
	    }
	    else
	    {
		m_smilFileVersion = SMILFileVersionUnknown;
	    }
	}
    }

cleanup:
    if (pszStartOfFile)
    {
	HX_VECTOR_DELETE(pszStartOfFile);
    }

    return pnreslt;
}


/////////////////////////////////////////////////////////////////////////
//  Method:
//	BreakUpBuffer
//  Purpose:
//	This Function will break the buffer into packets.
//
//	This function maintains a state, such that multiple buffers should
//	Be able to be passed into it at any point...
//

// XXX  jhug
// This doesn't allow text between tags... Future versions of SMIL might
// support this... this will need a bit of a modification.
HX_RESULT 
CSmilFileFormat::BreakUpBuffer(IHXBuffer* pBuffer)
{
    // walk through the buffer and escape all \"s
    // also forget about all white space and comments...
    // also break the buffer up into packets for easy access.

    HX_RESULT result = HXR_OK;

    UCHAR* pCb = NULL;
    if ( m_pCurrentPacketData )
    {
	pCb = m_pCurrentPacketData->pBuffer->GetBuffer();
    }

    const UCHAR* pData = pBuffer->GetBuffer();
    UINT32 ulSize = pBuffer->GetSize();
    for ( UINT32 ulPos = 0; ulPos < ulSize && pData[ulPos]; ++ulPos )
    {
	// three for the end of the packet structure, and 1 in case we have 
	// to escape a char...
	if ( m_ulCurrentBufferPos >= MaxPacketSize - 4 ) 
	{
	    pCb[m_ulCurrentBufferPos++] = '\"';
	    pCb[m_ulCurrentBufferPos++] = ')';
	    pCb[m_ulCurrentBufferPos++] = '\0';
	    m_pCurrentPacketData->pBuffer->SetSize(m_ulCurrentBufferPos);
	    m_pArrayOfPackets->Add((void*)m_pCurrentPacketData);
	    m_pCurrentPacketData = NULL;
	    m_ulCurrentBufferPos = 0;
	    pCb = NULL;
	}

	if ( !m_pCurrentPacketData )
	{
	    m_pCurrentPacketData = new PacketData;
	    if ( m_pCurrentPacketData == NULL )
	    {
		result = HXR_OUTOFMEMORY;
	    }
	    else
	    {
		m_pCurrentPacketData->pBuffer = NULL;
		m_pCurrentPacketData->pNumPos = NULL;
		result = m_pCommonClassFactory->CreateInstance(CLSID_IHXBuffer, 
			(void**)&m_pCurrentPacketData->pBuffer);
	    }
	    if ( SUCCEEDED(result) )
	    {
		result = m_pCurrentPacketData->pBuffer->SetSize(MaxPacketSize);
	    }
	    if ( SUCCEEDED(result) )
	    {
		pCb = m_pCurrentPacketData->pBuffer->GetBuffer();
		//memset(pCb, 0xef, MaxPacketSize);
		sprintf((char*)pCb, "(smil-document (ver %s)(npkt %ld)"
		    "(ttlpkt 0     )(doc \"", 
		    RMA_DRIVER_VERSION, ++m_ulCurrentPacket);
		m_ulCurrentBufferPos = strlen((char*)pCb);
		// back up to the begining of the total number position.
		// 13 is position back in header...
		m_pCurrentPacketData->pNumPos = (char*)pCb + 
		    m_ulCurrentBufferPos - 13; 
	    }
	}

	if ( FAILED(result) )
	{
	    break;
	}
	switch ( m_fileState )
	{
	case InContent:
	    {
		if ( pData[ulPos] == '\"' )
		{
		    pCb[m_ulCurrentBufferPos++] = '\\';
		    pCb[m_ulCurrentBufferPos++] = '\"';
		}
		else if ( pData[ulPos] == '\\' )
		{
		    pCb[m_ulCurrentBufferPos++] = '\\';
		    pCb[m_ulCurrentBufferPos++] = '\"';
		}
		else if ( pData[ulPos] == '<' )
		{
		    if ( pData[ulPos+1] == '!' )
		    {
			if ( pData[ulPos+2] == '-'
			    && pData[ulPos+3] == '-' )
			{
			    ulPos += 3;
			    m_fileState = InComment;
			}
			else if ( pData[ulPos+2] == '[' && 
				  pData[ulPos+3] == 'C' &&
				  pData[ulPos+4] == 'D' &&
				  pData[ulPos+5] == 'A' &&
				  pData[ulPos+6] == 'T' &&
				  pData[ulPos+7] == 'A' &&
				  pData[ulPos+8] == '[' )
			{
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos];
			    m_fileState = InCDATA;
			}
			else if ( pData[ulPos+2] == 'D' && 
				  pData[ulPos+3] == 'O' &&
				  pData[ulPos+4] == 'C' &&
				  pData[ulPos+5] == 'T' &&
				  pData[ulPos+6] == 'Y' &&
				  pData[ulPos+7] == 'P' &&
				  pData[ulPos+8] == 'E' )
			{
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos++];
			    pCb[m_ulCurrentBufferPos++] = pData[ulPos];
			    m_fileState = InDTD;
			}
		    }
		    else
		    {
			pCb[m_ulCurrentBufferPos++] = pData[ulPos];
			m_fileState = InTagName;
		    }
		}
		// preserve all lines so line number error reporting is
		// accurate
		else if ( isspace(pData[ulPos]) && pData[ulPos] != '\n'  &&
			pData[ulPos] != '\r')
		{
		    //continue...
		}
		//If we find \rx where x is not \n, then keep it else let
		// the next char (\n) be kept in the next iteration of
		// this loop.  This accomodates Mac-authored '\r'-only
		// text.  Think Different (pain is "different").
		else if (isspace(pData[ulPos])  &&  ('\r' == pData[ulPos]  &&
			(ulPos+1 < ulSize  &&  pData[ulPos+1])  &&
			'\n' == pData[ulPos+1]) )
		{
		    //continue...
		}
		else
		{
		    if ('\r' == pData[ulPos])
		    {
			pCb[m_ulCurrentBufferPos++] = '\n';
		    }
		    else
		    {
			pCb[m_ulCurrentBufferPos++] = pData[ulPos];
		    }
		}
	    }
	    break;
	case InDTD:
	    {
		if ( pData[ulPos] == '[' )
		{
		    m_fileState = InDTDMarkup;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -