VirtualBox

Changeset 30714 in vbox for trunk/include/VBox/com


Ignore:
Timestamp:
Jul 7, 2010 4:20:03 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
63479
Message:

Main: remove SupportErrorInfo template magic

Location:
trunk/include/VBox/com
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/com/SupportErrorInfo.h

    r28800 r30714  
    155155    }
    156156
     157    /**
     158     * Returns true if multi-mode is enabled for the current thread (i.e. at
     159     * least one MultiResult instance exists on the stack somewhere).
     160     * @return
     161     */
     162    static bool isMultiEnabled();
     163
    157164private:
    158165
     
    164171    static RTTLS sCounter;
    165172
    166     friend class SupportErrorInfoBase;
    167173    friend class MultiResultRef;
    168174};
     
    202208};
    203209
    204 /**
    205  * The SupportErrorInfoBase template class provides basic error info support.
    206  *
    207  * Basic error info support includes a group of setError() methods to set
    208  * extended error information on the current thread. This support does not
    209  * include all necessary implementation details (for example, implementation of
    210  * the ISupportErrorInfo interface on MS COM) to make the error info support
    211  * fully functional in a target component. These details are provided by the
    212  * SupportErrorInfoDerived class.
    213  *
    214  * This way, this class is intended to be directly inherited only by
    215  * intermediate component base classes that will be then inherited by final
    216  * component classes through the SupportErrorInfoDerived template class. In
    217  * all other cases, the SupportErrorInfoImpl class should be used as a base for
    218  * final component classes instead.
    219  */
    220 class SupportErrorInfoBase
    221 {
    222     static HRESULT setErrorInternal(HRESULT aResultCode,
    223                                     const GUID *aIID,
    224                                     const char *aComponent,
    225                                     const Utf8Str &strText,
    226                                     bool aWarning,
    227                                     IVirtualBoxErrorInfo *aInfo = NULL);
    228 
    229 protected:
    230 
    231     /**
    232      * Returns an interface ID that is to be used in short setError() variants
    233      * to specify the interface that has defined the error. Must be implemented
    234      * in subclasses.
    235      */
    236     virtual const GUID &mainInterfaceID() const = 0;
    237 
    238     /**
    239      * Returns an component name (in UTF8) that is to be used in short
    240      * setError() variants to specify the interface that has defined the error.
    241      * Must be implemented in subclasses.
    242      */
    243     virtual const char *componentName() const = 0;
    244 
    245     /**
    246      * Same as #setError (HRESULT, const GUID &, const char *, const char *) but
    247      * interprets the @a aText argument as a RTPrintf-like format string and the
    248      * @a aArgs argument as an argument list for this format string.
    249      */
    250     static HRESULT setErrorV(HRESULT aResultCode, const GUID &aIID,
    251                              const char *aComponent, const char *aText,
    252                              va_list aArgs)
    253     {
    254         return setErrorInternal(aResultCode, &aIID, aComponent,
    255                                 Utf8StrFmtVA(aText, aArgs),
    256                                 false /* aWarning */);
    257     }
    258 
    259     /**
    260      * Same as #setWarning (HRESULT, const GUID &, const char *, const char *)
    261      * but interprets the @a aText argument as a RTPrintf-like format string and
    262      * the @a aArgs argument as an argument list for this format string.
    263      */
    264     static HRESULT setWarningV(HRESULT aResultCode, const GUID &aIID,
    265                                const char *aComponent, const char *aText,
    266                                va_list aArgs)
    267     {
    268         return setErrorInternal(aResultCode, &aIID,
    269                                 aComponent,
    270                                 Utf8StrFmtVA(aText, aArgs),
    271                                 true /* aWarning */);
    272     }
    273 
    274     /**
    275      * Same as #setError (HRESULT, const GUID &, const char *, const char *) but
    276      * interprets the @a aText argument as a RTPrintf-like format string and
    277      * takes a variable list of arguments for this format string.
    278      */
    279     static HRESULT setError(HRESULT aResultCode,
    280                             const GUID &aIID,
    281                             const char *aComponent,
    282                             const char *aText,
    283                             ...);
    284 
    285     /**
    286      * Same as #setWarning (HRESULT, const GUID &, const char *, const char *)
    287      * but interprets the @a aText argument as a RTPrintf-like format string and
    288      * takes a variable list of arguments for this format string.
    289      */
    290     static HRESULT setWarning(HRESULT aResultCode, const GUID &aIID,
    291                               const char *aComponent, const char *aText,
    292                               ...);
    293 
    294     /**
    295      * Sets the given error info object on the current thread.
    296      *
    297      * Note that In multi-error mode (see MultiResult), the existing error info
    298      * object (if any) will be preserved by attaching it to the tail of the
    299      * error chain of the given aInfo object.
    300      *
    301      * @param aInfo     Error info object to set (must not be NULL).
    302      */
    303     static HRESULT setErrorInfo(IVirtualBoxErrorInfo *aInfo)
    304     {
    305         AssertReturn (aInfo != NULL, E_FAIL);
    306         return setErrorInternal(0, NULL, NULL, Utf8Str::Null, false, aInfo);
    307     }
    308 
    309     /**
    310      * Same as #setError (HRESULT, const GUID &, const char *, const char *,
    311      * ...) but uses the return value of the mainInterfaceID() method as an @a
    312      * aIID argument and the return value of the componentName() method as a @a
    313      * aComponent argument.
    314      *
    315      * This method is the most common (and convenient) way to set error
    316      * information from within a component method. The typical usage pattern is:
    317      * <code>
    318      *     return setError (E_FAIL, "Terrible Error");
    319      * </code>
    320      * or
    321      * <code>
    322      *     HRESULT rc = setError (E_FAIL, "Terrible Error");
    323      *     ...
    324      *     return rc;
    325      * </code>
    326      */
    327     HRESULT setError(HRESULT aResultCode, const char *aText, ...);
    328 
    329     HRESULT setError(HRESULT aResultCode, const Utf8Str &strText);
    330 
    331     /**
    332      * Same as #setWarning (HRESULT, const GUID &, const char *, const char *,
    333      * ...) but uses the return value of the mainInterfaceID() method as an @a
    334      * aIID argument and the return value of the componentName() method as a @a
    335      * aComponent argument.
    336      *
    337      * This method is the most common (and convenient) way to set warning
    338      * information from within a component method. The typical usage pattern is:
    339      * <code>
    340      *     return setWarning (E_FAIL, "Dangerous warning");
    341      * </code>
    342      * or
    343      * <code>
    344      *     HRESULT rc = setWarning (E_FAIL, "Dangerous warning");
    345      *     ...
    346      *     return rc;
    347      * </code>
    348      */
    349     HRESULT setWarning (HRESULT aResultCode, const char *aText, ...);
    350 
    351     /**
    352      * Same as #setError (HRESULT, const char *, ...) but takes a va_list
    353      * argument instead of a variable argument list.
    354      */
    355     HRESULT setErrorV (HRESULT aResultCode, const char *aText, va_list aArgs)
    356     {
    357         return setError (aResultCode, mainInterfaceID(), componentName(),
    358                          aText, aArgs);
    359     }
    360 
    361     /**
    362      * Same as #setWarning (HRESULT, const char *, ...) but takes a va_list
    363      * argument instead of a variable argument list.
    364      */
    365     HRESULT setWarningV (HRESULT aResultCode, const char *aText, va_list aArgs)
    366     {
    367         return setWarning (aResultCode, mainInterfaceID(), componentName(),
    368                            aText, aArgs);
    369     }
    370 
    371     /**
    372      * Same as #setError (HRESULT, const char *, ...) but allows to specify the
    373      * interface ID manually.
    374      */
    375     HRESULT setError (HRESULT aResultCode, const GUID &aIID,
    376                       const char *aText, ...);
    377 
    378     /**
    379      * Same as #setWarning (HRESULT, const char *, ...) but allows to specify
    380      * the interface ID manually.
    381      */
    382     HRESULT setWarning (HRESULT aResultCode, const GUID &aIID,
    383                         const char *aText, ...);
    384 };
    385 
    386 ////////////////////////////////////////////////////////////////////////////////
    387 
    388 /**
    389  * The SupportErrorInfoDerived template class implements the remaining parts
    390  * of error info support in addition to SupportErrorInfoBase.
    391  *
    392  * These parts include the ISupportErrorInfo implementation on the MS COM
    393  * platform and implementations of mandatory SupportErrorInfoBase virtual
    394  * methods.
    395  *
    396  * On MS COM, the @a C template argument must declare a COM interface map using
    397  * BEGIN_COM_MAP / END_COM_MAP macros and this map must contain a
    398  * COM_INTERFACE_ENTRY(ISupportErrorInfo) definition. All interface entries that
    399  * follow it will be considered to support IErrorInfo, i.e. the
    400  * InterfaceSupportsErrorInfo() implementation will return S_OK for the
    401  * corresponding IIDs.
    402  *
    403  * On all platforms, the @a C template argument must be a subclass of
    404  * SupportErrorInfoBase and also define the following method: <tt>public static
    405  * const char *ComponentName()</tt> that will be used as a value returned by the
    406  * SupportErrorInfoBase::componentName() implementation.
    407  *
    408  * If SupportErrorInfoBase is used as a base for an intermediate component base
    409  * class FooBase then the final component FooFinal that inherits FooBase should
    410  * use this template class as follows:
    411  * <code>
    412  *     class FooFinal : public SupportErrorInfoDerived <FooBase, FooFinal, IFoo>
    413  *     {
    414  *         ...
    415  *     };
    416  * </code>
    417  *
    418  * Note that if you don not use intermediate component base classes, you should
    419  * use the SupportErrorInfoImpl class as a base for your component instead.
    420  *
    421  * @param B     Intermediate component base derived from SupportErrorInfoBase.
    422  * @param C     Component class that implements one or more COM interfaces.
    423  * @param I     Default interface for the component (for short #setError()
    424  *              versions).
    425  */
    426 template <class B, class C, class I>
    427 class ATL_NO_VTABLE SupportErrorInfoDerived : public B
    428 #if !defined (VBOX_WITH_XPCOM)
    429     , public ISupportErrorInfo
    430 #endif
    431 {
    432 public:
    433 
    434 #if !defined (VBOX_WITH_XPCOM)
    435     STDMETHOD(InterfaceSupportsErrorInfo) (REFIID aIID)
    436     {
    437         const _ATL_INTMAP_ENTRY* pEntries = C::_GetEntries();
    438         Assert (pEntries);
    439         if (!pEntries)
    440             return S_FALSE;
    441 
    442         BOOL bSupports = FALSE;
    443         BOOL bISupportErrorInfoFound = FALSE;
    444 
    445         while (pEntries->pFunc != NULL && !bSupports)
    446         {
    447             if (!bISupportErrorInfoFound)
    448             {
    449                 /* skip the COM map entries until ISupportErrorInfo is found */
    450                 bISupportErrorInfoFound =
    451                     InlineIsEqualGUID (*(pEntries->piid), IID_ISupportErrorInfo);
    452             }
    453             else
    454             {
    455                 /* look for the requested interface in the rest of the com map */
    456                 bSupports = InlineIsEqualGUID (*(pEntries->piid), aIID);
    457             }
    458             pEntries++;
    459         }
    460 
    461         Assert (bISupportErrorInfoFound);
    462 
    463         return bSupports ? S_OK : S_FALSE;
    464     }
    465 #endif /* !defined (VBOX_WITH_XPCOM) */
    466 
    467 protected:
    468 
    469     virtual const GUID &mainInterfaceID() const { return COM_IIDOF (I); }
    470 
    471     virtual const char *componentName() const { return C::ComponentName(); }
    472 };
    473 
    474 ////////////////////////////////////////////////////////////////////////////////
    475 
    476 /**
    477  * The SupportErrorInfoImpl template class provides complete error info support
    478  * for COM component classes.
    479  *
    480  * Complete error info support includes what both SupportErrorInfoBase and
    481  * SupportErrorInfoDerived provide, e.g. a variety of setError() methods to
    482  * set extended error information from within a component's method
    483  * implementation and all necessary additional interface implementations (see
    484  * descriptions of these classes for details).
    485  *
    486  * To add error info support to a Foo component that implements a IFoo
    487  * interface, use the following pattern:
    488  * <code>
    489  *     class Foo : public SupportErrorInfoImpl <Foo, IFoo>
    490  *     {
    491  *     public:
    492  *
    493  *         ...
    494  *
    495  *         static const char *ComponentName() const { return "Foo"; }
    496  *     };
    497  * </code>
    498  *
    499  * Note that your component class (the @a C template argument) must provide the
    500  * ComponentName() implementation as shown above.
    501  *
    502  * @param C Component class that implements one or more COM interfaces.
    503  * @param I Default interface for the component (for short #setError()
    504  *          versions).
    505  */
    506 template <class C, class I>
    507 class ATL_NO_VTABLE SupportErrorInfoImpl
    508     : public SupportErrorInfoDerived <SupportErrorInfoBase, C, I>
    509 {
    510 };
    511210
    512211} /* namespace com */
  • trunk/include/VBox/com/VirtualBoxErrorInfo.h

    r28800 r30714  
    144144
    145145    // IVirtualBoxErrorInfo properties
    146     COM_FORWARD_IVirtualBoxErrorInfo_GETTER_ResultCode_TO_OBJ (mReal)
    147     COM_FORWARD_IVirtualBoxErrorInfo_GETTER_InterfaceID_TO_OBJ (mReal)
    148     COM_FORWARD_IVirtualBoxErrorInfo_GETTER_Component_TO_OBJ (mReal)
    149     COM_FORWARD_IVirtualBoxErrorInfo_GETTER_Text_TO_OBJ (mReal)
     146    COM_FORWARD_IVirtualBoxErrorInfo_GETTER_ResultCode_TO_OBJ(mReal)
     147    COM_FORWARD_IVirtualBoxErrorInfo_GETTER_InterfaceID_TO_OBJ(mReal)
     148    COM_FORWARD_IVirtualBoxErrorInfo_GETTER_Component_TO_OBJ(mReal)
     149    COM_FORWARD_IVirtualBoxErrorInfo_GETTER_Text_TO_OBJ(mReal)
    150150    STDMETHOD(COMGETTER(Next)) (IVirtualBoxErrorInfo **aNext);
    151151
  • trunk/include/VBox/com/defs.h

    r30681 r30714  
    225225 *  @param i    interface class
    226226 */
    227 #define COM_IIDOF(I) _ATL_IIDOF (I)
     227#define COM_IIDOF(I) _ATL_IIDOF(I)
    228228
    229229#else /* defined (RT_OS_WINDOWS) */
     
    349349#define STDMETHODIMP NS_IMETHODIMP
    350350
    351 #define COM_IIDOF(I) NS_GET_IID (I)
     351#define COM_IIDOF(I) NS_GET_IID(I)
    352352
    353353/* A few very simple ATL emulator classes to provide
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette