Bug 1874684 - Part 6: Limit day length calculations to safe integers. r=mgaudet
[gecko.git] / dom / quota / Client.cpp
blob87da8815cc84657482c8b6bb35267364182d442c
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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "Client.h"
9 // Global includes
10 #include "mozilla/ipc/BackgroundParent.h"
11 #include "mozilla/Assertions.h"
12 #include "mozilla/dom/quota/QuotaManager.h"
14 namespace mozilla::dom::quota {
16 using mozilla::ipc::AssertIsOnBackgroundThread;
17 using mozilla::ipc::IsOnBackgroundThread;
19 namespace {
21 const char kIDBPrefix = 'I';
22 const char kDOMCachePrefix = 'C';
23 const char kSDBPrefix = 'S';
24 const char kFILESYSTEMPrefix = 'F';
25 const char kLSPrefix = 'L';
27 template <Client::Type type>
28 struct ClientTypeTraits;
30 template <>
31 struct ClientTypeTraits<Client::Type::IDB> {
32 template <typename T>
33 static void To(T& aData) {
34 aData.AssignLiteral(IDB_DIRECTORY_NAME);
37 static void To(char& aData) { aData = kIDBPrefix; }
39 template <typename T>
40 static bool From(const T& aData) {
41 return aData.EqualsLiteral(IDB_DIRECTORY_NAME);
44 static bool From(char aData) { return aData == kIDBPrefix; }
47 template <>
48 struct ClientTypeTraits<Client::Type::DOMCACHE> {
49 template <typename T>
50 static void To(T& aData) {
51 aData.AssignLiteral(DOMCACHE_DIRECTORY_NAME);
54 static void To(char& aData) { aData = kDOMCachePrefix; }
56 template <typename T>
57 static bool From(const T& aData) {
58 return aData.EqualsLiteral(DOMCACHE_DIRECTORY_NAME);
61 static bool From(char aData) { return aData == kDOMCachePrefix; }
64 template <>
65 struct ClientTypeTraits<Client::Type::SDB> {
66 template <typename T>
67 static void To(T& aData) {
68 aData.AssignLiteral(SDB_DIRECTORY_NAME);
71 static void To(char& aData) { aData = kSDBPrefix; }
73 template <typename T>
74 static bool From(const T& aData) {
75 return aData.EqualsLiteral(SDB_DIRECTORY_NAME);
78 static bool From(char aData) { return aData == kSDBPrefix; }
81 template <>
82 struct ClientTypeTraits<Client::Type::FILESYSTEM> {
83 template <typename T>
84 static void To(T& aData) {
85 aData.AssignLiteral(FILESYSTEM_DIRECTORY_NAME);
88 static void To(char& aData) { aData = kFILESYSTEMPrefix; }
90 template <typename T>
91 static bool From(const T& aData) {
92 return aData.EqualsLiteral(FILESYSTEM_DIRECTORY_NAME);
95 static bool From(char aData) { return aData == kFILESYSTEMPrefix; }
98 template <>
99 struct ClientTypeTraits<Client::Type::LS> {
100 template <typename T>
101 static void To(T& aData) {
102 aData.AssignLiteral(LS_DIRECTORY_NAME);
105 static void To(char& aData) { aData = kLSPrefix; }
107 template <typename T>
108 static bool From(const T& aData) {
109 return aData.EqualsLiteral(LS_DIRECTORY_NAME);
112 static bool From(char aData) { return aData == kLSPrefix; }
115 template <typename T>
116 bool TypeTo_impl(Client::Type aType, T& aData) {
117 switch (aType) {
118 case Client::IDB:
119 ClientTypeTraits<Client::Type::IDB>::To(aData);
120 return true;
122 case Client::DOMCACHE:
123 ClientTypeTraits<Client::Type::DOMCACHE>::To(aData);
124 return true;
126 case Client::SDB:
127 ClientTypeTraits<Client::Type::SDB>::To(aData);
128 return true;
130 case Client::FILESYSTEM:
131 ClientTypeTraits<Client::Type::FILESYSTEM>::To(aData);
132 return true;
134 case Client::LS:
135 if (CachedNextGenLocalStorageEnabled()) {
136 ClientTypeTraits<Client::Type::LS>::To(aData);
137 return true;
139 [[fallthrough]];
141 case Client::TYPE_MAX:
142 default:
143 return false;
146 MOZ_CRASH("Should never get here!");
149 template <typename T>
150 bool TypeFrom_impl(const T& aData, Client::Type& aType) {
151 if (ClientTypeTraits<Client::Type::IDB>::From(aData)) {
152 aType = Client::IDB;
153 return true;
156 if (ClientTypeTraits<Client::Type::DOMCACHE>::From(aData)) {
157 aType = Client::DOMCACHE;
158 return true;
161 if (ClientTypeTraits<Client::Type::SDB>::From(aData)) {
162 aType = Client::SDB;
163 return true;
166 if (ClientTypeTraits<Client::Type::FILESYSTEM>::From(aData)) {
167 aType = Client::FILESYSTEM;
168 return true;
171 if (CachedNextGenLocalStorageEnabled() &&
172 ClientTypeTraits<Client::Type::LS>::From(aData)) {
173 aType = Client::LS;
174 return true;
177 return false;
180 void BadType() { MOZ_CRASH("Bad client type value!"); }
182 } // namespace
184 // static
185 bool Client::IsValidType(Type aType) {
186 switch (aType) {
187 case Client::IDB:
188 case Client::DOMCACHE:
189 case Client::SDB:
190 case Client::FILESYSTEM:
191 return true;
193 case Client::LS:
194 if (CachedNextGenLocalStorageEnabled()) {
195 return true;
197 [[fallthrough]];
199 default:
200 return false;
204 // static
205 bool Client::TypeToText(Type aType, nsAString& aText, const fallible_t&) {
206 nsString text;
207 if (!TypeTo_impl(aType, text)) {
208 return false;
210 aText = text;
211 return true;
214 // static
215 nsAutoString Client::TypeToString(Type aType) {
216 nsAutoString res;
217 if (!TypeTo_impl(aType, res)) {
218 BadType();
220 return res;
223 // static
224 nsAutoCString Client::TypeToText(Type aType) {
225 nsAutoCString res;
226 if (!TypeTo_impl(aType, res)) {
227 BadType();
229 return res;
232 // static
233 bool Client::TypeFromText(const nsAString& aText, Type& aType,
234 const fallible_t&) {
235 Type type;
236 if (!TypeFrom_impl(aText, type)) {
237 return false;
239 aType = type;
240 return true;
243 // static
244 Client::Type Client::TypeFromText(const nsACString& aText) {
245 Type type;
246 if (!TypeFrom_impl(aText, type)) {
247 BadType();
249 return type;
252 // static
253 char Client::TypeToPrefix(Type aType) {
254 char prefix;
255 if (!TypeTo_impl(aType, prefix)) {
256 BadType();
258 return prefix;
261 // static
262 bool Client::TypeFromPrefix(char aPrefix, Type& aType, const fallible_t&) {
263 Type type;
264 if (!TypeFrom_impl(aPrefix, type)) {
265 return false;
267 aType = type;
268 return true;
271 bool Client::InitiateShutdownWorkThreads() {
272 AssertIsOnBackgroundThread();
274 QuotaManager::MaybeRecordQuotaClientShutdownStep(GetType(), "starting"_ns);
276 InitiateShutdown();
278 return IsShutdownCompleted();
281 void Client::FinalizeShutdownWorkThreads() {
282 QuotaManager::MaybeRecordQuotaClientShutdownStep(GetType(), "completed"_ns);
284 FinalizeShutdown();
287 // static
288 bool Client::IsShuttingDownOnBackgroundThread() {
289 MOZ_ASSERT(IsOnBackgroundThread());
290 return QuotaManager::IsShuttingDown();
293 // static
294 bool Client::IsShuttingDownOnNonBackgroundThread() {
295 MOZ_ASSERT(!IsOnBackgroundThread());
296 return QuotaManager::IsShuttingDown();
299 } // namespace mozilla::dom::quota