📄 chxclientdatastream.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: CHXClientDataStream.cpp,v 1.6.2.3 2004/07/09 01:49:47 hubbe Exp $ * * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (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. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * 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 ***** */#include "CHXClientDataStream.h"#include "CHXClientBuffer.h"#include "CHXClientRequest.h"#include "CHXClientPlayer.h"#include "CHXClientEngine.h"#include "CHXClientDebug.h"#include "hlxclib/stdlib.h"#include "enter_hx_headers.h"#include "ihxpckts.h"#include "hxplugn.h"#include "hxcore.h" // IHXValidator#include "mfsiface.h"#include "hxsmartptr.h"HX_SMART_POINTER_INLINE( SPIHXBuffer, IHXBuffer );HX_SMART_POINTER_INLINE( SPIHXValues, IHXValues );HX_SMART_POINTER_INLINE( SPIHXClientEngine, IHXClientEngine );HX_SMART_POINTER_INLINE( SPIHXPlugin, IHXPlugin );HX_SMART_POINTER_INLINE( SPIHXPlugin2Handler, IHXPlugin2Handler );HX_SMART_POINTER_INLINE( SPIHXMemoryFileSystem2, IHXMemoryFileSystem2 );HX_SMART_POINTER_INLINE( SPIHXValidator, IHXValidator );#include "exit_hx_headers.h"static const char* const kProtocolMemFSName = "mem";static const char* const kProtocolPropertyName = "FileProtocol";static UINT32 const kMetaFileMaximumSize = 8192; // 8Kstatic const char* const kMimeTypePropertyName = "Content-Type"; // XXXSEH: Put in common header. Duplicated in CHXMimeTypeHeader.// Created this class instead of inheriting CHXClientDataStream from IHXMemoryFileContext to avoid circular references.class CHXClientMemoryFileContext : public IHXMemoryFileContext{ DECLARE_UNKNOWN_NOCREATE( CHXClientMemoryFileContext )private: LONG32 m_lCount;public: virtual ~CHXClientMemoryFileContext( void ) {} CHXClientMemoryFileContext( void ) : m_lCount( 0 ) {} // IHXMemoryFileContext STDMETHOD ( RequestOpen ) ( THIS_ const char* pURL ) { return HXR_NOTIMPL; } STDMETHOD ( RequestRead ) ( THIS_ void* pID, ULONG32 ulBytes ) { return HXR_NOTIMPL; }};DEFINE_SINGLE_INTERFACE_COMPONENT( CHXClientMemoryFileContext, IHXMemoryFileContext, m_lCount )CHXClientDataStream::CHXClientDataStream( CHXClientPlayer* pClientPlayer, const char* pURL, const char* pMimeType, UINT32 dataLength, bool autoPlay ) : m_pClientPlayer( pClientPlayer ) , m_pBuffer( NULL ) , m_pIRequest( NULL ) , m_DataLength( dataLength ) , m_pIMemoryFileSystem( NULL ) , m_AutoPlay( autoPlay ){ CHXASSERT( pURL && *pURL ); char* pMemFSURL = ( char* ) malloc( strlen( kProtocolMemFSName ) + 3 + strlen( pURL ) + 1 ); CHXASSERT( pMemFSURL ); if ( pMemFSURL ) { sprintf( pMemFSURL, "%s://%s", kProtocolMemFSName, pURL ); m_pIRequest = new CHXClientRequest( pMemFSURL, pMimeType ); m_pIRequest->AddRef(); free( pMemFSURL ); }}CHXClientDataStream::~CHXClientDataStream( void ){ if ( m_pIMemoryFileSystem ) { m_pIMemoryFileSystem->Remove( this ); m_pIMemoryFileSystem->Release(); m_pIMemoryFileSystem = NULL; } HX_RELEASE( m_pBuffer ); HX_RELEASE( m_pIRequest );}HX_RESULTCHXClientDataStream::GetMemoryFileSystem( IHXMemoryFileSystem** ppMemoryFileSystem ){ CHXASSERT( ppMemoryFileSystem && !*ppMemoryFileSystem ); SPIHXClientEngine spClientEngine; if ( !SUCCEEDED( m_pClientPlayer->GetHXClientEngine( spClientEngine.AsInOutParam() ) ) ) return HXR_FAIL; HX_RESULT result; SPIHXPlugin2Handler spPlugin2Handler; result = spPlugin2Handler.Query( spClientEngine.Ptr() ); if ( FAILED( result ) ) return result; SPIUnknown spUnkPlugin; result = spPlugin2Handler->FindPluginUsingStrings( ( char* ) kProtocolPropertyName, ( char* ) kProtocolMemFSName, NULL, NULL, NULL, NULL, *spUnkPlugin.AsInOutParam() ); if ( FAILED( result ) ) return result; SPIHXPlugin spPlugin = spUnkPlugin.Ptr(); CHXASSERT( spPlugin.IsValid() ); result = spPlugin->InitPlugin( spClientEngine.Ptr() ); if ( FAILED( result ) ) return result; result = spPlugin.Ptr()->QueryInterface( IID_IHXMemoryFileSystem, ( void** ) ppMemoryFileSystem ); if ( FAILED( result ) ) return result; // if the recursion depth has been overriden, change it /* SPIHXValues spValues = *ppMemoryFileSystem; if ( spValues.IsValid() ) { spValues->SetPropertyULONG32( MEMFS_RECURSION_DEPTH, ... ); } */ return HXR_OK;}HX_RESULTCHXClientDataStream::InitMemoryFileSystem( void ){ if ( NULL != m_pIMemoryFileSystem ) return HXR_OK; if ( !m_pIRequest ) return HXR_FAIL; const char* pMemFSURL = NULL; m_pIRequest->GetURL( pMemFSURL ); if ( !pMemFSURL || !*pMemFSURL ) return HXR_FAIL; HX_RESULT result = GetMemoryFileSystem( &m_pIMemoryFileSystem ); if ( FAILED( result ) ) return result; IHXMemoryFileContext* pIMemoryFileContext = new CHXClientMemoryFileContext; pIMemoryFileContext->AddRef(); const char* pMimeType = NULL; SPIHXValues spHeader; SPIHXBuffer spMimeTypeBuffer; m_pIRequest->GetResponseHeaders( *spHeader.AsInOutParam() ); if ( spHeader.IsValid() ) { spHeader->GetPropertyCString( kMimeTypePropertyName, *spMimeTypeBuffer.AsInOutParam() ); if ( spMimeTypeBuffer.IsValid() ) { pMimeType = ( const char* ) spMimeTypeBuffer->GetBuffer(); } } SPIHXMemoryFileSystem2 spMemoryFileSystem2 = m_pIMemoryFileSystem; result = spMemoryFileSystem2.IsValid() ? spMemoryFileSystem2->AddWithSize( pMemFSURL, pIMemoryFileContext, this, pMimeType, m_DataLength ) : m_pIMemoryFileSystem->Add( pMemFSURL, pIMemoryFileContext, this, pMimeType ); pIMemoryFileContext->Release(); pIMemoryFileContext = NULL; if ( FAILED( result ) ) { m_pIMemoryFileSystem->Release(); m_pIMemoryFileSystem = NULL; } return result;}boolCHXClientDataStream::ValidateBufferData( void ){ if ( !m_pIRequest ) return false; SPIHXClientEngine spClientEngine; if ( !SUCCEEDED( m_pClientPlayer->GetHXClientEngine( spClientEngine.AsInOutParam() ) ) ) return false; SPIHXValidator spValidator = spClientEngine.Ptr(); if ( !spValidator.IsValid() ) return false; HX_RESULT result = spValidator->ValidateMetaFile( m_pIRequest, m_pBuffer ); return result != HXR_INVALID_METAFILE;}HX_RESULTCHXClientDataStream::WriteData( UINT32 bufferLength, unsigned char* pBuffer ){ HX_RESULT outResult = HXR_FAIL; if ( m_pIMemoryFileSystem ) { outResult = m_pIMemoryFileSystem->Append( this, pBuffer, bufferLength ); } else { UINT32 newBufferSize = bufferLength + ( m_pBuffer ? m_pBuffer->GetSize() : 0 ); if ( newBufferSize > kMetaFileMaximumSize ) { outResult = InitMemoryFileSystem(); if ( SUCCEEDED( outResult ) ) { if ( m_pBuffer ) { outResult = m_pIMemoryFileSystem->Append( this, m_pBuffer->GetBuffer(), m_pBuffer->GetSize() ); } if ( SUCCEEDED( outResult ) ) { outResult = m_pIMemoryFileSystem->Append( this, pBuffer, bufferLength ); if ( SUCCEEDED( outResult ) ) { outResult = m_pClientPlayer->OpenRequest( m_pIRequest ); if ( SUCCEEDED( outResult ) && m_AutoPlay ) { m_pClientPlayer->Play(); } } } if ( FAILED( outResult ) ) { m_pIMemoryFileSystem->Remove( this ); m_pIMemoryFileSystem->Release(); m_pIMemoryFileSystem = NULL; } } HX_RELEASE( m_pBuffer ); } else { outResult = HXR_OUTOFMEMORY; if ( !m_pBuffer ) { m_pBuffer = new CHXClientBuffer; if ( m_pBuffer ) { m_pBuffer->AddRef(); } } if ( m_pBuffer ) { outResult = m_pBuffer->Add( pBuffer, bufferLength ); } } } return outResult;}HX_RESULTCHXClientDataStream::CloseData( void ){ HX_RESULT outResult; if ( m_pIMemoryFileSystem ) { ( void ) m_pIMemoryFileSystem->Finish( this ); outResult = HXR_OK; } else { outResult = HXR_FAIL; if ( m_pBuffer ) { if ( ValidateBufferData() ) { outResult = InitMemoryFileSystem(); if ( SUCCEEDED( outResult ) ) { outResult = m_pIMemoryFileSystem->Append( this, m_pBuffer->GetBuffer(), m_pBuffer->GetSize() ); if ( SUCCEEDED( outResult ) ) { ( void ) m_pIMemoryFileSystem->Finish( this ); // XXXSEH: Don't know if we care about the return value? outResult = m_pClientPlayer->OpenRequest( m_pIRequest ); if ( SUCCEEDED( outResult ) && m_AutoPlay ) { m_pClientPlayer->Play(); } } if ( FAILED( outResult ) ) { m_pIMemoryFileSystem->Remove( this ); m_pIMemoryFileSystem->Release(); m_pIMemoryFileSystem = NULL; } } } HX_RELEASE( m_pBuffer ); } } return outResult;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -