home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / object10 / oobject.cpp < prev    next >
C/C++ Source or Header  |  1995-03-20  |  12KB  |  472 lines

  1. /* Copyright (c) Oracle Corporation 1994.  All Rights Reserved */
  2.  
  3. /*
  4.     This source code is provided as a debugging aid for developers
  5.     who have purchased Oracle Objects for OLE    .  Please see the
  6.     online help for documentation of these classes.
  7. */
  8.  
  9. /*
  10.     Oracle Objects for OLE     C++ Classes
  11.     
  12.     This file implements the OOracleObject class
  13.                            
  14.     CREATED    ********   11/22/94
  15.     RWOOLARD    MODIFIED    03/20/95
  16.                 bug#    262912    *ErrorText should return "" and not NULL
  17.                         262914    *ErrorText should return const char *
  18. */
  19.  
  20. #include "windows.h"
  21. #include <ole2.h>
  22. #include <olenls.h>       
  23. #include <dispatch.h>  
  24.  
  25. #ifndef ORACL_ORACLE
  26. #include "oracl.h"
  27. #endif
  28.  
  29. #ifndef _OracleInProcServer_H_
  30. #include <oratlb.h>
  31. #endif
  32.  
  33. #ifndef ORAOBJI_ORACLE
  34. #include "oraobji.h"
  35. #endif
  36.  
  37. static const IID IID_IExDispatch =
  38. {0x51309a40, 0x14ba, 0x101b, { 0x91, 0x9e, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  39.  
  40. // values for error state
  41. #define OERROR_OBJECT -1 // use the normal object error interface
  42. #define OERROR_OTHER -2  // indicates that we should use "other" interface
  43. #define OERROR_INTERNAL -3  // some error in our code - no error interface has the error 
  44.  
  45.  
  46. // ----- OOracleObject -----------------------------------------------
  47.  
  48. // default constructor
  49. OOracleObject::OOracleObject(void)
  50. {
  51.     // we haven't opened interfaces yet - they're null
  52.     m_obji = 0;
  53.     m_erri = 0;
  54.     m_errotheri = 0;
  55.     m_errstate = OERROR_OBJECT;
  56.     m_errno = OERROR_NONE;
  57.     m_lasterrstring = 0;
  58. }
  59.  
  60. // copy construtor
  61. OOracleObject::OOracleObject(const OOracleObject &other)
  62. {
  63.     m_obji = 0;
  64.     m_erri = 0;
  65.     m_errotheri = 0;
  66.     m_errstate = OERROR_OBJECT;
  67.     m_errno = OERROR_NONE;
  68.     m_lasterrstring = 0;
  69.     // copy new state
  70.     Copy(other);
  71. }
  72.  
  73. // destructor
  74. OOracleObject::~OOracleObject(void)
  75. {
  76.     // clean out current state
  77.     Cleanup();
  78. }
  79.  
  80. // overloaded assignment operator
  81. OOracleObject &OOracleObject::operator=(const OOracleObject &other)
  82. {
  83.     if (&other == this)
  84.         return(*this); // self assignment - do nothing
  85.     
  86.     // clear out our old state
  87.     if (OSUCCESS == Cleanup())
  88.     {
  89.         Copy(other); // call copy constructor
  90.     }
  91.     // if the cleanup failed (possible but unlikely) we don't do the copy
  92.     //    and as a result, we pass on the unmodified (or partly cleaned!) object
  93.     
  94.     return(*this);
  95.  
  96. int OOracleObject::operator==(const OOracleObject &other) const
  97. {
  98.     // closed objects are never equal to anything
  99.     if (!m_obji)
  100.         return(FALSE);
  101.     return(m_obji == other.m_obji);
  102. }
  103.  
  104. int OOracleObject::operator!=(const OOracleObject &other) const
  105. {
  106.     // closed objects are never equal to anything
  107.     if (!m_obji)
  108.         return(TRUE);
  109.     
  110.     return(m_obji != other.m_obji);
  111. }
  112.  
  113. void *OOracleObject::Internal(void) const
  114. {
  115.     return m_obji;
  116. }
  117.  
  118. oboolean OOracleObject::IsOpen(void) const
  119. {
  120.     return (m_obji ? TRUE : FALSE);
  121. }
  122.  
  123. // routine to clean up current state
  124. //   This routine makes the object look as it did after default constructor
  125. oresult OOracleObject::Cleanup(void)
  126. {
  127.     if (m_obji)
  128.     {  // release object interface
  129.         ((IDispatch *) m_obji)->Release();
  130.         m_obji = 0;
  131.     }
  132.     
  133.     if (m_erri)
  134.     {   // release error interface
  135.         ((_IExDispatch *) m_erri)->Release();
  136.         m_erri = 0;
  137.     }
  138.     
  139.     if (m_errotheri)
  140.     {   // release error interface
  141.         ((_IExDispatch *) m_errotheri)->Release();
  142.         m_errotheri = 0;
  143.     }
  144.     
  145.     if (m_lasterrstring)
  146.     {
  147.         OObjectFreeString(m_lasterrstring);
  148.         m_lasterrstring = 0;
  149.     }
  150.     
  151.     m_errstate = OERROR_OBJECT;
  152.     m_errno = OERROR_NONE;
  153.     
  154.     return(OSUCCESS);
  155. }
  156.  
  157. oresult OOracleObject::Copy(const OOracleObject &other)
  158. {
  159.     if (other.m_obji)
  160.     { // copy the object interface
  161.         m_obji = other.m_obji;
  162.         ((IDispatch *) m_obji)->AddRef();
  163.     }
  164.     else
  165.         m_obji = 0;
  166.     
  167.     // copy error information
  168.     if (other.m_erri)
  169.     { // copy the error interface
  170.         m_erri = other.m_erri;
  171.         ((_IExDispatch *) m_erri)->AddRef();
  172.     }
  173.     else
  174.         m_erri = 0;
  175.     
  176.     if (other.m_errotheri)
  177.     { // copy the other error interface
  178.         m_errotheri = other.m_errotheri;
  179.         ((_IExDispatch *) m_errotheri)->AddRef();
  180.     }
  181.     else
  182.         m_errotheri = 0;
  183.     
  184.     m_errno = other.m_errno;
  185.     m_errstate = other.m_errstate;
  186.     
  187.     // we don't bother copying m_lasterrstring
  188.     m_lasterrstring = 0;
  189.     
  190.     
  191.     return(OSUCCESS);    
  192. }
  193.  
  194. // SetObjectInterface - lets subclasses set the object interface
  195. oresult OOracleObject::SetObjectInterface(void *obji, oboolean geterror)
  196. {
  197.     // get rid of old object & error interfaces
  198.     OOracleObject::Cleanup();
  199.     
  200.     // take care of error interface
  201.     if (geterror)
  202.     {  // try to get error interface from object
  203.         HRESULT hc;
  204.         hc = ((IDispatch *) obji)->QueryInterface(IID_IExDispatch, &m_erri);
  205.         if (FAILED(hc))
  206.         {
  207.             m_erri = 0; // to be sure 
  208.         
  209.             // set error condition
  210.             SetInternalError(OERROR_NOINTER);
  211.             return(OFAILURE);
  212.         }
  213.     }
  214.     else
  215.     { // don't even try to get error interface (maybe there isn't one...)
  216.         m_erri = 0;
  217.     }
  218.     
  219.     // everything went fine
  220.     
  221.     // set the new object interface
  222.     m_obji = obji;
  223.     
  224.     ErrorReset();
  225.     
  226.     return(OSUCCESS);
  227. }
  228.  
  229. // helper routine for all the routines that do something...
  230. oresult OOracleObject::ActionStart(void) const
  231. {
  232.     if (!IsOpen())
  233.     {
  234.         SetInternalError(OERROR_NOTOPEN);
  235.         return(OFAILURE);
  236.     }
  237.     ErrorReset();
  238.  
  239.     return(OSUCCESS);
  240. }
  241.  
  242. // helper routine for all the routines that return an object...
  243. oresult OOracleObject::ActionGetStart(const OOracleObject *nobj) const
  244. {
  245.     if (!IsOpen())
  246.     {
  247.         SetInternalError(OERROR_NOTOPEN);
  248.         nobj->SetInternalError(OERROR_INVPARENT);
  249.         return(OFAILURE);
  250.     }
  251.     ErrorReset();
  252.  
  253.     return(OSUCCESS);
  254. }
  255.  
  256. void OOracleObject::ErrorReset(void) const
  257. {
  258.     // we need non-const version of "this" for manipulating error state
  259.     OOracleObject *op = (OOracleObject *) this;
  260.     
  261.     if (m_erri)
  262.     {
  263.         ((_IExDispatch *) m_erri)->Reset();
  264.     }
  265.     
  266.     if (m_errotheri)
  267.     {   // release other error interface (we don't need it anymore)
  268.         ((_IExDispatch *) m_errotheri)->Release();
  269.         op->m_errotheri = 0;
  270.     }
  271.     
  272.     if (m_lasterrstring)
  273.     {
  274.         OObjectFreeString(m_lasterrstring);
  275.         op->m_lasterrstring = 0;
  276.     }
  277.     
  278.     op->m_errstate = OERROR_OBJECT;
  279.     op->m_errno = OERROR_NONE;
  280.     
  281.     return;   
  282. }
  283.  
  284. void OOracleObject::SetOtherError(void *otheri) const
  285. {
  286.     // we need non-const version of "this" for manipulating error state
  287.     OOracleObject *op = (OOracleObject *) this;
  288.     
  289.     if (m_errotheri)
  290.     {   // release old other error interface (we don't need it anymore)
  291.         ((_IExDispatch *) m_errotheri)->Release();
  292.         op->m_errotheri = 0;
  293.     }
  294.     
  295.     if (m_lasterrstring)
  296.     {
  297.         OObjectFreeString(m_lasterrstring);
  298.         op->m_lasterrstring = 0;
  299.     }
  300.     
  301.     // try to get other error interface
  302.     HRESULT hc;
  303.     void *errotheri;
  304.     hc = ((IDispatch *) otheri)->QueryInterface(IID_IExDispatch, &errotheri);
  305.     if (FAILED(hc))
  306.     {// yikes! now we don't have the proper error info at all!
  307.         // we'd better not ever get here...
  308.         op->m_errotheri = 0; // to be sure 
  309.         
  310.         // set error condition
  311.         SetInternalError(OERROR_NOINTER);
  312.     }
  313.     else
  314.     { // we got the error interface
  315.         op->m_errotheri = errotheri;
  316.         op->m_errstate = OERROR_OTHER;
  317.         op->m_errno = OERROR_NONE;  // actual error is contained in the other interface
  318.     }
  319.     
  320.     return;
  321. }
  322.  
  323. void OOracleObject::SetInternalError(long errno) const
  324. {
  325.     // we need non-const version of "this" for manipulating error state
  326.     OOracleObject *op = (OOracleObject *) this;
  327.     
  328.     if (m_errotheri)
  329.     {   // release other error interface (we don't need it anymore)
  330.         ((_IExDispatch *) m_errotheri)->Release();
  331.         op->m_errotheri = 0;
  332.     }
  333.     
  334.     if (m_lasterrstring)
  335.     {
  336.         OObjectFreeString(m_lasterrstring);
  337.         op->m_lasterrstring = 0;
  338.     }
  339.     
  340.     op->m_errstate = OERROR_INTERNAL;
  341.     op->m_errno = errno;
  342.     
  343.     return;
  344. }
  345.  
  346. long OOracleObject::ErrorNumber(void) const
  347. {
  348.     // note that just because m_errno contains OERROR_NONE doesn't mean that
  349.     // there is no error.  If the errstate is OERROR_OBJECT or OERROR_OTHER there
  350.     // may be an error in the interface we don't know about yet
  351.     
  352.     long errno = 0;
  353.     HRESULT hr;
  354.  
  355.     if (m_errstate == OERROR_INTERNAL)
  356.     { // internal error condition
  357.         return(m_errno);
  358.     }
  359.     else if (m_errstate == OERROR_OBJECT)
  360.     {
  361.         if (m_erri)
  362.         {
  363.             hr = ((_IExDispatch *) m_erri)->get_ResultCode();
  364.             long scode = GetScode(hr);
  365.             if (SUCCEEDED(scode))
  366.                 errno = OERROR_NONE;
  367.             else
  368.             { // try to translate the error
  369.                 // what facility is this?
  370.                 if (SCODE_FACILITY(scode) == 4)
  371.                 { // this is interface-specific errors, that's us
  372.                     errno = SCODE_CODE(scode);
  373.                 }
  374.                 else // some other facility - just return generic "implementation" error
  375.                     errno = OERROR_SYSTEM;
  376.             }
  377.         }
  378.         else
  379.         { // must be object that doesn't have error interface
  380.             errno = m_errno;
  381.         }
  382.     }
  383.     else if (m_errstate == OERROR_OTHER && m_errotheri)
  384.     {
  385.         hr = ((_IExDispatch *) m_errotheri)->get_ResultCode();
  386.         long scode = GetScode(hr);
  387.         if (SUCCEEDED(scode))
  388.             errno = OERROR_NONE;
  389.         else
  390.         {
  391.             if (SCODE_FACILITY(scode) == 4)
  392.             { // this is interface-specific errors, that's us
  393.                 errno = SCODE_CODE(scode);
  394.             }
  395.             else // some other facility - just return generic "implementation" error
  396.                 errno = OERROR_SYSTEM;
  397.         }
  398.     }
  399.     else
  400.     { // error state indicated an interface that is gone!
  401.         errno = OERROR_BADERR;
  402.     }    
  403.     
  404.     return(errno);
  405. }
  406.  
  407. // BUG #262914
  408. const char *OOracleObject::LookupErrorText(long errno) const
  409. {
  410.     // we need non-const version of "this" for manipulating error state
  411.     OOracleObject *op = (OOracleObject *) this;
  412.     
  413.     // any such text message should be obtainable from the error object (?)
  414.     if (m_erri)
  415.     {
  416.         if (m_lasterrstring)
  417.         {  // we've already got a string - free it
  418.             OObjectFreeString(m_lasterrstring);
  419.             op->m_lasterrstring = 0;
  420.         }
  421.  
  422.         op->m_lasterrstring = ((_IExDispatch *) m_erri)->LookupScodeText(errno);
  423.         return(m_lasterrstring ? m_lasterrstring : "");
  424.     }
  425.     else
  426. // BUG #262912
  427.         return("");       
  428. }
  429.  
  430. // BUG #262914
  431. const char *OOracleObject::GetErrorText(void) const
  432. {
  433.     // we need non-const version of "this" for manipulating error state
  434.     OOracleObject *op = (OOracleObject *) this;
  435.     
  436.     if (m_lasterrstring)
  437.     {  // we've already got a string - free it
  438.         OObjectFreeString(m_lasterrstring);
  439.         op->m_lasterrstring = 0;
  440.     }
  441.  
  442.     if (m_errstate == OERROR_INTERNAL)
  443.     { // internal error condition
  444.         op->m_lasterrstring = 0;
  445.     }
  446.     else if (m_errstate == OERROR_OBJECT)
  447.     {
  448.         if (m_erri)
  449.             op->m_lasterrstring = ((_IExDispatch *) m_erri)->get_ResultText();
  450.         else
  451.             op->m_lasterrstring = 0;  // object with no error interface
  452.     }
  453.     else if (m_errstate == OERROR_OTHER && m_errotheri)
  454.     {
  455.         op->m_lasterrstring = ((_IExDispatch *) m_errotheri)->get_ResultText();
  456.     }
  457.     else
  458.     { // error state indicated an interface that is gone!
  459.         op->m_lasterrstring = 0;
  460.     }
  461.     
  462. // BUG #262912
  463.     return(m_lasterrstring ? m_lasterrstring : "");   
  464. }
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.