tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

IUnknownImpl.h (6784B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. *
      6 */
      7 
      8 #ifndef mozilla_a11y_IUnknownImpl_h_
      9 #define mozilla_a11y_IUnknownImpl_h_
     10 
     11 #include <windows.h>
     12 #undef CreateEvent  // thank you windows you're such a helper
     13 #include "nsError.h"
     14 
     15 // Avoid warning C4509 like "nonstandard extension used:
     16 // 'AccessibleWrap::[acc_getName]' uses SEH and 'name' has destructor.
     17 // At this point we're catching a crash which is of much greater
     18 // importance than the missing dereference for the nsCOMPtr<>
     19 #ifdef _MSC_VER
     20 #  pragma warning(disable : 4509)
     21 #endif
     22 
     23 namespace mozilla {
     24 namespace a11y {
     25 
     26 class AutoRefCnt {
     27 public:
     28  AutoRefCnt() : mValue(0) {}
     29 
     30  ULONG operator++() { return ++mValue; }
     31  ULONG operator--() { return --mValue; }
     32  ULONG operator++(int) { return ++mValue; }
     33  ULONG operator--(int) { return --mValue; }
     34 
     35  operator ULONG() const { return mValue; }
     36 
     37 private:
     38  ULONG mValue;
     39 };
     40 
     41 }  // namespace a11y
     42 }  // namespace mozilla
     43 
     44 #define DECL_IUNKNOWN                                                        \
     45 public:                                                                     \
     46  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**) override; \
     47  ULONG STDMETHODCALLTYPE AddRef() override {                                \
     48    MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");                     \
     49    ++mRefCnt;                                                               \
     50    return mRefCnt;                                                          \
     51  }                                                                          \
     52  ULONG STDMETHODCALLTYPE Release() override {                               \
     53    MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");                         \
     54    --mRefCnt;                                                               \
     55    if (mRefCnt) return mRefCnt;                                             \
     56                                                                             \
     57    delete this;                                                             \
     58    return 0;                                                                \
     59  }                                                                          \
     60                                                                             \
     61 private:                                                                    \
     62  mozilla::a11y::AutoRefCnt mRefCnt;                                         \
     63                                                                             \
     64 public:
     65 
     66 #define DECL_IUNKNOWN_INHERITED \
     67 public:                        \
     68  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**) override;
     69 
     70 #define IMPL_IUNKNOWN_QUERY_HEAD(Class)                     \
     71  STDMETHODIMP                                              \
     72  Class::QueryInterface(REFIID aIID, void** aInstancePtr) { \
     73    if (!aInstancePtr) return E_INVALIDARG;                 \
     74    *aInstancePtr = nullptr;                                \
     75                                                            \
     76    [[maybe_unused]] HRESULT hr = E_NOINTERFACE;
     77 
     78 #define IMPL_IUNKNOWN_QUERY_TAIL \
     79  return hr;                     \
     80  }
     81 
     82 #define IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(Member)  \
     83  return Member->QueryInterface(aIID, aInstancePtr); \
     84  }
     85 
     86 #define IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(BaseClass)   \
     87  return BaseClass::QueryInterface(aIID, aInstancePtr); \
     88  }
     89 
     90 #define IMPL_IUNKNOWN_QUERY_IFACE(Iface)       \
     91  if (aIID == IID_##Iface) {                   \
     92    *aInstancePtr = static_cast<Iface*>(this); \
     93    AddRef();                                  \
     94    return S_OK;                               \
     95  }
     96 
     97 #define IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(Iface, aResolveIface)           \
     98  if (aIID == IID_##Iface) {                                                \
     99    *aInstancePtr = static_cast<Iface*>(static_cast<aResolveIface*>(this)); \
    100    AddRef();                                                               \
    101    return S_OK;                                                            \
    102  }
    103 
    104 #define IMPL_IUNKNOWN_QUERY_CLASS(Class)          \
    105  hr = Class::QueryInterface(aIID, aInstancePtr); \
    106  if (SUCCEEDED(hr)) return hr;
    107 
    108 #define IMPL_IUNKNOWN_QUERY_CLASS_COND(Class, Cond) \
    109  if (Cond) {                                       \
    110    hr = Class::QueryInterface(aIID, aInstancePtr); \
    111    if (SUCCEEDED(hr)) return hr;                   \
    112  }
    113 
    114 #define IMPL_IUNKNOWN_QUERY_AGGR_COND(Member, Cond)  \
    115  if (Cond) {                                        \
    116    hr = Member->QueryInterface(aIID, aInstancePtr); \
    117    if (SUCCEEDED(hr)) return hr;                    \
    118  }
    119 
    120 #define IMPL_IUNKNOWN1(Class, I1)      \
    121  IMPL_IUNKNOWN_QUERY_HEAD(Class)      \
    122  IMPL_IUNKNOWN_QUERY_IFACE(I1);       \
    123  IMPL_IUNKNOWN_QUERY_IFACE(IUnknown); \
    124  IMPL_IUNKNOWN_QUERY_TAIL
    125 
    126 #define IMPL_IUNKNOWN2(Class, I1, I2)                \
    127  IMPL_IUNKNOWN_QUERY_HEAD(Class)                    \
    128  IMPL_IUNKNOWN_QUERY_IFACE(I1);                     \
    129  IMPL_IUNKNOWN_QUERY_IFACE(I2);                     \
    130  IMPL_IUNKNOWN_QUERY_IFACE_AMBIGIOUS(IUnknown, I1); \
    131  IMPL_IUNKNOWN_QUERY_TAIL
    132 
    133 #define IMPL_IUNKNOWN_INHERITED1(Class, Super0, Super1) \
    134  IMPL_IUNKNOWN_QUERY_HEAD(Class)                       \
    135  IMPL_IUNKNOWN_QUERY_CLASS(Super1);                    \
    136  IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0)
    137 
    138 #define IMPL_IUNKNOWN_INHERITED2(Class, Super0, Super1, Super2) \
    139  IMPL_IUNKNOWN_QUERY_HEAD(Class)                               \
    140  IMPL_IUNKNOWN_QUERY_CLASS(Super1);                            \
    141  IMPL_IUNKNOWN_QUERY_CLASS(Super2);                            \
    142  IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(Super0)
    143 
    144 /**
    145 * Overrides AddRef and Release to call a specific base class.
    146 * If you are inheriting a single class (e.g. to override some methods), you
    147 * shouldn't need to use this. However, if you are inheriting from a COM
    148 * implementation and also inheriting additional COM interfaces, you will need
    149 * to use this to specify which base implements reference counting.
    150 */
    151 #define IMPL_IUNKNOWN_REFCOUNTING_INHERITED(BaseClass)                      \
    152 public:                                                                    \
    153  ULONG STDMETHODCALLTYPE AddRef() override { return BaseClass::AddRef(); } \
    154  ULONG STDMETHODCALLTYPE Release() override { return BaseClass::Release(); }
    155 
    156 namespace mozilla {
    157 namespace a11y {
    158 
    159 /**
    160 * Converts nsresult to HRESULT.
    161 */
    162 HRESULT GetHRESULT(nsresult aResult);
    163 
    164 }  // namespace a11y
    165 }  // namespace mozilla
    166 
    167 #endif