home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / olectc.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  10.0 KB  |  268 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "stdafx.h"
  20.  
  21. #include "olectc.h"
  22.  
  23. #include "presentm.h"
  24. #include "oleview1.h"
  25. #include "cxsave.h"
  26. #include "winproto.h"
  27.  
  28. extern "C" int MK_OUT_OF_MEMORY;   // defined in allxpstr.h
  29.  
  30.  
  31. COLEStreamData::COLEStreamData(const char *pServer, const char *pMimeType) : CStreamData(CStreamData::m_OLE)  {
  32. //    Purpose:    Construct the data stream object.
  33. //    Arguments:  pServer The registry name of the automation server that we should contact in our data stream.
  34. //              pMimeType   The Mime type of the stream.
  35. //    Returns:    none
  36. //    Comments:   Note that we initialize the base class to know that we are an OLE viewer.
  37.  
  38.     //  Just copy over the relevant members.
  39.     m_csServerName = pServer;
  40.     m_csMimeType = pMimeType;
  41. }
  42.  
  43. COLEDownloadData::COLEDownloadData(COLEStreamData *pCData, const char *pAddress)  {
  44. //    Purpose:    Create an instance of the download data.
  45. //    Arguments:  pCData  A global object representing the OLE registered server.
  46. //              pAddress    The URL that we are about to handle.
  47. //    Returns:    none
  48. //    Comments:   Download instance specific member.
  49.  
  50.     //  Assign over our data.
  51.     m_pCData = pCData;
  52.     m_pBuffer = NULL;
  53.     m_bReadyCalled = FALSE;
  54.  
  55.     //  Attach ourselves to the OLE Automation server.
  56.     //  If an exception is thrown, it's handled elsewhere.
  57.     TRACE("%s:Initialize(%s, %s)\n", (const char *)m_pCData->m_csServerName, (const char *)m_pCData->m_csMimeType, pAddress);
  58.     m_Viewer.CreateDispatch(m_pCData->m_csServerName);
  59.     if(0 == m_Viewer.Initialize(m_pCData->m_csMimeType, pAddress)) {
  60.         AfxThrowNotSupportedException();
  61.     }
  62.  
  63.     //  Attempt to allocate a small buffer to start out with.
  64.     //  This may grow later, we don't really care.
  65.     if(NULL == (m_pBuffer = SysAllocStringLen(NULL, m_InitialBufferSize))) {
  66.         AfxThrowMemoryException();
  67.     }
  68. }
  69.  
  70. COLEDownloadData::~COLEDownloadData()   {
  71.     //  Use to free off our buffer if it exists.
  72.     if(m_pBuffer != NULL)   {
  73.         SysFreeString(m_pBuffer);
  74.     }
  75. }
  76.  
  77. extern "C"  {
  78.  
  79. NET_StreamClass *ole_stream(int iFormatOut, void *vpDataObj, URL_Struct *pURL, MWContext *pContext) {
  80. //    Purpose:    Return the stream class for our OLE automated stream.
  81. //    Arguments:  iFormatOut  The representation we are outputting (should be FO_PRESENT only for now)
  82. //              vpDataObj   Our COLEStreamData structure.
  83. //              pURL        The URL we're loading.
  84. //              pContext    The current context that we're loading in.
  85. //    Returns:    NET_StreamClass A group of functions that will handle the intimate details
  86. //                  of the download.
  87. //    Comments:   Set up the data stream.
  88. //              Initiate the conversation with the automation server.
  89. //              The stream will be lost if unable to establish the connection.  Can't really handle well.
  90.  
  91.     //  Convert our data object.
  92.     COLEStreamData *pCData = (COLEStreamData *)vpDataObj;
  93.     COLEDownloadData *pOData = NULL;
  94.     //  Create the stream data.
  95.     TRY {
  96.         pOData = new COLEDownloadData(pCData, pURL->address);
  97.  
  98.         NET_StreamClass *pOleStream = NET_NewStream("Speghetti(SP)",
  99.             ole_StreamWrite,
  100.             ole_StreamComplete,
  101.             ole_StreamAbort,
  102.             ole_StreamReady,
  103.             (void *)pOData,
  104.             pContext);
  105.  
  106.         //    See if we can't get this to load in a seperate context.
  107.         //    It will correctly call the stream members, and also reset
  108.         //        the context if able.
  109.         NET_StreamClass *pRetval =
  110.             CSaveCX::OleStreamObject(pOleStream, pURL, pCData->m_csServerName);
  111.         if(pRetval == NULL)    {
  112.             //    Couldn't switch
  113.             pRetval = pOleStream;
  114.         }
  115.  
  116.         return(pRetval);
  117.     }
  118.     CATCH(CException, e)    {   //  Any exception will do
  119.  
  120.         //  Tell the user that we were unable to complete the operation, ask them if they would like to unregister the OLE viewer.
  121.         TRACE("Couldn't connect to the OLE automation server\n");
  122.         CString csMessage = szLoadString(IDS_OLE_CANTUSE_VIEWER);
  123.         csMessage += pCData->m_csServerName;
  124.         csMessage += szLoadString(IDS_OLE_CANTUSE_VIEWER2);
  125.  
  126.         if(IDNO == AfxMessageBox(csMessage, MB_YESNO))   {
  127.             //  They don't want to use the viewer in the future.
  128.             //  Unregister it; assume FO_PRESENT.
  129.             WPM_UnRegisterContentTypeConverter(pCData->m_csServerName, pCData->m_csMimeType, FO_PRESENT);
  130.  
  131.             //  Remove the registration from the INI file also.
  132.             theApp.WriteProfileString("Automation Viewers", pCData->m_csMimeType, NULL);
  133.  
  134.             //  We know it's registered, and we know it's our current data, so remove it.
  135.             delete(pCData);
  136.         }
  137.         if(pOData != NULL)  {
  138.             delete(pOData);
  139.         }
  140.  
  141.         return(NULL);
  142.     }
  143.     END_CATCH
  144.  
  145.     return(NULL);
  146. }
  147.  
  148. int ole_StreamWrite(NET_StreamClass *stream, const char *cpWriteData, int32 lLength)    {
  149. //    Purpose:    Write data to our automated object.
  150. //    Arguments:  vpDataObject    The COLEDownloadObject for the load.
  151. //              cpWriteData     The data to write.
  152. //              lLength         The length of the string we're writing.
  153. //    Returns:    int MK_DATA_LOADED always.
  154. //    Comments:   Used to write data to the streaming viewer.
  155. //              If the viewer doesn't want the data, it should report the error status in Ready.
  156.  
  157.     void *vpDataObj=stream->data_object;    
  158.     //  Obtain the object.
  159.     COLEDownloadData *pOData = (COLEDownloadData *)vpDataObj;
  160.  
  161.     //  Check to see if the netlib didn't check is_write_ready
  162.     if(pOData->m_bReadyCalled == FALSE) {
  163.         TRACE("Please call Ready first.  This is a serious hack.\n");
  164.  
  165.         //  Since the netlib is being harsh to us, we have to do some special handling here.
  166.         //  We're going to do a tight loop, until the other viewer has gotten all the data
  167.         //      that we just got handed, and then we'll return as normal.
  168.         //  Enough OLE messages will be generated to keep the application running....
  169.         long lReady = 0;
  170.         long lOffset = 0;
  171.         while(1)    {
  172.             lReady = ole_StreamReady(stream);
  173.             if(lReady == 0) {
  174.                 continue;
  175.             }
  176.             else if(lReady < 0)   {
  177.                 //  Hm, they said error.
  178.                 pOData->m_bReadyCalled = FALSE;
  179.                 return(CASTINT(lReady));
  180.             }
  181.  
  182.             //  Okay, see if the ready amount is the amount we can send.
  183.             if(lReady + lOffset >= lLength)  {
  184.                 lReady = lLength - lOffset;
  185.                 if(lReady == 0) {
  186.                     pOData->m_bReadyCalled = FALSE;
  187.                     return(MK_DATA_LOADED);
  188.                 }
  189.             }
  190.  
  191.             //  Send the data.
  192.             ole_StreamWrite(stream, cpWriteData + lOffset, lReady);
  193.  
  194.             //  Increment our offset into the buffer.
  195.             lOffset += lReady;
  196.         }
  197.     }
  198.  
  199.     //  Clear this out for next time.
  200.     pOData->m_bReadyCalled = FALSE;
  201.  
  202.     //  If the length is greater than our buffer, then it's time to resize.
  203.     if((int32)SysStringLen(pOData->m_pBuffer) < lLength)    {
  204.         if(FALSE == SysReAllocStringLen(&(pOData->m_pBuffer), NULL, CASTUINT(lLength)))   {
  205.             //  Couldn't do it, return an error.
  206.             return(MK_OUT_OF_MEMORY);
  207.         }
  208.     }
  209.  
  210.     //  Copy over the bytes.
  211.     memcpy(pOData->m_pBuffer, cpWriteData, CASTSIZE_T(lLength));
  212.  
  213.     //  Write it to the viewer.
  214.     pOData->m_Viewer.Write(&(pOData->m_pBuffer), lLength);
  215.     return(MK_DATA_LOADED);
  216. }
  217.  
  218. void ole_StreamComplete(NET_StreamClass *stream)    {
  219. //    Purpose:    Normally complete the stream.
  220. //    Arguments:  vpDataObj   The COLEDownloadData object, which we will simply destroy.
  221. //    Returns:    void
  222. //    Comments:   Return a normal status to the viewer.
  223.  
  224.     //  Obtain our download data.
  225.     COLEDownloadData *pOData = (COLEDownloadData *)stream->data_object;    
  226.  
  227.     //  Close, with no error.
  228.     pOData->m_Viewer.Close(0);
  229.  
  230.     //  Delete the object.
  231.     delete(pOData);
  232. }
  233.  
  234. void ole_StreamAbort(NET_StreamClass *stream, int iStatus) {
  235. //    Purpose:    Abort the stream for miscellaneous reasons.
  236. //    Arguments:  vpDataObj   The COLEDownloadData object, we'll destroy this.
  237. //              iStatus The error status, which we pay no attention to.
  238. //    Returns:    void
  239. //    Comments:   Return an error status to the viewer.
  240.  
  241.     //  Obtain our download data.
  242.     COLEDownloadData *pOData = (COLEDownloadData *)stream->data_object;    
  243.  
  244.     //  Close, with error.
  245.     pOData->m_Viewer.Close(-1);
  246.  
  247.     //  Delete the object.
  248.     delete(pOData);
  249. }
  250.  
  251. unsigned int ole_StreamReady(NET_StreamClass *stream)   {
  252. //    Purpose:    Return the number of bytes which we are ready to have written to us.
  253. //    Arguments:  vpDataObj   The COLEDownloadData which handles the download.
  254. //    Returns:    unsigned int    The number of bytes that we're ready for.
  255. //    Comments:   We really simply ask the viewer how much they're ready to handle.
  256.  
  257.     //  Obtain our download data.
  258.     COLEDownloadData *pOData = (COLEDownloadData *)stream->data_object;    
  259.  
  260.     //  Mark that the netlib actually called us.
  261.     pOData->m_bReadyCalled = TRUE;    
  262.  
  263.     //  Return the amount that the viewer reports.
  264.     return(CASTUINT(pOData->m_Viewer.Ready()));
  265. }
  266.  
  267. };
  268.