michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef nsDOMStorageManager_h__ michael@0: #define nsDOMStorageManager_h__ michael@0: michael@0: #include "nsIDOMStorageManager.h" michael@0: #include "DOMStorageObserver.h" michael@0: michael@0: #include "nsPIDOMStorage.h" michael@0: #include "DOMStorageCache.h" michael@0: michael@0: #include "nsTHashtable.h" michael@0: #include "nsDataHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: const nsPIDOMStorage::StorageType SessionStorage = nsPIDOMStorage::SessionStorage; michael@0: const nsPIDOMStorage::StorageType LocalStorage = nsPIDOMStorage::LocalStorage; michael@0: michael@0: class DOMStorage; michael@0: michael@0: class DOMStorageManager : public nsIDOMStorageManager michael@0: , public DOMStorageObserverSink michael@0: { michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIDOMSTORAGEMANAGER michael@0: michael@0: public: michael@0: virtual nsPIDOMStorage::StorageType Type() { return mType; } michael@0: michael@0: // Reads the preference for DOM storage quota michael@0: static uint32_t GetQuota(); michael@0: // Gets (but not ensures) cache for the given scope michael@0: DOMStorageCache* GetCache(const nsACString& aScope) const; michael@0: // Returns object keeping usage cache for the scope. michael@0: already_AddRefed GetScopeUsage(const nsACString& aScope); michael@0: michael@0: protected: michael@0: DOMStorageManager(nsPIDOMStorage::StorageType aType); michael@0: virtual ~DOMStorageManager(); michael@0: michael@0: private: michael@0: // DOMStorageObserverSink, handler to various chrome clearing notification michael@0: virtual nsresult Observe(const char* aTopic, const nsACString& aScopePrefix); michael@0: michael@0: // Since nsTHashtable doesn't like multiple inheritance, we have to aggregate michael@0: // DOMStorageCache into the entry. michael@0: class DOMStorageCacheHashKey : public nsCStringHashKey michael@0: { michael@0: public: michael@0: DOMStorageCacheHashKey(const nsACString* aKey) michael@0: : nsCStringHashKey(aKey) michael@0: , mCache(new DOMStorageCache(aKey)) michael@0: {} michael@0: michael@0: DOMStorageCacheHashKey(const DOMStorageCacheHashKey& aOther) michael@0: : nsCStringHashKey(aOther) michael@0: { michael@0: NS_ERROR("Shouldn't be called"); michael@0: } michael@0: michael@0: DOMStorageCache* cache() { return mCache; } michael@0: // Keep the cache referenced forever, used for sessionStorage. michael@0: void HardRef() { mCacheRef = mCache; } michael@0: michael@0: private: michael@0: // weak ref only since cache references its manager. michael@0: DOMStorageCache* mCache; michael@0: // hard ref when this is sessionStorage to keep it alive forever. michael@0: nsRefPtr mCacheRef; michael@0: }; michael@0: michael@0: // Ensures cache for a scope, when it doesn't exist it is created and initalized, michael@0: // this also starts preload of persistent data. michael@0: already_AddRefed PutCache(const nsACString& aScope, michael@0: nsIURI* aFirstPartyIsolationURI, michael@0: nsIPrincipal* aPrincipal); michael@0: michael@0: // Helper for creation of DOM storage objects michael@0: nsresult GetStorageInternal(bool aCreate, michael@0: nsIURI* aFirstPartyIsolationURI, michael@0: nsIPrincipal* aPrincipal, michael@0: const nsAString& aDocumentURI, michael@0: bool aPrivate, michael@0: nsIDOMStorage** aRetval); michael@0: michael@0: // Scope->cache map michael@0: nsTHashtable mCaches; michael@0: const nsPIDOMStorage::StorageType mType; michael@0: michael@0: // If mLowDiskSpace is true it indicates a low device storage situation and michael@0: // so no localStorage writes are allowed. sessionStorage writes are still michael@0: // allowed. michael@0: bool mLowDiskSpace; michael@0: bool IsLowDiskSpace() const { return mLowDiskSpace; }; michael@0: michael@0: static PLDHashOperator ClearCacheEnumerator(DOMStorageCacheHashKey* aCache, michael@0: void* aClosure); michael@0: michael@0: protected: michael@0: // Keeps usage cache objects for eTLD+1 scopes we have touched. michael@0: nsDataHashtable > mUsages; michael@0: michael@0: friend class DOMStorageCache; michael@0: // Releases cache since it is no longer referrered by any DOMStorage object. michael@0: virtual void DropCache(DOMStorageCache* aCache); michael@0: }; michael@0: michael@0: // Derived classes to allow two different contract ids, one for localStorage and michael@0: // one for sessionStorage management. localStorage manager is used as service michael@0: // scoped to the application while sessionStorage managers are instantiated by each michael@0: // top doc shell in the application since sessionStorages are isolated per top level michael@0: // browsing context. The code may easily by shared by both. michael@0: michael@0: class DOMLocalStorageManager MOZ_FINAL : public DOMStorageManager michael@0: { michael@0: public: michael@0: DOMLocalStorageManager(); michael@0: virtual ~DOMLocalStorageManager(); michael@0: michael@0: // Global getter of localStorage manager service michael@0: static DOMLocalStorageManager* Self() { return sSelf; } michael@0: michael@0: private: michael@0: static DOMLocalStorageManager* sSelf; michael@0: }; michael@0: michael@0: class DOMSessionStorageManager MOZ_FINAL : public DOMStorageManager michael@0: { michael@0: public: michael@0: DOMSessionStorageManager(); michael@0: }; michael@0: michael@0: } // ::dom michael@0: } // ::mozilla michael@0: michael@0: #endif /* nsDOMStorageManager_h__ */