Source code

Revision control

Copy as Markdown

Other Tools

/* -*- 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<PersistenceType> mSet;
public:
explicit Set(const EnumSet<PersistenceType>& aSet) : mSet(aSet) {}
const EnumSet<PersistenceType>& GetSet() const { return mSet; }
};
struct Null {};
using DataType = Variant<Value, Set, Null>;
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 <typename... Args>
static PersistenceScope CreateFromSet(Args... aArgs) {
return PersistenceScope(std::move(Set(EnumSet<PersistenceType>(aArgs...))));
}
static PersistenceScope CreateFromNull() {
return PersistenceScope(std::move(Null()));
}
bool IsValue() const { return mData.is<Value>(); }
bool IsSet() const { return mData.is<Set>(); }
bool IsNull() const { return mData.is<Null>(); }
void SetFromValue(PersistenceType aValue) {
mData = AsVariant(Value(aValue));
}
void SetFromNull() { mData = AsVariant(Null()); }
PersistenceType GetValue() const {
MOZ_ASSERT(IsValue());
return mData.as<Value>().GetValue();
}
const EnumSet<PersistenceType>& GetSet() const {
MOZ_ASSERT(IsSet());
return mData.as<Set>().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_