1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/* -*- 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_CLIENTSTORAGESCOPE_H_
#define DOM_QUOTA_CLIENTSTORAGESCOPE_H_
#include "mozilla/Assertions.h"
#include "mozilla/Variant.h"
#include "mozilla/dom/quota/Client.h"
namespace mozilla::dom::quota {
/**
* Represents a scope within an origin directory, currently covering either a
* specific client (`Client`), metadata (`Metadata`), or a match-all scope
* (`Null`).
*
* The use of "Storage" in the class name is intentional. Unlike
* `PersistenceScope` and `OriginScope`, which match only specific directories,
* this scope is meant to cover all entries within an origin directory. That
* includes client specific folders (e.g., idb/, fs/) and, in the future, files
* like metadata that exist alongside them.
*
* The special `Metadata` scope exists because adding the metadata type to
* client types would complicate other aspects of the system. A special client
* implementation just for working with the metadata file would be overkill.
* However, we need a way to lock just the metadata file. Since metadata files
* reside alongside client directories under the same origin directory, it
* makes sense to include them in the `ClientStorageScope`.
*
* This class provides operations to check the current scope type
* (`Client`, `Metadata`, or `Null`), set the scope type, retrieve a client
* type, and match it with another scope.
*/
class ClientStorageScope {
class Client {
quota::Client::Type mClientType;
public:
explicit Client(quota::Client::Type aClientType)
: mClientType(aClientType) {}
quota::Client::Type GetClientType() const { return mClientType; }
};
struct Metadata {};
struct Null {};
using DataType = Variant<Client, Metadata, Null>;
DataType mData;
public:
ClientStorageScope() : mData(Null()) {}
static ClientStorageScope CreateFromClient(quota::Client::Type aClientType) {
return ClientStorageScope(std::move(Client(aClientType)));
}
static ClientStorageScope CreateFromMetadata() {
return ClientStorageScope(std::move(Metadata()));
}
static ClientStorageScope CreateFromNull() {
return ClientStorageScope(std::move(Null()));
}
bool IsClient() const { return mData.is<Client>(); }
bool IsMetadata() const { return mData.is<Metadata>(); }
bool IsNull() const { return mData.is<Null>(); }
void SetFromClient(quota::Client::Type aClientType) {
mData = AsVariant(Client(aClientType));
}
void SetFromNull() { mData = AsVariant(Null()); }
quota::Client::Type GetClientType() const {
MOZ_ASSERT(IsClient());
return mData.as<Client>().GetClientType();
}
bool Matches(const ClientStorageScope& aOther) const {
struct Matcher {
const ClientStorageScope& mThis;
explicit Matcher(const ClientStorageScope& aThis) : mThis(aThis) {}
bool operator()(const Client& aOther) {
return mThis.MatchesClient(aOther);
}
bool operator()(const Metadata& aOther) {
return mThis.MatchesMetadata(aOther);
}
bool operator()(const Null& aOther) { return true; }
};
return aOther.mData.match(Matcher(*this));
}
private:
// Move constructors
explicit ClientStorageScope(const Client&& aClient) : mData(aClient) {}
explicit ClientStorageScope(const Metadata&& aMetadata) : mData(aMetadata) {}
explicit ClientStorageScope(const Null&& aNull) : mData(aNull) {}
// Copy constructor
explicit ClientStorageScope(const DataType& aOther) : mData(aOther) {}
bool MatchesClient(const Client& aOther) const {
struct ClientMatcher {
const Client& mOther;
explicit ClientMatcher(const Client& aOther) : mOther(aOther) {}
bool operator()(const Client& aThis) {
return aThis.GetClientType() == mOther.GetClientType();
}
bool operator()(const Metadata& aThis) { return false; }
bool operator()(const Null& aThis) {
// Null covers everything.
return true;
}
};
return mData.match(ClientMatcher(aOther));
}
bool MatchesMetadata(const Metadata& aOther) const {
struct MetadataMatcher {
const Metadata& mOther;
explicit MetadataMatcher(const Metadata& aOther) : mOther(aOther) {}
bool operator()(const Client& aThis) { return false; }
bool operator()(const Metadata& aThis) { return true; }
bool operator()(const Null& aThis) {
// Null covers everything.
return true;
}
};
return mData.match(MetadataMatcher(aOther));
}
bool operator==(const ClientStorageScope& aOther) = delete;
};
} // namespace mozilla::dom::quota
#endif // DOM_QUOTA_CLIENTSTORAGESCOPE_H_
|