modules/libpref/src/nsPrefBranch.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #ifndef nsPrefBranch_h
michael@0 7 #define nsPrefBranch_h
michael@0 8
michael@0 9 #include "nsCOMPtr.h"
michael@0 10 #include "nsIObserver.h"
michael@0 11 #include "nsIPrefBranch.h"
michael@0 12 #include "nsIPrefBranchInternal.h"
michael@0 13 #include "nsIPrefLocalizedString.h"
michael@0 14 #include "nsXPCOM.h"
michael@0 15 #include "nsISupportsPrimitives.h"
michael@0 16 #include "nsIRelativeFilePref.h"
michael@0 17 #include "nsIFile.h"
michael@0 18 #include "nsString.h"
michael@0 19 #include "nsTArray.h"
michael@0 20 #include "nsWeakReference.h"
michael@0 21 #include "nsClassHashtable.h"
michael@0 22 #include "nsCRT.h"
michael@0 23 #include "nsISupportsImpl.h"
michael@0 24 #include "mozilla/HashFunctions.h"
michael@0 25 #include "mozilla/MemoryReporting.h"
michael@0 26
michael@0 27 namespace mozilla {
michael@0 28 class PreferenceServiceReporter;
michael@0 29 } // namespace mozilla;
michael@0 30
michael@0 31 class nsPrefBranch;
michael@0 32
michael@0 33 class PrefCallback : public PLDHashEntryHdr {
michael@0 34 friend class mozilla::PreferenceServiceReporter;
michael@0 35
michael@0 36 public:
michael@0 37 typedef PrefCallback* KeyType;
michael@0 38 typedef const PrefCallback* KeyTypePointer;
michael@0 39
michael@0 40 static const PrefCallback* KeyToPointer(PrefCallback *aKey)
michael@0 41 {
michael@0 42 return aKey;
michael@0 43 }
michael@0 44
michael@0 45 static PLDHashNumber HashKey(const PrefCallback *aKey)
michael@0 46 {
michael@0 47 uint32_t hash = mozilla::HashString(aKey->mDomain);
michael@0 48 return mozilla::AddToHash(hash, aKey->mCanonical);
michael@0 49 }
michael@0 50
michael@0 51
michael@0 52 public:
michael@0 53 // Create a PrefCallback with a strong reference to its observer.
michael@0 54 PrefCallback(const char *aDomain, nsIObserver *aObserver,
michael@0 55 nsPrefBranch *aBranch)
michael@0 56 : mDomain(aDomain),
michael@0 57 mBranch(aBranch),
michael@0 58 mWeakRef(nullptr),
michael@0 59 mStrongRef(aObserver)
michael@0 60 {
michael@0 61 MOZ_COUNT_CTOR(PrefCallback);
michael@0 62 nsCOMPtr<nsISupports> canonical = do_QueryInterface(aObserver);
michael@0 63 mCanonical = canonical;
michael@0 64 }
michael@0 65
michael@0 66 // Create a PrefCallback with a weak reference to its observer.
michael@0 67 PrefCallback(const char *aDomain,
michael@0 68 nsISupportsWeakReference *aObserver,
michael@0 69 nsPrefBranch *aBranch)
michael@0 70 : mDomain(aDomain),
michael@0 71 mBranch(aBranch),
michael@0 72 mWeakRef(do_GetWeakReference(aObserver)),
michael@0 73 mStrongRef(nullptr)
michael@0 74 {
michael@0 75 MOZ_COUNT_CTOR(PrefCallback);
michael@0 76 nsCOMPtr<nsISupports> canonical = do_QueryInterface(aObserver);
michael@0 77 mCanonical = canonical;
michael@0 78 }
michael@0 79
michael@0 80 // Copy constructor needs to be explicit or the linker complains.
michael@0 81 PrefCallback(const PrefCallback *&aCopy)
michael@0 82 : mDomain(aCopy->mDomain),
michael@0 83 mBranch(aCopy->mBranch),
michael@0 84 mWeakRef(aCopy->mWeakRef),
michael@0 85 mStrongRef(aCopy->mStrongRef),
michael@0 86 mCanonical(aCopy->mCanonical)
michael@0 87 {
michael@0 88 MOZ_COUNT_CTOR(PrefCallback);
michael@0 89 }
michael@0 90
michael@0 91 ~PrefCallback()
michael@0 92 {
michael@0 93 MOZ_COUNT_DTOR(PrefCallback);
michael@0 94 }
michael@0 95
michael@0 96 bool KeyEquals(const PrefCallback *aKey) const
michael@0 97 {
michael@0 98 // We want to be able to look up a weakly-referencing PrefCallback after
michael@0 99 // its observer has died so we can remove it from the table. Once the
michael@0 100 // callback's observer dies, its canonical pointer is stale -- in
michael@0 101 // particular, we may have allocated a new observer in the same spot in
michael@0 102 // memory! So we can't just compare canonical pointers to determine
michael@0 103 // whether aKey refers to the same observer as this.
michael@0 104 //
michael@0 105 // Our workaround is based on the way we use this hashtable: When we ask
michael@0 106 // the hashtable to remove a PrefCallback whose weak reference has
michael@0 107 // expired, we use as the key for removal the same object as was inserted
michael@0 108 // into the hashtable. Thus we can say that if one of the keys' weak
michael@0 109 // references has expired, the two keys are equal iff they're the same
michael@0 110 // object.
michael@0 111
michael@0 112 if (IsExpired() || aKey->IsExpired())
michael@0 113 return this == aKey;
michael@0 114
michael@0 115 if (mCanonical != aKey->mCanonical)
michael@0 116 return false;
michael@0 117
michael@0 118 return mDomain.Equals(aKey->mDomain);
michael@0 119 }
michael@0 120
michael@0 121 PrefCallback *GetKey() const
michael@0 122 {
michael@0 123 return const_cast<PrefCallback*>(this);
michael@0 124 }
michael@0 125
michael@0 126 // Get a reference to the callback's observer, or null if the observer was
michael@0 127 // weakly referenced and has been destroyed.
michael@0 128 already_AddRefed<nsIObserver> GetObserver() const
michael@0 129 {
michael@0 130 if (!IsWeak()) {
michael@0 131 nsCOMPtr<nsIObserver> copy = mStrongRef;
michael@0 132 return copy.forget();
michael@0 133 }
michael@0 134
michael@0 135 nsCOMPtr<nsIObserver> observer = do_QueryReferent(mWeakRef);
michael@0 136 return observer.forget();
michael@0 137 }
michael@0 138
michael@0 139 const nsCString& GetDomain() const
michael@0 140 {
michael@0 141 return mDomain;
michael@0 142 }
michael@0 143
michael@0 144 nsPrefBranch* GetPrefBranch() const
michael@0 145 {
michael@0 146 return mBranch;
michael@0 147 }
michael@0 148
michael@0 149 // Has this callback's weak reference died?
michael@0 150 bool IsExpired() const
michael@0 151 {
michael@0 152 if (!IsWeak())
michael@0 153 return false;
michael@0 154
michael@0 155 nsCOMPtr<nsIObserver> observer(do_QueryReferent(mWeakRef));
michael@0 156 return !observer;
michael@0 157 }
michael@0 158
michael@0 159 enum { ALLOW_MEMMOVE = true };
michael@0 160
michael@0 161 private:
michael@0 162 nsCString mDomain;
michael@0 163 nsPrefBranch *mBranch;
michael@0 164
michael@0 165 // Exactly one of mWeakRef and mStrongRef should be non-null.
michael@0 166 nsWeakPtr mWeakRef;
michael@0 167 nsCOMPtr<nsIObserver> mStrongRef;
michael@0 168
michael@0 169 // We need a canonical nsISupports pointer, per bug 578392.
michael@0 170 nsISupports *mCanonical;
michael@0 171
michael@0 172 bool IsWeak() const
michael@0 173 {
michael@0 174 return !!mWeakRef;
michael@0 175 }
michael@0 176 };
michael@0 177
michael@0 178 class nsPrefBranch : public nsIPrefBranchInternal,
michael@0 179 public nsIObserver,
michael@0 180 public nsSupportsWeakReference
michael@0 181 {
michael@0 182 friend class mozilla::PreferenceServiceReporter;
michael@0 183 public:
michael@0 184 NS_DECL_ISUPPORTS
michael@0 185 NS_DECL_NSIPREFBRANCH
michael@0 186 NS_DECL_NSIPREFBRANCH2
michael@0 187 NS_DECL_NSIOBSERVER
michael@0 188
michael@0 189 nsPrefBranch(const char *aPrefRoot, bool aDefaultBranch);
michael@0 190 virtual ~nsPrefBranch();
michael@0 191
michael@0 192 int32_t GetRootLength() { return mPrefRootLength; }
michael@0 193
michael@0 194 nsresult RemoveObserverFromMap(const char *aDomain, nsISupports *aObserver);
michael@0 195
michael@0 196 static void NotifyObserver(const char *newpref, void *data);
michael@0 197
michael@0 198 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
michael@0 199
michael@0 200 protected:
michael@0 201 nsPrefBranch() /* disallow use of this constructer */
michael@0 202 { }
michael@0 203
michael@0 204 nsresult GetDefaultFromPropertiesFile(const char *aPrefName, char16_t **return_buf);
michael@0 205 // As SetCharPref, but without any check on the length of |aValue|
michael@0 206 nsresult SetCharPrefInternal(const char *aPrefName, const char *aValue);
michael@0 207 // Reject strings that are more than 1Mb, warn if strings are more than 16kb
michael@0 208 nsresult CheckSanityOfStringLength(const char* aPrefName, const nsAString& aValue);
michael@0 209 nsresult CheckSanityOfStringLength(const char* aPrefName, const char* aValue);
michael@0 210 nsresult CheckSanityOfStringLength(const char* aPrefName, const uint32_t aLength);
michael@0 211 void RemoveExpiredCallback(PrefCallback *aCallback);
michael@0 212 const char *getPrefName(const char *aPrefName);
michael@0 213 void freeObserverList(void);
michael@0 214
michael@0 215 friend PLDHashOperator
michael@0 216 FreeObserverFunc(PrefCallback *aKey,
michael@0 217 nsAutoPtr<PrefCallback> &aCallback,
michael@0 218 void *aArgs);
michael@0 219
michael@0 220 private:
michael@0 221 int32_t mPrefRootLength;
michael@0 222 nsCString mPrefRoot;
michael@0 223 bool mIsDefault;
michael@0 224
michael@0 225 bool mFreeingObserverList;
michael@0 226 nsClassHashtable<PrefCallback, PrefCallback> mObservers;
michael@0 227 };
michael@0 228
michael@0 229
michael@0 230 class nsPrefLocalizedString : public nsIPrefLocalizedString,
michael@0 231 public nsISupportsString
michael@0 232 {
michael@0 233 public:
michael@0 234 nsPrefLocalizedString();
michael@0 235 virtual ~nsPrefLocalizedString();
michael@0 236
michael@0 237 NS_DECL_ISUPPORTS
michael@0 238 NS_FORWARD_NSISUPPORTSSTRING(mUnicodeString->)
michael@0 239 NS_FORWARD_NSISUPPORTSPRIMITIVE(mUnicodeString->)
michael@0 240
michael@0 241 nsresult Init();
michael@0 242
michael@0 243 private:
michael@0 244 NS_IMETHOD GetData(char16_t**);
michael@0 245 NS_IMETHOD SetData(const char16_t* aData);
michael@0 246 NS_IMETHOD SetDataWithLength(uint32_t aLength, const char16_t *aData);
michael@0 247
michael@0 248 nsCOMPtr<nsISupportsString> mUnicodeString;
michael@0 249 };
michael@0 250
michael@0 251
michael@0 252 class nsRelativeFilePref : public nsIRelativeFilePref
michael@0 253 {
michael@0 254 public:
michael@0 255 NS_DECL_ISUPPORTS
michael@0 256 NS_DECL_NSIRELATIVEFILEPREF
michael@0 257
michael@0 258 nsRelativeFilePref();
michael@0 259 virtual ~nsRelativeFilePref();
michael@0 260
michael@0 261 private:
michael@0 262 nsCOMPtr<nsIFile> mFile;
michael@0 263 nsCString mRelativeToKey;
michael@0 264 };
michael@0 265
michael@0 266 #endif

mercurial