home *** CD-ROM | disk | FTP | other *** search
- /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * The contents of this file are subject to the Netscape Public License
- * Version 1.0 (the "NPL"); you may not use this file except in
- * compliance with the NPL. You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- *
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- *
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation. All Rights
- * Reserved.
- */
-
- #include "stdafx.h"
-
- #include "olectc.h"
-
- #include "presentm.h"
- #include "oleview1.h"
- #include "cxsave.h"
- #include "winproto.h"
-
- extern "C" int MK_OUT_OF_MEMORY; // defined in allxpstr.h
-
-
- COLEStreamData::COLEStreamData(const char *pServer, const char *pMimeType) : CStreamData(CStreamData::m_OLE) {
- // Purpose: Construct the data stream object.
- // Arguments: pServer The registry name of the automation server that we should contact in our data stream.
- // pMimeType The Mime type of the stream.
- // Returns: none
- // Comments: Note that we initialize the base class to know that we are an OLE viewer.
-
- // Just copy over the relevant members.
- m_csServerName = pServer;
- m_csMimeType = pMimeType;
- }
-
- COLEDownloadData::COLEDownloadData(COLEStreamData *pCData, const char *pAddress) {
- // Purpose: Create an instance of the download data.
- // Arguments: pCData A global object representing the OLE registered server.
- // pAddress The URL that we are about to handle.
- // Returns: none
- // Comments: Download instance specific member.
-
- // Assign over our data.
- m_pCData = pCData;
- m_pBuffer = NULL;
- m_bReadyCalled = FALSE;
-
- // Attach ourselves to the OLE Automation server.
- // If an exception is thrown, it's handled elsewhere.
- TRACE("%s:Initialize(%s, %s)\n", (const char *)m_pCData->m_csServerName, (const char *)m_pCData->m_csMimeType, pAddress);
- m_Viewer.CreateDispatch(m_pCData->m_csServerName);
- if(0 == m_Viewer.Initialize(m_pCData->m_csMimeType, pAddress)) {
- AfxThrowNotSupportedException();
- }
-
- // Attempt to allocate a small buffer to start out with.
- // This may grow later, we don't really care.
- if(NULL == (m_pBuffer = SysAllocStringLen(NULL, m_InitialBufferSize))) {
- AfxThrowMemoryException();
- }
- }
-
- COLEDownloadData::~COLEDownloadData() {
- // Use to free off our buffer if it exists.
- if(m_pBuffer != NULL) {
- SysFreeString(m_pBuffer);
- }
- }
-
- extern "C" {
-
- NET_StreamClass *ole_stream(int iFormatOut, void *vpDataObj, URL_Struct *pURL, MWContext *pContext) {
- // Purpose: Return the stream class for our OLE automated stream.
- // Arguments: iFormatOut The representation we are outputting (should be FO_PRESENT only for now)
- // vpDataObj Our COLEStreamData structure.
- // pURL The URL we're loading.
- // pContext The current context that we're loading in.
- // Returns: NET_StreamClass A group of functions that will handle the intimate details
- // of the download.
- // Comments: Set up the data stream.
- // Initiate the conversation with the automation server.
- // The stream will be lost if unable to establish the connection. Can't really handle well.
-
- // Convert our data object.
- COLEStreamData *pCData = (COLEStreamData *)vpDataObj;
- COLEDownloadData *pOData = NULL;
- // Create the stream data.
- TRY {
- pOData = new COLEDownloadData(pCData, pURL->address);
-
- NET_StreamClass *pOleStream = NET_NewStream("Speghetti(SP)",
- ole_StreamWrite,
- ole_StreamComplete,
- ole_StreamAbort,
- ole_StreamReady,
- (void *)pOData,
- pContext);
-
- // See if we can't get this to load in a seperate context.
- // It will correctly call the stream members, and also reset
- // the context if able.
- NET_StreamClass *pRetval =
- CSaveCX::OleStreamObject(pOleStream, pURL, pCData->m_csServerName);
- if(pRetval == NULL) {
- // Couldn't switch
- pRetval = pOleStream;
- }
-
- return(pRetval);
- }
- CATCH(CException, e) { // Any exception will do
-
- // Tell the user that we were unable to complete the operation, ask them if they would like to unregister the OLE viewer.
- TRACE("Couldn't connect to the OLE automation server\n");
- CString csMessage = szLoadString(IDS_OLE_CANTUSE_VIEWER);
- csMessage += pCData->m_csServerName;
- csMessage += szLoadString(IDS_OLE_CANTUSE_VIEWER2);
-
- if(IDNO == AfxMessageBox(csMessage, MB_YESNO)) {
- // They don't want to use the viewer in the future.
- // Unregister it; assume FO_PRESENT.
- WPM_UnRegisterContentTypeConverter(pCData->m_csServerName, pCData->m_csMimeType, FO_PRESENT);
-
- // Remove the registration from the INI file also.
- theApp.WriteProfileString("Automation Viewers", pCData->m_csMimeType, NULL);
-
- // We know it's registered, and we know it's our current data, so remove it.
- delete(pCData);
- }
- if(pOData != NULL) {
- delete(pOData);
- }
-
- return(NULL);
- }
- END_CATCH
-
- return(NULL);
- }
-
- int ole_StreamWrite(NET_StreamClass *stream, const char *cpWriteData, int32 lLength) {
- // Purpose: Write data to our automated object.
- // Arguments: vpDataObject The COLEDownloadObject for the load.
- // cpWriteData The data to write.
- // lLength The length of the string we're writing.
- // Returns: int MK_DATA_LOADED always.
- // Comments: Used to write data to the streaming viewer.
- // If the viewer doesn't want the data, it should report the error status in Ready.
-
- void *vpDataObj=stream->data_object;
- // Obtain the object.
- COLEDownloadData *pOData = (COLEDownloadData *)vpDataObj;
-
- // Check to see if the netlib didn't check is_write_ready
- if(pOData->m_bReadyCalled == FALSE) {
- TRACE("Please call Ready first. This is a serious hack.\n");
-
- // Since the netlib is being harsh to us, we have to do some special handling here.
- // We're going to do a tight loop, until the other viewer has gotten all the data
- // that we just got handed, and then we'll return as normal.
- // Enough OLE messages will be generated to keep the application running....
- long lReady = 0;
- long lOffset = 0;
- while(1) {
- lReady = ole_StreamReady(stream);
- if(lReady == 0) {
- continue;
- }
- else if(lReady < 0) {
- // Hm, they said error.
- pOData->m_bReadyCalled = FALSE;
- return(CASTINT(lReady));
- }
-
- // Okay, see if the ready amount is the amount we can send.
- if(lReady + lOffset >= lLength) {
- lReady = lLength - lOffset;
- if(lReady == 0) {
- pOData->m_bReadyCalled = FALSE;
- return(MK_DATA_LOADED);
- }
- }
-
- // Send the data.
- ole_StreamWrite(stream, cpWriteData + lOffset, lReady);
-
- // Increment our offset into the buffer.
- lOffset += lReady;
- }
- }
-
- // Clear this out for next time.
- pOData->m_bReadyCalled = FALSE;
-
- // If the length is greater than our buffer, then it's time to resize.
- if((int32)SysStringLen(pOData->m_pBuffer) < lLength) {
- if(FALSE == SysReAllocStringLen(&(pOData->m_pBuffer), NULL, CASTUINT(lLength))) {
- // Couldn't do it, return an error.
- return(MK_OUT_OF_MEMORY);
- }
- }
-
- // Copy over the bytes.
- memcpy(pOData->m_pBuffer, cpWriteData, CASTSIZE_T(lLength));
-
- // Write it to the viewer.
- pOData->m_Viewer.Write(&(pOData->m_pBuffer), lLength);
- return(MK_DATA_LOADED);
- }
-
- void ole_StreamComplete(NET_StreamClass *stream) {
- // Purpose: Normally complete the stream.
- // Arguments: vpDataObj The COLEDownloadData object, which we will simply destroy.
- // Returns: void
- // Comments: Return a normal status to the viewer.
-
- // Obtain our download data.
- COLEDownloadData *pOData = (COLEDownloadData *)stream->data_object;
-
- // Close, with no error.
- pOData->m_Viewer.Close(0);
-
- // Delete the object.
- delete(pOData);
- }
-
- void ole_StreamAbort(NET_StreamClass *stream, int iStatus) {
- // Purpose: Abort the stream for miscellaneous reasons.
- // Arguments: vpDataObj The COLEDownloadData object, we'll destroy this.
- // iStatus The error status, which we pay no attention to.
- // Returns: void
- // Comments: Return an error status to the viewer.
-
- // Obtain our download data.
- COLEDownloadData *pOData = (COLEDownloadData *)stream->data_object;
-
- // Close, with error.
- pOData->m_Viewer.Close(-1);
-
- // Delete the object.
- delete(pOData);
- }
-
- unsigned int ole_StreamReady(NET_StreamClass *stream) {
- // Purpose: Return the number of bytes which we are ready to have written to us.
- // Arguments: vpDataObj The COLEDownloadData which handles the download.
- // Returns: unsigned int The number of bytes that we're ready for.
- // Comments: We really simply ask the viewer how much they're ready to handle.
-
- // Obtain our download data.
- COLEDownloadData *pOData = (COLEDownloadData *)stream->data_object;
-
- // Mark that the netlib actually called us.
- pOData->m_bReadyCalled = TRUE;
-
- // Return the amount that the viewer reports.
- return(CASTUINT(pOData->m_Viewer.Ready()));
- }
-
- };
-