www.pudn.com > pueblo.zip > ChHTMLStream.cpp


/*---------------------------------------------------------------------------- 
                        _                              _ _        
        /\             | |                            | (_)       
       /  \   _ __   __| |_ __ ___  _ __ ___   ___  __| |_  __ _  
      / /\ \ | '_ \ / _` | '__/ _ \| '_ ` _ \ / _ \/ _` | |/ _` | 
     / ____ \| | | | (_| | | | (_) | | | | | |  __/ (_| | | (_| | 
    /_/    \_\_| |_|\__,_|_|  \___/|_| |_| |_|\___|\__,_|_|\__,_| 
 
    The contents of this file are subject to the Andromedia Public 
	License Version 1.0 (the "License"); you may not use this file 
	except in compliance with the License. You may obtain a copy of 
	the License at http://www.andromedia.com/APL/ 
 
    Software distributed under the License is distributed on an 
	"AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 
	implied. See the License for the specific language governing 
	rights and limitations under the License. 
 
    The Original Code is Pueblo client code, released November 4, 1998. 
 
    The Initial Developer of the Original Code is Andromedia Incorporated. 
	Portions created by Andromedia are Copyright (C) 1998 Andromedia 
	Incorporated.  All Rights Reserved. 
 
	Andromedia Incorporated                         415.365.6700 
	818 Mission Street - 2nd Floor                  415.365.6701 fax 
	San Francisco, CA 94103 
 
    Contributor(s): 
	-------------------------------------------------------------------------- 
	   Chaco team:  Dan Greening, Glenn Crocker, Jim Doubek, 
	                Coyote Lussier, Pritham Shetty. 
 
					Wrote and designed original codebase. 
 
------------------------------------------------------------------------------ 
 
	This file contains the implementation of the ChHTMLStreamManager class notification 
	methods. 
----------------------------------------------------------------------------*/ 
 
 
#include "headers.h" 
#include  
#include  
#include    
#include  
#include  
#include  
#include  
#include  
 
#include "ChHtmlView.h" 
#include "ChTxtObj.h" 
#include "ChPlgInMgr.h" 
#include "ChHTMLStream.h" 
#include "ChHtmlPane.h" 
 
 
/*---------------------------------------------------------------------------- 
	ChHtmlReqInfo class	member functions 
----------------------------------------------------------------------------*/ 
 
ChHtmlReqInfo::ChHtmlReqInfo(  ChHtmlView* pView ) : 
								m_uReqID( 0 ), 
								m_iError( 0 ), 
								m_pFrameMgr( 0 ) 
{ 
	m_strViewName = pView->GetFrameName(); 
	m_uViewID  = pView->GetPageNumber(); 
} 
 
void ChHtmlReqInfo::SetFrameMgrInfo( ChHtmlWnd* pWnd ) 	 
{   
	m_pFrameMgr = pWnd;  
	m_uReqID    = pWnd->GetPageID(); 
} 
 
/*---------------------------------------------------------------------------- 
	ChHtmlInlineReq class	member functions 
----------------------------------------------------------------------------*/ 
 
ChHtmlInlineReq::~ChHtmlInlineReq()  
{ 
	delete m_pDib; 
} 
 
/*---------------------------------------------------------------------------- 
	ChHtmlBkPatternReq class	member functions 
----------------------------------------------------------------------------*/ 
 
ChHtmlBkPatternReq::~ChHtmlBkPatternReq()  
{ 
	delete m_pDib; 
} 
 
 
/*---------------------------------------------------------------------------- 
	ChHTMLStreamManager class	member functions 
----------------------------------------------------------------------------*/ 
 
 
int ChHTMLStreamManager::NewStream( chparam requestData, pChHTTPStream pStream, bool boolSeekable  ) 
{ 
	ChHtmlReqInfo* 	pLoadInfo = (ChHtmlReqInfo*)requestData; 
 
	if ( pLoadInfo  ) 
	{  
		pLoadInfo->SetURL( pStream->GetURL() ); 
		pLoadInfo->SetMimeType( pStream->GetMimeType()  ); 
			 
	} 
 
	return streamAsFile; 
} 
 
chint32 ChHTMLStreamManager::WriteReady( chparam requestData, pChHTTPStream pStream, chint32 iBytes ) 
{ 
	return iBytes; 
} 
 
chint32 ChHTMLStreamManager::Write( chparam requestData, pChHTTPStream pStream,  
						chint32 lOffset, chint32 lLen, const char* pBuffer ) 
{ 
	return lLen; 
} 
 
 
void ChHTMLStreamManager::StreamAsFile(chparam requestData, pChHTTPStream pStream, const char* fname) 
{ 
 
	ChHtmlReqInfo* 	pLoadInfo = (ChHtmlReqInfo*)requestData; 
 
	if ( pLoadInfo == 0 ) 
	{ // What is this ? 
		return;	 
	} 
 
	// Set the cache file name 
	pLoadInfo->SetFile( pStream->GetCacheFilename()  ); 
 
#if defined ( CH_PUEBLO_PLUGIN ) 
	// The mime type can change due to a bug in IE and Netscape 2.0 
	pLoadInfo->SetMimeType( pStream->GetMimeType()  ); 
#endif 
 
	// If it is a image decode it now 
 
	if ( pLoadInfo->GetFrameMgr()->GetPageID() == pLoadInfo->GetReqID() )  
	{ // Request has been canceled 
		switch( pLoadInfo->GetType() ) 
		{ 
			case ChHtmlReqInfo::loadBkPattern : 
			{ 
				ChHtmlBkPatternReq*		pBkInfo = (ChHtmlBkPatternReq*)pLoadInfo; 
 
				pBkInfo->SetImage( pLoadInfo->GetFrameMgr()-> 
								LoadDIB( pStream->GetMimeType(), fname ) ); 
				break; 
			} 
			case ChHtmlReqInfo::loadInline :	   
			{ 
				ChHtmlInlineReq*		pInlineInfo = (ChHtmlInlineReq*)pLoadInfo; 
 
				pInlineInfo->SetImage( pLoadInfo->GetFrameMgr()-> 
								LoadDIB( pStream->GetMimeType(), fname ) ); 
				break; 
			} 
			default : 
			{ 
				break; 
			} 
		} 
	} 
 
} 
 
 
void ChHTMLStreamManager::DestroyStream( chparam requestData, pChHTTPStream pStream, int iReason ) 
{ 
 	ChHtmlReqInfo* pLoadInfo = (ChHtmlReqInfo*)requestData; 
 
	if ( pLoadInfo == 0 ) 
	{ // No idea what this is 
		return; 
	} 
 
	int iType  	=   pLoadInfo->GetType(); 
	if ( iType != ChHtmlReqInfo::loadURL &&  
				pLoadInfo->GetFrameMgr()->GetPageID() != pLoadInfo->GetReqID() )  
	{ // Request has been canceled 
	  	delete pLoadInfo; 
	  	return;  
	} 
 
	if ( iReason ) 
	{ 
 
		pLoadInfo->SetError( pStream->GetErrorMsg(), iReason ); 
 
 
		if( !pLoadInfo->GetFrameMgr()->PostMessage( WM_CHACO_HTTP_MSG,  
								ChHtmlReqInfo::loadError, (LPARAM)pLoadInfo ) ) 
		{ 
			TRACE1("Post message failed %ld\n", ::GetLastError() ); 
		} 
	} 
	else 
	{ 
 
		if( !pLoadInfo->GetFrameMgr()->PostMessage( WM_CHACO_HTTP_MSG,  
							iType, (LPARAM)pLoadInfo ) ) 
		{ 
			TRACE1("Post message failed %ld\n", ::GetLastError() ); 
		} 
	} 
} 
 
 
/*---------------------------------------------------------------------------- 
	ChHtmlWnd class	member functions 
----------------------------------------------------------------------------*/ 
 
ChHTTPConn* ChHtmlWnd::GetHTTPConn()	  
{  
#if !defined ( CH_PUEBLO_PLUGIN ) 
	if ( m_pHttpConnection == 0 ) 
	{	 
		m_phtmlStreamMgr = new  ChHTMLStreamManager( this ); 
		ASSERT( m_phtmlStreamMgr ); 
 
		m_pHttpConnection = new ChHTTPSocketConn( m_phtmlStreamMgr ); 
		ASSERT( m_pHttpConnection ); 
		 
		m_boolMyConn = true;	 
	} 
#endif 
	return m_pHttpConnection;  
} 
 
bool ChHtmlWnd::VisitedURL( const string &strLink, const char * pstrDefault /* = 0 */ ) 
{ 
	 
	if ( GetHTTPConn()->IsVisitedURL( strLink, pstrDefault ) ) 
	{ 
		return true; 
	} 
	else 
	{ 
		return false; 
	} 
} 
 
void ChHtmlWnd::AbortFormatting()					 
{ 
	m_boolAbortFormatting = true; 
	GetHTTPConn()->AbortRequests( false, m_phtmlStreamMgr ); 
} 
 
 
void ChHtmlWnd::LoadURL( const string& strURL, const char* pstrWindowName /* = 0 */ ) 
{ 
	string strTarget( pstrWindowName ? pstrWindowName : TOP_WINDOW ); 
 
	ChHtmlView *pView = GetHtmlViewByName( strTarget ); 
 
	if ( !pView ) 
	{ 
		pView = GetDefaultView(); 
		strTarget = pView->GetFrameName(); 
	} 
 
	// Abort all previous out standing requests 
	GetHTTPConn()->AbortRequests( false, m_phtmlStreamMgr ); 
 
	if ( pView ==  GetDefaultView() ) 
	{ 
 
		while ( m_pRedirectStack ) 
		{ 
			while( m_pRedirectStack->GetCount() ) 
			{ 
				delete  m_pRedirectStack->RemoveHead(); 
			} 
			delete m_pRedirectStack; 
			m_pRedirectStack = 0;		 
		} 
 
		// Delete all frames 
		while ( m_htmlViewList.GetCount() > 1 ) 
		{ 
 
			ChHtmlViewObj*	pFrameObj = m_htmlViewList.RemoveTail(); 
			delete pFrameObj; 
		} 
 
	} 
 
 
	ChHtmlReqInfo* pInfo = new ChHtmlURLReq( pView, strTarget );  
 
	pInfo->SetFrameMgrInfo( this ); 
 
 
 
	GetHTTPConn()->GetURL( strURL, (chparam)pInfo, 0, 0, m_phtmlStreamMgr ); 
} 
 
 
void ChHtmlWnd::PostURL( const string& strURL, const string& strData,  
									const char* pstrWindowName /* = 0 */ ) 
{ 
	string strTarget( pstrWindowName ? pstrWindowName : TOP_WINDOW ); 
 
	ChHtmlView *pView = GetHtmlViewByName( strTarget ); 
 
	if ( !pView ) 
	{ 
		pView = GetDefaultView(); 
	} 
	 
	GetHTTPConn()->AbortRequests( false, m_phtmlStreamMgr ); 
 
	if ( pView ==  GetDefaultView() ) 
	{ 
		while ( m_pRedirectStack ) 
		{ 
			while( m_pRedirectStack->GetCount() ) 
			{ 
				delete  m_pRedirectStack->RemoveHead(); 
			} 
			delete m_pRedirectStack; 
			m_pRedirectStack = 0;		 
		} 
 
		//NewPage(); 
 
 
		// Delete all frames 
		while ( m_htmlViewList.GetCount() > 1 ) 
		{ 
 
			ChHtmlViewObj*	pFrameObj = m_htmlViewList.RemoveTail(); 
			delete pFrameObj; 
		} 
 
	} 
 
	ChHtmlReqInfo* pInfo = new ChHtmlURLReq( pView, strTarget );  
 
	pInfo->SetFrameMgrInfo( this ); 
 
 
	GetHTTPConn()->PostURL(  strURL, strData,  
							strData.GetLength(), 
							(chparam)pInfo, 0, 0, m_phtmlStreamMgr  ); 
} 
 
 
void ChHtmlWnd::PrefetchURL( const string& strURL, const char * pstrDef /* = 0 */ ) 
{ 
	if ( !VisitedURL( strURL, pstrDef ) ) 
	{ 
		// prefetch only if we don't have this document 
		GetHTTPConn()->GetURL( strURL, 0, pstrDef,  
					ChHTTPConn::PrefetchURL, m_phtmlStreamMgr ); 
	} 
} 
 
void ChHtmlWnd::LoadURL( const string& strURL, ChHtmlReqInfo* pReqInfo ) 
{ 
	ChHtmlView *pView = GetHtmlViewByName( pReqInfo->GetViewName() ); 
	ASSERT( pView ); 
 
	pReqInfo->SetFrameMgrInfo( this ); 
	GetHTTPConn()->GetURL( strURL, (chparam)pReqInfo,  
					pView->GetDocBaseURL(), 0, m_phtmlStreamMgr ); 
} 
 
void ChHtmlWnd::PostURL( const string& strURL, const string& strData, ChHtmlReqInfo* pReqInfo ) 
{ 
	ChHtmlView *pView = GetHtmlViewByName( pReqInfo->GetViewName() ); 
	ASSERT( pView ); 
 
	pReqInfo->SetFrameMgrInfo( this ); 
 
	GetHTTPConn()->PostURL( strURL, strData,  
							strData.GetLength(), 
							(chparam)pReqInfo, pView->GetDocBaseURL(),  
							0, m_phtmlStreamMgr ); 
} 
 
 
 
ChDib* ChHtmlWnd::LoadDIB( const string& strMimeType, const char* pstrFilename ) 
{ 
 
	int iMimeType = ChHTTPConn::GetMimeType( strMimeType ); 
 
	ChDib*	pDib = 0; 
 
	switch ( iMimeType ) 
	{ 
		case ChHTTPConn::typeGIF: 
		{								/* Update the image */ 
 
			pDib = new ChDib; 
			ASSERT( pDib ); 
			// create the gif object 
			ChGifDecoder gifDecoder( pDib ); 
			if ( gifDecoder.Load( pstrFilename ) ) 
			{ 
				return( pDib ); 
			} 
			else 
			{ 
				return pDib; 
			} 
			break; 
		} 
		case ChHTTPConn::typeJPEG: 
		{								/* Update the image */ 
			pDib = new ChDib; 
			ASSERT( pDib ); 
			// create the JPEG object 
			ChJPEG jpegDecoder( pDib ); 
			if ( jpegDecoder.Load( pstrFilename, ChImageDecoder::load8Bit ) ) 
			{ 
				return( pDib ); 
			} 
			else 
			{ 
				return pDib; 
			} 
			break; 
		} 
		case ChHTTPConn::typeBMP : 
		{								/* Update the image */ 
			// create the Dib object 
			ChDib *pDib = new ChDib; 
			ChDibDecoder dibDecoder( pDib ); 
			if ( dibDecoder.Load( pstrFilename ) ) 
			{ 
				return( pDib ); 
			} 
			else 
			{ 
				return pDib; 
			} 
			break; 
		} 
	} 
 
	return 0; 
} 
 
/*---------------------------------------------------------------------------- 
	This method called when HTTP posts a message  
----------------------------------------------------------------------------*/ 
 
LONG ChHtmlWnd::OnHTTPNotificaton( UINT wParam, LONG lParam ) 
{ 
	ChHtmlReqInfo* pInfo = (ChHtmlReqInfo*)lParam; 
 
	if ( GetPageID() != pInfo->GetReqID() )  
	{ // Request has been canceled 
	  	delete pInfo; 
	  	return 0;  
	} 
 
 
	switch( wParam ) 
	{  
		case ChHtmlReqInfo::loadURL : 
		{ 
 
			ChHtmlURLReq*		pLoadInfo = (ChHtmlURLReq*)pInfo; 
			ChHtmlView *pView = GetHtmlViewByName( pLoadInfo->GetTarget() ); 
 
			if ( pView == GetDefaultView() ) 
			{ 
				OnLoadComplete( pInfo->GetFile(), pInfo->GetURL(), pInfo->GetMimeType(), 
										 					(chparam)pInfo );  
			} 
			else if ( pView ) 
			{ 
			 	StreamFile( pInfo->GetFile(),	pInfo->GetMimeType(),  
			 								ChHtmlWnd::fileReplace,  
			 								pInfo->GetURL(), pView ); 
			} 
			break; 
		} 
		case  ChHtmlReqInfo::loadPlugInReq : 
		{ 
			// did we get a new page after this load 
			ChHtmlPluginReq*		pLoadInfo = (ChHtmlPluginReq*)pInfo; 
			ChHtmlView *pView = GetHtmlViewByName( pLoadInfo->GetViewName() ); 
 
			if ( pView && pView->GetPageNumber()  == pLoadInfo->GetViewID() ) 
			{ 
				ChPlugInStream* pStream = pLoadInfo->GetPlugInStream(); 
				pStream->OnLoadComplete( pInfo->GetFile(), pInfo->GetURL(), pInfo->GetMimeType() ); 
			} 
			break; 
		} 
		case  ChHtmlReqInfo::loadInline : 
		{ 
			ChHtmlInlineReq*		pLoadInfo = (ChHtmlInlineReq*)pInfo; 
 
			ChObjInline* pImage = pLoadInfo->GetInlineData(); 
 
			ChHtmlView *pView = GetHtmlViewByName( pLoadInfo->GetViewName() ); 
 
			if ( pView && pView->GetPageNumber()  == pLoadInfo->GetViewID() ) 
			{ 
				ChDib *pDib = pLoadInfo->GetImage(); 
				pLoadInfo->SetImage( 0 ); // we want the Dib to stay around 
				if ( pDib ) 
				{ 
					ChSize sizeOld, sizeNew( 0, 0) ; 
					// old size 
					pImage->GetImageSize( sizeOld ); 
					// set the image into our object wrapper 
					if ( 0 == pImage->GetImageData() ) 
					{ 
						ChInlineImageData* pData = new ChInlineImageData; 
						ASSERT( pData ); 
						pView->GetImageList().Insert( pInfo->GetURL(), pData ); 
						// remove the plugin object if any 
						pImage->ShutdownPlugin(); 
						pImage->SetImageData( pData ); 
					} 
					// Set the image object 
					pImage->GetImageData()->SetImage( pDib ); 
					pImage->GetImageSize( sizeNew ); 
					pView->UpdateObject( pImage, sizeOld != sizeNew ); 
 
					if (m_pPaneMgr && (sizeOld != sizeNew)) 
					{ 
						ChPane*		pPane;  
 
						pPane = m_pPaneMgr->FindPane( pView->GetFrameName() ); 
						if (pPane && pPane->IsSizeToFit()) 
						{ 
											/* Inline image has changed the 
												document size */ 
 
							m_pPaneMgr->RecalcLayout( pPane ); 
						} 
					} 
				} 
				else 
				{  
					  
					ChSize sizeObj; 
					// old size 
					pImage->GetObjectSize( sizeObj );   
					 
					if ( sizeObj.cx == 8 && sizeObj.cy == 8 ) 
					{ 
						sizeObj.cx = (80 * pView->GetViewWidth())/100;	 
						sizeObj.cy = (40 * pView->GetViewHeight())/100; 
						 
						pImage->SetObjectSize( sizeObj );	 
					} 
 
					if (pView->GetPlugInMgr()->HandleMimeType( pInfo->GetMimeType() )) 
					{ 
											// Load the plugin 
						pView->GetPlugInMgr()-> 
								LoadPlugInModule( pView, pInfo->GetFile(), 
													pInfo->GetURL(), 
													pInfo->GetMimeType(), 
													pImage ); 
						InvalidateRect( NULL, true ); 
 
						if (m_pPaneMgr) 
						{ 
							ChPane*		pPane;  
 
							pPane = m_pPaneMgr->FindPane( pView->GetFrameName() ); 
							if (pPane && pPane->IsSizeToFit()) 
							{ 
											/* Inline image has changed the 
												document size */ 
 
								m_pPaneMgr->RecalcLayout( pPane ); 
							} 
						} 
					} 
					else 
					{						// Display broken image 
					} 
 
				} 
			} 
			break; 
		} 
		case  ChHtmlReqInfo::loadBkPattern : 
		{ 
			ChHtmlBkPatternReq*		pLoadInfo = (ChHtmlBkPatternReq*)pInfo; 
			//SetRedraw();  // turn it on  
			if ( pLoadInfo->GetImage() ) 
			{ 
				ChHtmlView *pView = GetHtmlViewByName( pLoadInfo->GetViewName() ); 
				if ( pView ) 
				{ 
					pView->SetBackPattern( pLoadInfo->GetImage() ); 
					// We need to save this else the object will be deleted by 
					// ChHtmlBkPatternReq 
					pLoadInfo->SetImage( 0 ); 
				} 
			} 
			break; 
		} 
 
		case ChHtmlReqInfo::loadFrameReq: 
		{ 
			ChHtmlFrameReq*	pLoadInfo = (ChHtmlFrameReq*)pInfo; 
			ChHtmlView*		pView; 
 
			pView = GetHtmlViewByName( pLoadInfo->GetViewName() ); 
 
			if (pView) 
			{ 
				chflag32	flDispOptions; 
 
				flDispOptions = 
					pLoadInfo->GetOptions() & ChHtmlPane::optionFileAppend ? 
									ChHtmlWnd::fileAppend : 
									ChHtmlWnd::fileReplace; 
 
				if (DisplayFile( pInfo->GetFile(), pInfo->GetMimeType(), 
									flDispOptions, pInfo->GetURL(), 
									pView->GetFrameName() )) 
				{ 
					ChPane*		pPane;  
 
					if (m_pPaneMgr && 
						(pPane = m_pPaneMgr->FindPane( pView->GetFrameName() ))) 
					{ 
											// Finally show the pane 
						pPane->Show(); 
					} 
					else 
					{						// our frame do the show 
 
						ChPosition pos = m_htmlViewList.GetHeadPosition(); 
 
						while (pos) 
						{ 
							ChHtmlViewObj*	pFrameObj = m_htmlViewList.GetNext( pos ); 
 
							if (0 == pFrameObj->GetHtmlView()->GetFrameName().CompareNoCase( pView->GetFrameName() )) 
							{ 
								if ( pFrameObj->GetFrameWnd() ) 
								{ 
									pFrameObj->GetFrameWnd()->ShowWindow( SW_SHOWNORMAL ); 
								} 
								break; 
							} 
							else if (0 == pFrameObj->GetAltFrameName().CompareNoCase( pView->GetFrameName() )) 
							{ 
								if ( pFrameObj->GetFrameWnd() ) 
								{ 
									pFrameObj->GetFrameWnd()->ShowWindow( SW_SHOWNORMAL ); 
								} 
								break; 
							} 
						} 
					} 
		 
				} 
			} 
			break; 
		} 
		case ChHtmlReqInfo::loadError : 
		{ 
 
			string strMsg( pInfo->GetURL() ); 
			strMsg += TEXT( " : " ); 
			strMsg += pInfo->GetErrorMsg(); 
 
			OnTrace( strMsg, traceError ); 
			 
			switch( pInfo->GetType() ) 
			{  
				case ChHtmlReqInfo::loadURL : 
				{	// call the virtual function to notify 
					OnLoadError( pInfo->GetError(),  
							pInfo->GetErrorMsg(), pInfo->GetURL(), 0 ); 
					break; 
				} 
				case  ChHtmlReqInfo::loadPlugInReq : 
				{ 
					ChHtmlPluginReq*		pLoadInfo = (ChHtmlPluginReq*)pInfo; 
					ChPlugInStream* pStream = pLoadInfo->GetPlugInStream(); 
					pStream->OnLoadError( pInfo->GetError(), pInfo->GetURL() ); 
					break; 
				} 
				case ChHtmlReqInfo::loadInline : 
				{  // display broken image 
					break; 
				} 
				case ChHtmlReqInfo::loadBkPattern : 
				{ 
					SetRedraw();  // turn it on  
					InvalidateRect( NULL ); 
					break; 
				} 
			} 
			break; 
		} 
		default : 
		{ 
			break; 
		} 
	} 
	// Delete the user data we associated with this request 
	delete 	pInfo; 
 
	return 0; 
}