File: ClientStorageScope.h

package info (click to toggle)
firefox 143.0.3-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,617,328 kB
  • sloc: cpp: 7,478,492; javascript: 6,417,157; ansic: 3,720,058; python: 1,396,372; xml: 627,523; asm: 438,677; java: 186,156; sh: 63,477; makefile: 19,171; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,405; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (166 lines) | stat: -rw-r--r-- 4,966 bytes parent folder | download | duplicates (12)
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_