📄 smlffpln.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#define INITGUID
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "smlffpln.ver"
#include "hxtypes.h"
#include "hxcom.h"
#include "hxcomm.h"
#include "ihxpckts.h"
#include "hxfiles.h"
#include "hxformt.h"
#include "hxengin.h"
#include "hxplugn.h"
#include "hxpends.h"
#include "hxasm.h"
#include "hxprefs.h"
#include "hxvsrc.h" /*IHXFileViewSource*/
#include "chxfgbuf.h" /*CHXFragmentedBuffer */
#include "hxmon.h"
#include "hxerror.h"
#include "hxstack.h"
#include "hxslist.h"
#include "hxstring.h"
#include "chxpckts.h"
#include "hxurl.h"
#include "hxver.h"
#include "verutil.h"
#include "perplex.h"
#include "xmlreslt.h"
#include "smlpkt.h"
#include "smlffpln.h"
#if defined(HELIX_FEATURE_VIEWSOURCE)
#include "escsmil.h" /* CEscapeSMIL */
#include "shadvsrc.h" /* CShadowViewSource */
#endif /* #if defined(HELIX_FEATURE_VIEWSOURCE) */
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
#ifdef _AIX
#include "dllpath.h"
ENABLE_MULTILOAD_DLLACCESS_PATHS(Smlffplin);
#endif
//#define DUMPFILEFORMATOUTPUT 1
static const UINT32 FileChunkSize = 10000; //XXXBAB adjust
static const UINT32 MaxPacketSize = 1000;
#define XML_BAD_ATTRIBUTE_NAME "SMIL Parse Error: Error in attribute name"
#define XML_BAD_TAG_NAME "SMIL Parse Error: Bad Tag Name"
#define XML_MISSING_ATTRIBUTE_VALUE "SMIL Parse Error: Attribute value is missing"
#define XML_NO_CLOSE_QUOTE "SMIL Parse Error: No closing quote"
#define XML_MISSING_SPACE "SMIL Parse Error: Missing space"
/****************************************************************************
*
* Function:
*
* HXCreateInstance()
*
* Purpose:
*
* Function implemented by all plugin DLL's to create an instance of
* any of the objects supported by the DLL. This method is similar to
* Window's CoCreateInstance() in its purpose, except that it only
* creates objects from this plugin DLL.
*
* NOTE: Aggregation is never used. Therefore and outer unknown is
* not passed to this function, and you do not need to code for this
* situation.
*
*/
STDAPI ENTRYPOINT(HXCreateInstance)
(
IUnknown** /*OUT*/ ppIUnknown
)
{
*ppIUnknown = (IUnknown*)(IHXPlugin*)new CSmilFileFormat();
if (*ppIUnknown)
{
(*ppIUnknown)->AddRef();
return HXR_OK;
}
return HXR_OUTOFMEMORY;
}
/****************************************************************************
*
* Function:
*
* CanUnload2()
*
* Purpose:
*
* Function implemented by all plugin DLL's if it returns HXR_OK
* then the pluginhandler can unload the DLL
*
*/
STDAPI ENTRYPOINT(CanUnload2)(void)
{
return (CHXBaseCountingObject::ObjectsActive() > 0 ? HXR_FAIL : HXR_OK );
}
const char* const CSmilFileFormat::zm_pDescription = "RealNetworks SMIL File Format Plugin";
const char* const CSmilFileFormat::zm_pCopyright = HXVER_COPYRIGHT;
const char* const CSmilFileFormat::zm_pMoreInfoURL = HXVER_MOREINFO;
const char* const CSmilFileFormat::zm_pFileMimeTypes[] = {"application/smil", NULL};
// /NOTE: here's what's sent as stream mime types; if there is no default
// namespace, then the file is treated as a SMIL 1.0 document and sent to
// our old renderer. If the default namespace is unrecognized, then we
// send "application/smil" and let the 2.0 or later SMIL renderer parse the
// namespace in the smil file data and, if it recognizes it (e.g., the SMIL
// renderer is a SMIL 3.0 renderer and the namespace is SMIL 3.0 but this
// file format is of the SMIL 2.0 timeframe), then it plays it. If the
// renderer doesn't recognize the namespace, it tries to auto upgrade with
// the following as the AU mime-type request: "application/smil.[namespace]"
// and the AU server then looks for a component (maybe not even an RN one)
// that can handle this type of SMIL file.
const char* const CSmilFileFormat::zm_pStreamMimeTypes[] = {
// /The following are SMIL 1.0 stream mime types that will be handled
// by SMIL 1.0-exclusive players (e.g., RealPlayer 8):
"application/rma-driver", // /Beta-1, SMIL 1.0 stream
"application/vnd.rn-rmadriver", // /SMIL 1.0 strm (no dflt namespace)
// /The following is SMIL 1.0 Rec default namespace:
// "http://www.w3.org/TR/REC-smil"
"application/smil",
// /The following is SMIL 2.0 Candidate Rec (i.e., pre SMIL 2.0 W3C Rec
// status) default namespace:
// "http://www.w3.org/2000/SMIL20/CR/Language"
// The following is SMIL 2.0 Proposed Rec default namespace:
// "http://www.w3.org/2001/SMIL20/PR/Language"
// Both CR and PR use this stream mime type:
"application/smil",
// /The following is the SMIL 2.0 Recommendation namespace
// "http://www.w3.org/2001/SMIL20/Language",
"application/smil",
// /We'll use this for any unrecognized SMIL file version (and note:
// this is probably going to always be the same as the SMIL20 mime
// type; the renderer will do all the work of deciding whether or not
// to auto upgrade if it doesn't recognize the default namespace):
"application/smil",
NULL};
const char* const CSmilFileFormat::zm_pFileExtensions[] = {"smi", "smil", NULL};
const char* const CSmilFileFormat::zm_pFileOpenNames[] = {"SMIL File Format (*.smi,*.smil)", NULL};
CSmilFileFormat::CSmilFileFormat()
: m_lRefCount(0)
, m_pContext(0)
, m_pFileObject(0)
, m_pFFResponse(0)
, m_bHeaderSent(FALSE)
, m_bChannelInit(FALSE)
, m_bSentFirstChannel(FALSE)
, m_bSourceInit(FALSE)
, m_ulCurrentTime(0)
, m_state(Ready)
, m_pRequest(0)
, m_pCommonClassFactory(0)
, m_ulPacketCount(0)
, m_ulCurrentPacket(0)
, m_ulStreamVersion(0)
, m_ulContentVersion(0)
, m_pCurrentPacketData(NULL)
, m_fileState(InContent)
, m_smilFileVersion(SMILFileVersionSmil10)
, m_pArrayOfPackets(0)
, m_bLogErrors(FALSE)
, m_pStartOfFile(NULL)
{
};
CSmilFileFormat::~CSmilFileFormat()
{
Close();
}
/************************************************************************
* Method:
* IHXPlugin::InitPlugin
* Purpose:
* Initializes the plugin for use. This interface must always be
* called before any other method is called. This is primarily needed
* so that the plugin can have access to the context for creation of
* IHXBuffers and IMalloc.
*/
STDMETHODIMP CSmilFileFormat::InitPlugin(IUnknown* /*IN*/ pContext)
{
m_pContext = pContext;
m_pContext->AddRef();
m_pContext->QueryInterface(IID_IHXCommonClassFactory,
(void**)&m_pCommonClassFactory);
return HXR_OK;
}
/************************************************************************
* Method:
* IHXPlugin::GetPluginInfo
* Purpose:
* Returns the basic information about this plugin. Including:
*
* bLoadMultiple whether or not this plugin DLL can be loaded
* multiple times. All File Formats must set
* this value to TRUE.
* pDescription which is used in about UIs (can be NULL)
* pCopyright which is used in about UIs (can be NULL)
* pMoreInfoURL which is used in about UIs (can be NULL)
*/
STDMETHODIMP CSmilFileFormat::GetPluginInfo
(
REF(BOOL) /*OUT*/ bLoadMultiple,
REF(const char*)/*OUT*/ pDescription,
REF(const char*)/*OUT*/ pCopyright,
REF(const char*)/*OUT*/ pMoreInfoURL,
REF(ULONG32) /*OUT*/ ulVersionNumber
)
{
bLoadMultiple = TRUE; // Must be true for file formats.
pDescription = (const char*) zm_pDescription;
pCopyright = (const char*) zm_pCopyright;
pMoreInfoURL = (const char*) zm_pMoreInfoURL;
ulVersionNumber = TARVER_ULONG32_VERSION;
return HXR_OK;
}
/************************************************************************
* Method:
* IHXPlugin::GetObjFileFormatInfo
* Purpose:
* If this object is a file format object this method returns
* information vital to the instantiation of file format plugins.
* If this object is not a file format object, it should return
* HXR_UNEXPECTED.
*/
STDMETHODIMP CSmilFileFormat::GetFileFormatInfo
(
REF(const char**) /*OUT*/ pFileMimeTypes,
REF(const char**) /*OUT*/ pFileExtensions,
REF(const char**) /*OUT*/ pFileOpenNames
)
{
pFileMimeTypes = (const char**) zm_pFileMimeTypes;
pFileExtensions = (const char**) zm_pFileExtensions;
pFileOpenNames = (const char**) zm_pFileOpenNames;
return HXR_OK;
}
// *** IUnknown methods ***
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::QueryInterface
// Purpose:
// Implement this to export the interfaces supported by your
// object.
//
STDMETHODIMP CSmilFileFormat::QueryInterface(REFIID riid, void** ppvObj)
{
if (IsEqualIID(riid, IID_IUnknown))
{
AddRef();
*ppvObj = this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXPlugin))
{
AddRef();
*ppvObj = (IHXPlugin*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXFileFormatObject))
{
AddRef();
*ppvObj = (IHXFileFormatObject*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXFileResponse))
{
AddRef();
*ppvObj = (IHXFileResponse*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXPendingStatus))
{
AddRef();
*ppvObj = (IHXPendingStatus*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXInterruptSafe))
{
AddRef();
*ppvObj = (IHXInterruptSafe*)this;
return HXR_OK;
}
else if (IsEqualIID(riid, IID_IHXThreadSafeMethods))
{
AddRef();
*ppvObj = (IHXThreadSafeMethods*)this;
return HXR_OK;
}
#if defined(HELIX_FEATURE_VIEWSOURCE)
else if ( IsEqualIID(riid, IID_IHXFileViewSource) )
{
CShadowViewSource* pVsrc = new CShadowViewSource(m_pContext,
(IUnknown*)(IHXPlugin*)this);
if ( pVsrc == NULL )
{
return HXR_FAIL;
}
return pVsrc->QueryInterface(riid, ppvObj);
}
#endif /* #if defined(HELIX_FEATURE_VIEWSOURCE) */
*ppvObj = NULL;
return HXR_NOINTERFACE;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) CSmilFileFormat::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) CSmilFileFormat::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
// *** IHXFileFormatObject methods ***
STDMETHODIMP CSmilFileFormat::InitFileFormat
(
IHXRequest* /*IN*/ pRequest,
IHXFormatResponse* /*IN*/ pFormatResponse,
IHXFileObject* /*IN*/ pFileObject
)
{
HX_RESULT ret = HXR_OK;
m_pRequest = pRequest;
m_pFFResponse = pFormatResponse;
m_pFileObject = pFileObject;
m_pRequest->AddRef();
m_pFFResponse->AddRef();
m_pFileObject->AddRef();
// set stream and content versions
m_ulStreamVersion = HX_ENCODE_PROD_VERSION(STREAM_MAJOR_VER,
STREAM_MINOR_VER,
STREAM_RELEASE,
STREAM_BUILD);
m_ulContentVersion = HX_ENCODE_PROD_VERSION(CONTENT_MAJOR_VER,
CONTENT_MINOR_VER,
CONTENT_RELEASE,
CONTENT_BUILD);
if ( m_pArrayOfPackets )
{
int s = m_pArrayOfPackets->GetSize();
for ( int i = s; i > 0; --i )
{
PacketData* pckt = (PacketData*)(*m_pArrayOfPackets)[i-1];
HX_RELEASE(pckt->pBuffer);
HX_DELETE(pckt);
(*m_pArrayOfPackets)[i-1] = NULL;
}
HX_DELETE(m_pArrayOfPackets);
}
m_pArrayOfPackets = new CHXPtrArray;
if ( m_pCurrentPacketData )
{
HX_RELEASE(m_pCurrentPacketData->pBuffer);
HX_DELETE(m_pCurrentPacketData);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -