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