xpcom/glue/nsIClassInfoImpl.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #ifndef nsIClassInfoImpl_h__
     6 #define nsIClassInfoImpl_h__
     8 #include "mozilla/Alignment.h"
     9 #include "mozilla/Assertions.h"
    10 #include "mozilla/MacroArgs.h"
    11 #include "mozilla/MacroForEach.h"
    12 #include "nsIClassInfo.h"
    13 #include "nsISupportsImpl.h"
    15 #include <new>
    17 /**
    18  * This header file provides macros which help you make your class implement
    19  * nsIClassInfo.  Implementing nsIClassInfo is particularly helpful if you have
    20  * a C++ class which implements multiple interfaces and which you access from
    21  * JavaScript.  If that class implements nsIClassInfo, the JavaScript code
    22  * won't have to call QueryInterface on instances of the class; all methods
    23  * from all interfaces returned by GetInterfaces() will be available
    24  * automagically.
    25  *
    26  * Here's all you need to do.  Given a class
    27  *
    28  *   class nsFooBar : public nsIFoo, public nsIBar { };
    29  *
    30  * you should already have the following nsISupports implementation in its cpp
    31  * file:
    32  *
    33  *   NS_IMPL_ISUPPORTS(nsFooBar, nsIFoo, nsIBar).
    34  *
    35  * Change this to
    36  *
    37  *   NS_IMPL_CLASSINFO(nsFooBar, nullptr, 0, NS_FOOBAR_CID)
    38  *   NS_IMPL_ISUPPORTS_CI(nsFooBar, nsIFoo, nsIBar)
    39  *
    40  * If nsFooBar is threadsafe, change the 0 above to nsIClassInfo::THREADSAFE.
    41  * If it's a singleton, use nsIClassInfo::SINGLETON.  The full list of flags is
    42  * in nsIClassInfo.idl.
    43  *
    44  * The nullptr parameter is there so you can pass a function for converting
    45  * from an XPCOM object to a scriptable helper.  Unless you're doing
    46  * specialized JS work, you can probably leave this as nullptr.
    47  *
    48  * This file also defines the NS_IMPL_QUERY_INTERFACE_CI macro, which you can
    49  * use to replace NS_IMPL_QUERY_INTERFACE, if you use that instead of
    50  * NS_IMPL_ISUPPORTS.
    51  *
    52  * That's it!  The rest is gory details.
    53  *
    54  *
    55  * Notice that nsFooBar didn't need to inherit from nsIClassInfo in order to
    56  * "implement" it.  However, after adding these macros to nsFooBar, you you can
    57  * QueryInterface an instance of nsFooBar to nsIClassInfo.  How can this be?
    58  *
    59  * The answer lies in the NS_IMPL_ISUPPORTS_CI macro.  It modifies nsFooBar's
    60  * QueryInterface implementation such that, if we ask to QI to nsIClassInfo, it
    61  * returns a singleton object associated with the class.  (That singleton is
    62  * defined by NS_IMPL_CLASSINFO.)  So all nsFooBar instances will return the
    63  * same object when QI'ed to nsIClassInfo.  (You can see this in
    64  * NS_IMPL_QUERY_CLASSINFO below.)
    65  *
    66  * This hack breaks XPCOM's rules, since if you take an instance of nsFooBar,
    67  * QI it to nsIClassInfo, and then try to QI to nsIFoo, that will fail.  On the
    68  * upside, implementing nsIClassInfo doesn't add a vtable pointer to instances
    69  * of your class.
    70  *
    71  * In principal, you can also implement nsIClassInfo by inheriting from the
    72  * interface.  But some code expects that when it QI's an object to
    73  * nsIClassInfo, it gets back a singleton which isn't attached to any
    74  * particular object.  If a class were to implement nsIClassInfo through
    75  * inheritance, that code might QI to nsIClassInfo and keep the resulting
    76  * object alive, thinking it was only keeping alive the classinfo singleton,
    77  * but in fact keeping a whole instance of the class alive.  See, e.g., bug
    78  * 658632.
    79  *
    80  * Unless you specifically need to have a different nsIClassInfo instance for
    81  * each instance of your class, you should probably just implement nsIClassInfo
    82  * as a singleton.
    83  */
    85 class NS_COM_GLUE GenericClassInfo : public nsIClassInfo
    86 {
    87 public:
    88   struct ClassInfoData
    89   {
    90     typedef NS_CALLBACK(GetInterfacesProc)(uint32_t* countp,
    91                                            nsIID*** array);
    92     typedef NS_CALLBACK(GetLanguageHelperProc)(uint32_t language,
    93                                                nsISupports** helper);
    95     GetInterfacesProc getinterfaces;
    96     GetLanguageHelperProc getlanguagehelper;
    97     uint32_t flags;
    98     nsCID cid;
    99   };
   101   NS_DECL_ISUPPORTS_INHERITED
   102   NS_DECL_NSICLASSINFO
   104   GenericClassInfo(const ClassInfoData* data)
   105     : mData(data)
   106   { }
   108 private:
   109   const ClassInfoData* mData;
   110 };
   112 #define NS_CLASSINFO_NAME(_class) g##_class##_classInfoGlobal
   113 #define NS_CI_INTERFACE_GETTER_NAME(_class) _class##_GetInterfacesHelper
   114 #define NS_DECL_CI_INTERFACE_GETTER(_class)                                   \
   115   extern NS_IMETHODIMP NS_CI_INTERFACE_GETTER_NAME(_class)                    \
   116      (uint32_t *, nsIID ***);
   118 #define NS_IMPL_CLASSINFO(_class, _getlanguagehelper, _flags, _cid)     \
   119   NS_DECL_CI_INTERFACE_GETTER(_class)                                   \
   120   static const GenericClassInfo::ClassInfoData k##_class##ClassInfoData = { \
   121     NS_CI_INTERFACE_GETTER_NAME(_class),                                \
   122     _getlanguagehelper,                                                 \
   123     _flags | nsIClassInfo::SINGLETON_CLASSINFO,                         \
   124     _cid,                                                               \
   125   };                                                                    \
   126   mozilla::AlignedStorage2<GenericClassInfo> k##_class##ClassInfoDataPlace;   \
   127   nsIClassInfo* NS_CLASSINFO_NAME(_class) = nullptr;
   129 #define NS_IMPL_QUERY_CLASSINFO(_class)                                       \
   130   if ( aIID.Equals(NS_GET_IID(nsIClassInfo)) ) {                              \
   131     if (!NS_CLASSINFO_NAME(_class))                                           \
   132       NS_CLASSINFO_NAME(_class) = new (k##_class##ClassInfoDataPlace.addr())  \
   133         GenericClassInfo(&k##_class##ClassInfoData);                          \
   134     foundInterface = NS_CLASSINFO_NAME(_class);                               \
   135   } else
   137 #define NS_CLASSINFO_HELPER_BEGIN(_class, _c)                                 \
   138 NS_IMETHODIMP                                                                 \
   139 NS_CI_INTERFACE_GETTER_NAME(_class)(uint32_t *count, nsIID ***array)          \
   140 {                                                                             \
   141     *count = _c;                                                              \
   142     *array = (nsIID **)nsMemory::Alloc(sizeof (nsIID *) * _c);                \
   143     uint32_t i = 0;
   145 #define NS_CLASSINFO_HELPER_ENTRY(_interface)                                 \
   146     (*array)[i++] = (nsIID*)nsMemory::Clone(&NS_GET_IID(_interface),          \
   147                                             sizeof(nsIID));
   149 #define NS_CLASSINFO_HELPER_END                                               \
   150     MOZ_ASSERT(i == *count, "Incorrent number of entries");                   \
   151     return NS_OK;                                                             \
   152 }
   154 #define NS_IMPL_CI_INTERFACE_GETTER(aClass, ...)                              \
   155   MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__);                             \
   156   NS_CLASSINFO_HELPER_BEGIN(aClass,                                           \
   157                             MOZ_PASTE_PREFIX_AND_ARG_COUNT(/* No prefix */,   \
   158                                                            __VA_ARGS__))      \
   159     MOZ_FOR_EACH(NS_CLASSINFO_HELPER_ENTRY, (), (__VA_ARGS__))                \
   160   NS_CLASSINFO_HELPER_END
   162 #define NS_IMPL_QUERY_INTERFACE_CI(aClass, ...)                               \
   163   MOZ_STATIC_ASSERT_VALID_ARG_COUNT(__VA_ARGS__);                             \
   164   NS_INTERFACE_MAP_BEGIN(aClass)                                              \
   165     MOZ_FOR_EACH(NS_INTERFACE_MAP_ENTRY, (), (__VA_ARGS__))                   \
   166     NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, MOZ_ARG_1(__VA_ARGS__))     \
   167     NS_IMPL_QUERY_CLASSINFO(aClass)                                           \
   168   NS_INTERFACE_MAP_END
   170 #define NS_IMPL_ISUPPORTS_CI(aClass, ...)                                     \
   171   NS_IMPL_ADDREF(aClass)                                                      \
   172   NS_IMPL_RELEASE(aClass)                                                     \
   173   NS_IMPL_QUERY_INTERFACE_CI(aClass, __VA_ARGS__)                             \
   174   NS_IMPL_CI_INTERFACE_GETTER(aClass, __VA_ARGS__)
   176 #endif // nsIClassInfoImpl_h__

mercurial