/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef DOM_QUOTA_PERSISTENCESCOPE_H_ #define DOM_QUOTA_PERSISTENCESCOPE_H_ #include "mozilla/Assertions.h" #include "mozilla/EnumSet.h" #include "mozilla/Variant.h" #include "mozilla/dom/quota/PersistenceType.h" namespace mozilla::dom::quota { class PersistenceScope { class Value { PersistenceType mValue; public: explicit Value(PersistenceType aValue) : mValue(aValue) {} PersistenceType GetValue() const { return mValue; } }; class Set { EnumSet mSet; public: explicit Set(const EnumSet& aSet) : mSet(aSet) {} const EnumSet& GetSet() const { return mSet; } }; struct Null {}; using DataType = Variant; DataType mData; public: PersistenceScope() : mData(Null()) {} // XXX Consider renaming these static methods to Create static PersistenceScope CreateFromValue(PersistenceType aValue) { return PersistenceScope(std::move(Value(aValue))); } template static PersistenceScope CreateFromSet(Args... aArgs) { return PersistenceScope(std::move(Set(EnumSet(aArgs...)))); } static PersistenceScope CreateFromNull() { return PersistenceScope(std::move(Null())); } bool IsValue() const { return mData.is(); } bool IsSet() const { return mData.is(); } bool IsNull() const { return mData.is(); } void SetFromValue(PersistenceType aValue) { mData = AsVariant(Value(aValue)); } void SetFromNull() { mData = AsVariant(Null()); } PersistenceType GetValue() const { MOZ_ASSERT(IsValue()); return mData.as().GetValue(); } const EnumSet& GetSet() const { MOZ_ASSERT(IsSet()); return mData.as().GetSet(); } bool Matches(const PersistenceScope& aOther) const { struct Matcher { const PersistenceScope& mThis; explicit Matcher(const PersistenceScope& aThis) : mThis(aThis) {} bool operator()(const Value& aOther) { return mThis.MatchesValue(aOther); } bool operator()(const Set& aOther) { return mThis.MatchesSet(aOther); } bool operator()(const Null& aOther) { return true; } }; return aOther.mData.match(Matcher(*this)); } private: // Move constructors explicit PersistenceScope(const Value&& aValue) : mData(aValue) {} explicit PersistenceScope(const Set&& aSet) : mData(aSet) {} explicit PersistenceScope(const Null&& aNull) : mData(aNull) {} // Copy constructor explicit PersistenceScope(const DataType& aOther) : mData(aOther) {} bool MatchesValue(const Value& aOther) const { struct ValueMatcher { const Value& mOther; explicit ValueMatcher(const Value& aOther) : mOther(aOther) {} bool operator()(const Value& aThis) { return aThis.GetValue() == mOther.GetValue(); } bool operator()(const Set& aThis) { return aThis.GetSet().contains(mOther.GetValue()); } bool operator()(const Null& aThis) { // Null covers everything. return true; } }; return mData.match(ValueMatcher(aOther)); } bool MatchesSet(const Set& aOther) const { struct SetMatcher { const Set& mOther; explicit SetMatcher(const Set& aOther) : mOther(aOther) {} bool operator()(const Value& aThis) { return mOther.GetSet().contains(aThis.GetValue()); } bool operator()(const Set& aThis) { for (auto persistenceType : aThis.GetSet()) { if (mOther.GetSet().contains(persistenceType)) { return true; } } return false; } bool operator()(const Null& aThis) { // Null covers everything. return true; } }; return mData.match(SetMatcher(aOther)); } bool operator==(const PersistenceScope& aOther) = delete; }; bool MatchesPersistentPersistenceScope( const PersistenceScope& aPersistenceScope); bool MatchesBestEffortPersistenceScope( const PersistenceScope& aPersistenceScope); } // namespace mozilla::dom::quota #endif // DOM_QUOTA_PERSISTENCESCOPE_H_