modules/libpref/src/nsPrefBranch.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/modules/libpref/src/nsPrefBranch.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,266 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef nsPrefBranch_h
    1.10 +#define nsPrefBranch_h
    1.11 +
    1.12 +#include "nsCOMPtr.h"
    1.13 +#include "nsIObserver.h"
    1.14 +#include "nsIPrefBranch.h"
    1.15 +#include "nsIPrefBranchInternal.h"
    1.16 +#include "nsIPrefLocalizedString.h"
    1.17 +#include "nsXPCOM.h"
    1.18 +#include "nsISupportsPrimitives.h"
    1.19 +#include "nsIRelativeFilePref.h"
    1.20 +#include "nsIFile.h"
    1.21 +#include "nsString.h"
    1.22 +#include "nsTArray.h"
    1.23 +#include "nsWeakReference.h"
    1.24 +#include "nsClassHashtable.h"
    1.25 +#include "nsCRT.h"
    1.26 +#include "nsISupportsImpl.h"
    1.27 +#include "mozilla/HashFunctions.h"
    1.28 +#include "mozilla/MemoryReporting.h"
    1.29 +
    1.30 +namespace mozilla {
    1.31 +class PreferenceServiceReporter;
    1.32 +} // namespace mozilla;
    1.33 +
    1.34 +class nsPrefBranch;
    1.35 +
    1.36 +class PrefCallback : public PLDHashEntryHdr {
    1.37 +  friend class mozilla::PreferenceServiceReporter;
    1.38 +
    1.39 +  public:
    1.40 +    typedef PrefCallback* KeyType;
    1.41 +    typedef const PrefCallback* KeyTypePointer;
    1.42 +
    1.43 +    static const PrefCallback* KeyToPointer(PrefCallback *aKey)
    1.44 +    {
    1.45 +      return aKey;
    1.46 +    }
    1.47 +
    1.48 +    static PLDHashNumber HashKey(const PrefCallback *aKey)
    1.49 +    {
    1.50 +      uint32_t hash = mozilla::HashString(aKey->mDomain);
    1.51 +      return mozilla::AddToHash(hash, aKey->mCanonical);
    1.52 +    }
    1.53 +
    1.54 +
    1.55 +  public:
    1.56 +    // Create a PrefCallback with a strong reference to its observer.
    1.57 +    PrefCallback(const char *aDomain, nsIObserver *aObserver,
    1.58 +                 nsPrefBranch *aBranch)
    1.59 +      : mDomain(aDomain),
    1.60 +        mBranch(aBranch),
    1.61 +        mWeakRef(nullptr),
    1.62 +        mStrongRef(aObserver)
    1.63 +    {
    1.64 +      MOZ_COUNT_CTOR(PrefCallback);
    1.65 +      nsCOMPtr<nsISupports> canonical = do_QueryInterface(aObserver);
    1.66 +      mCanonical = canonical;
    1.67 +    }
    1.68 +
    1.69 +    // Create a PrefCallback with a weak reference to its observer.
    1.70 +    PrefCallback(const char *aDomain,
    1.71 +                 nsISupportsWeakReference *aObserver,
    1.72 +                 nsPrefBranch *aBranch)
    1.73 +      : mDomain(aDomain),
    1.74 +        mBranch(aBranch),
    1.75 +        mWeakRef(do_GetWeakReference(aObserver)),
    1.76 +        mStrongRef(nullptr)
    1.77 +    {
    1.78 +      MOZ_COUNT_CTOR(PrefCallback);
    1.79 +      nsCOMPtr<nsISupports> canonical = do_QueryInterface(aObserver);
    1.80 +      mCanonical = canonical;
    1.81 +    }
    1.82 +
    1.83 +    // Copy constructor needs to be explicit or the linker complains.
    1.84 +    PrefCallback(const PrefCallback *&aCopy)
    1.85 +      : mDomain(aCopy->mDomain),
    1.86 +        mBranch(aCopy->mBranch),
    1.87 +        mWeakRef(aCopy->mWeakRef),
    1.88 +        mStrongRef(aCopy->mStrongRef),
    1.89 +        mCanonical(aCopy->mCanonical)
    1.90 +    {
    1.91 +      MOZ_COUNT_CTOR(PrefCallback);
    1.92 +    }
    1.93 +
    1.94 +    ~PrefCallback()
    1.95 +    {
    1.96 +      MOZ_COUNT_DTOR(PrefCallback);
    1.97 +    }
    1.98 +
    1.99 +    bool KeyEquals(const PrefCallback *aKey) const
   1.100 +    {
   1.101 +      // We want to be able to look up a weakly-referencing PrefCallback after
   1.102 +      // its observer has died so we can remove it from the table.  Once the
   1.103 +      // callback's observer dies, its canonical pointer is stale -- in
   1.104 +      // particular, we may have allocated a new observer in the same spot in
   1.105 +      // memory!  So we can't just compare canonical pointers to determine
   1.106 +      // whether aKey refers to the same observer as this.
   1.107 +      //
   1.108 +      // Our workaround is based on the way we use this hashtable: When we ask
   1.109 +      // the hashtable to remove a PrefCallback whose weak reference has
   1.110 +      // expired, we use as the key for removal the same object as was inserted
   1.111 +      // into the hashtable.  Thus we can say that if one of the keys' weak
   1.112 +      // references has expired, the two keys are equal iff they're the same
   1.113 +      // object.
   1.114 +
   1.115 +      if (IsExpired() || aKey->IsExpired())
   1.116 +        return this == aKey;
   1.117 +
   1.118 +      if (mCanonical != aKey->mCanonical)
   1.119 +        return false;
   1.120 +
   1.121 +      return mDomain.Equals(aKey->mDomain);
   1.122 +    }
   1.123 +
   1.124 +    PrefCallback *GetKey() const
   1.125 +    {
   1.126 +      return const_cast<PrefCallback*>(this);
   1.127 +    }
   1.128 +
   1.129 +    // Get a reference to the callback's observer, or null if the observer was
   1.130 +    // weakly referenced and has been destroyed.
   1.131 +    already_AddRefed<nsIObserver> GetObserver() const
   1.132 +    {
   1.133 +      if (!IsWeak()) {
   1.134 +        nsCOMPtr<nsIObserver> copy = mStrongRef;
   1.135 +        return copy.forget();
   1.136 +      }
   1.137 +
   1.138 +      nsCOMPtr<nsIObserver> observer = do_QueryReferent(mWeakRef);
   1.139 +      return observer.forget();
   1.140 +    }
   1.141 +
   1.142 +    const nsCString& GetDomain() const
   1.143 +    {
   1.144 +      return mDomain;
   1.145 +    }
   1.146 +
   1.147 +    nsPrefBranch* GetPrefBranch() const
   1.148 +    {
   1.149 +      return mBranch;
   1.150 +    }
   1.151 +
   1.152 +    // Has this callback's weak reference died?
   1.153 +    bool IsExpired() const
   1.154 +    {
   1.155 +      if (!IsWeak())
   1.156 +        return false;
   1.157 +
   1.158 +      nsCOMPtr<nsIObserver> observer(do_QueryReferent(mWeakRef));
   1.159 +      return !observer;
   1.160 +    }
   1.161 +
   1.162 +    enum { ALLOW_MEMMOVE = true };
   1.163 +
   1.164 +  private:
   1.165 +    nsCString             mDomain;
   1.166 +    nsPrefBranch         *mBranch;
   1.167 +
   1.168 +    // Exactly one of mWeakRef and mStrongRef should be non-null.
   1.169 +    nsWeakPtr             mWeakRef;
   1.170 +    nsCOMPtr<nsIObserver> mStrongRef;
   1.171 +
   1.172 +    // We need a canonical nsISupports pointer, per bug 578392.
   1.173 +    nsISupports          *mCanonical;
   1.174 +
   1.175 +    bool IsWeak() const
   1.176 +    {
   1.177 +      return !!mWeakRef;
   1.178 +    }
   1.179 +};
   1.180 +
   1.181 +class nsPrefBranch : public nsIPrefBranchInternal,
   1.182 +                     public nsIObserver,
   1.183 +                     public nsSupportsWeakReference
   1.184 +{
   1.185 +  friend class mozilla::PreferenceServiceReporter;
   1.186 +public:
   1.187 +  NS_DECL_ISUPPORTS
   1.188 +  NS_DECL_NSIPREFBRANCH
   1.189 +  NS_DECL_NSIPREFBRANCH2
   1.190 +  NS_DECL_NSIOBSERVER
   1.191 +
   1.192 +  nsPrefBranch(const char *aPrefRoot, bool aDefaultBranch);
   1.193 +  virtual ~nsPrefBranch();
   1.194 +
   1.195 +  int32_t GetRootLength() { return mPrefRootLength; }
   1.196 +
   1.197 +  nsresult RemoveObserverFromMap(const char *aDomain, nsISupports *aObserver);
   1.198 +
   1.199 +  static void NotifyObserver(const char *newpref, void *data);
   1.200 +
   1.201 +  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
   1.202 +
   1.203 +protected:
   1.204 +  nsPrefBranch()    /* disallow use of this constructer */
   1.205 +    { }
   1.206 +
   1.207 +  nsresult   GetDefaultFromPropertiesFile(const char *aPrefName, char16_t **return_buf);
   1.208 +  // As SetCharPref, but without any check on the length of |aValue|
   1.209 +  nsresult   SetCharPrefInternal(const char *aPrefName, const char *aValue);
   1.210 +  // Reject strings that are more than 1Mb, warn if strings are more than 16kb
   1.211 +  nsresult   CheckSanityOfStringLength(const char* aPrefName, const nsAString& aValue);
   1.212 +  nsresult   CheckSanityOfStringLength(const char* aPrefName, const char* aValue);
   1.213 +  nsresult   CheckSanityOfStringLength(const char* aPrefName, const uint32_t aLength);
   1.214 +  void RemoveExpiredCallback(PrefCallback *aCallback);
   1.215 +  const char *getPrefName(const char *aPrefName);
   1.216 +  void       freeObserverList(void);
   1.217 +
   1.218 +  friend PLDHashOperator
   1.219 +    FreeObserverFunc(PrefCallback *aKey,
   1.220 +                     nsAutoPtr<PrefCallback> &aCallback,
   1.221 +                     void *aArgs);
   1.222 +
   1.223 +private:
   1.224 +  int32_t               mPrefRootLength;
   1.225 +  nsCString             mPrefRoot;
   1.226 +  bool                  mIsDefault;
   1.227 +
   1.228 +  bool                  mFreeingObserverList;
   1.229 +  nsClassHashtable<PrefCallback, PrefCallback> mObservers;
   1.230 +};
   1.231 +
   1.232 +
   1.233 +class nsPrefLocalizedString : public nsIPrefLocalizedString,
   1.234 +                              public nsISupportsString
   1.235 +{
   1.236 +public:
   1.237 +  nsPrefLocalizedString();
   1.238 +  virtual ~nsPrefLocalizedString();
   1.239 +
   1.240 +  NS_DECL_ISUPPORTS
   1.241 +  NS_FORWARD_NSISUPPORTSSTRING(mUnicodeString->)
   1.242 +  NS_FORWARD_NSISUPPORTSPRIMITIVE(mUnicodeString->)
   1.243 +
   1.244 +  nsresult Init();
   1.245 +
   1.246 +private:
   1.247 +  NS_IMETHOD GetData(char16_t**);
   1.248 +  NS_IMETHOD SetData(const char16_t* aData);
   1.249 +  NS_IMETHOD SetDataWithLength(uint32_t aLength, const char16_t *aData);
   1.250 +
   1.251 +  nsCOMPtr<nsISupportsString> mUnicodeString;
   1.252 +};
   1.253 +
   1.254 +
   1.255 +class nsRelativeFilePref : public nsIRelativeFilePref
   1.256 +{
   1.257 +public:
   1.258 +  NS_DECL_ISUPPORTS
   1.259 +  NS_DECL_NSIRELATIVEFILEPREF
   1.260 +  
   1.261 +                nsRelativeFilePref();
   1.262 +  virtual       ~nsRelativeFilePref();
   1.263 +  
   1.264 +private:
   1.265 +  nsCOMPtr<nsIFile> mFile;
   1.266 +  nsCString mRelativeToKey;
   1.267 +};
   1.268 +
   1.269 +#endif

mercurial