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/. */
6 
7 #include "PersistenceType.h"
8 
9 #include <utility>
10 #include "nsIFile.h"
11 #include "nsLiteralString.h"
12 #include "nsString.h"
13 
14 namespace mozilla::dom::quota {
15 
16 namespace {
17 
18 constexpr auto kPersistentCString = "persistent"_ns;
19 constexpr auto kTemporaryCString = "temporary"_ns;
20 constexpr auto kDefaultCString = "default"_ns;
21 
22 constexpr auto kPermanentString = u"permanent"_ns;
23 constexpr auto kTemporaryString = u"temporary"_ns;
24 constexpr auto kDefaultString = u"default"_ns;
25 
26 static_assert(PERSISTENCE_TYPE_PERSISTENT == 0 &&
27                   PERSISTENCE_TYPE_TEMPORARY == 1 &&
28                   PERSISTENCE_TYPE_DEFAULT == 2 &&
29                   PERSISTENCE_TYPE_INVALID == 3,
30               "Incorrect enum values!");
31 
32 template <PersistenceType type>
33 struct PersistenceTypeTraits;
34 
35 template <>
36 struct PersistenceTypeTraits<PERSISTENCE_TYPE_PERSISTENT> {
37   template <typename T>
38   static T To();
39 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits40   static bool From(const nsACString& aString) {
41     return aString == kPersistentCString;
42   }
43 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits44   static bool From(const StorageType aStorageType) {
45     return aStorageType == StorageType::Persistent;
46   }
47 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits48   static bool From(const int32_t aInt32) { return aInt32 == 0; }
49 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits50   static bool From(nsIFile& aFile) {
51     nsAutoString leafName;
52     MOZ_ALWAYS_SUCCEEDS(aFile.GetLeafName(leafName));
53     return leafName == kPermanentString;
54   }
55 };
56 
57 template <>
58 nsLiteralCString
To()59 PersistenceTypeTraits<PERSISTENCE_TYPE_PERSISTENT>::To<nsLiteralCString>() {
60   return kPersistentCString;
61 }
62 
63 template <>
64 StorageType
To()65 PersistenceTypeTraits<PERSISTENCE_TYPE_PERSISTENT>::To<StorageType>() {
66   return StorageType::Persistent;
67 }
68 
69 template <>
70 struct PersistenceTypeTraits<PERSISTENCE_TYPE_TEMPORARY> {
71   template <typename T>
72   static T To();
73 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits74   static bool From(const nsACString& aString) {
75     return aString == kTemporaryCString;
76   }
77 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits78   static bool From(const StorageType aStorageType) {
79     return aStorageType == StorageType::Temporary;
80   }
81 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits82   static bool From(const int32_t aInt32) { return aInt32 == 1; }
83 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits84   static bool From(nsIFile& aFile) {
85     nsAutoString leafName;
86     MOZ_ALWAYS_SUCCEEDS(aFile.GetLeafName(leafName));
87     return leafName == kTemporaryString;
88   }
89 };
90 
91 template <>
92 nsLiteralCString
To()93 PersistenceTypeTraits<PERSISTENCE_TYPE_TEMPORARY>::To<nsLiteralCString>() {
94   return kTemporaryCString;
95 }
96 
97 template <>
98 StorageType
To()99 PersistenceTypeTraits<PERSISTENCE_TYPE_TEMPORARY>::To<StorageType>() {
100   return StorageType::Temporary;
101 }
102 
103 template <>
104 struct PersistenceTypeTraits<PERSISTENCE_TYPE_DEFAULT> {
105   template <typename T>
106   static T To();
107 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits108   static bool From(const nsACString& aString) {
109     return aString == kDefaultCString;
110   }
111 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits112   static bool From(const StorageType aStorageType) {
113     return aStorageType == StorageType::Default;
114   }
115 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits116   static bool From(const int32_t aInt32) { return aInt32 == 2; }
117 
Frommozilla::dom::quota::__anonccb47e540111::PersistenceTypeTraits118   static bool From(nsIFile& aFile) {
119     nsAutoString leafName;
120     MOZ_ALWAYS_SUCCEEDS(aFile.GetLeafName(leafName));
121     return leafName == kDefaultString;
122   }
123 };
124 
125 template <>
126 nsLiteralCString
To()127 PersistenceTypeTraits<PERSISTENCE_TYPE_DEFAULT>::To<nsLiteralCString>() {
128   return kDefaultCString;
129 }
130 
131 template <>
To()132 StorageType PersistenceTypeTraits<PERSISTENCE_TYPE_DEFAULT>::To<StorageType>() {
133   return StorageType::Default;
134 }
135 
136 template <typename T>
TypeTo_impl(const PersistenceType aPersistenceType)137 Maybe<T> TypeTo_impl(const PersistenceType aPersistenceType) {
138   switch (aPersistenceType) {
139     case PERSISTENCE_TYPE_PERSISTENT:
140       return Some(PersistenceTypeTraits<PERSISTENCE_TYPE_PERSISTENT>::To<T>());
141 
142     case PERSISTENCE_TYPE_TEMPORARY:
143       return Some(PersistenceTypeTraits<PERSISTENCE_TYPE_TEMPORARY>::To<T>());
144 
145     case PERSISTENCE_TYPE_DEFAULT:
146       return Some(PersistenceTypeTraits<PERSISTENCE_TYPE_DEFAULT>::To<T>());
147 
148     default:
149       return Nothing();
150   }
151 }
152 
153 template <typename T>
TypeFrom_impl(T & aData)154 Maybe<PersistenceType> TypeFrom_impl(T& aData) {
155   if (PersistenceTypeTraits<PERSISTENCE_TYPE_PERSISTENT>::From(aData)) {
156     return Some(PERSISTENCE_TYPE_PERSISTENT);
157   }
158 
159   if (PersistenceTypeTraits<PERSISTENCE_TYPE_TEMPORARY>::From(aData)) {
160     return Some(PERSISTENCE_TYPE_TEMPORARY);
161   }
162 
163   if (PersistenceTypeTraits<PERSISTENCE_TYPE_DEFAULT>::From(aData)) {
164     return Some(PERSISTENCE_TYPE_DEFAULT);
165   }
166 
167   return Nothing();
168 }
169 
BadPersistenceType()170 void BadPersistenceType() { MOZ_CRASH("Bad persistence type value!"); }
171 
172 }  // namespace
173 
IsValidPersistenceType(const PersistenceType aPersistenceType)174 bool IsValidPersistenceType(const PersistenceType aPersistenceType) {
175   switch (aPersistenceType) {
176     case PERSISTENCE_TYPE_PERSISTENT:
177     case PERSISTENCE_TYPE_TEMPORARY:
178     case PERSISTENCE_TYPE_DEFAULT:
179       return true;
180 
181     default:
182       return false;
183   }
184 }
185 
IsBestEffortPersistenceType(const PersistenceType aPersistenceType)186 bool IsBestEffortPersistenceType(const PersistenceType aPersistenceType) {
187   switch (aPersistenceType) {
188     case PERSISTENCE_TYPE_TEMPORARY:
189     case PERSISTENCE_TYPE_DEFAULT:
190       return true;
191 
192     case PERSISTENCE_TYPE_PERSISTENT:
193     case PERSISTENCE_TYPE_INVALID:
194     default:
195       return false;
196   }
197 }
198 
PersistenceTypeToString(const PersistenceType aPersistenceType)199 nsLiteralCString PersistenceTypeToString(
200     const PersistenceType aPersistenceType) {
201   const auto maybeString = TypeTo_impl<nsLiteralCString>(aPersistenceType);
202   if (maybeString.isNothing()) {
203     BadPersistenceType();
204   }
205   return maybeString.value();
206 }
207 
PersistenceTypeFromString(const nsACString & aString,const fallible_t &)208 Maybe<PersistenceType> PersistenceTypeFromString(const nsACString& aString,
209                                                  const fallible_t&) {
210   return TypeFrom_impl(aString);
211 }
212 
PersistenceTypeFromString(const nsACString & aString)213 PersistenceType PersistenceTypeFromString(const nsACString& aString) {
214   const auto maybePersistenceType = TypeFrom_impl(aString);
215   if (maybePersistenceType.isNothing()) {
216     BadPersistenceType();
217   }
218   return maybePersistenceType.value();
219 }
220 
PersistenceTypeToStorageType(const PersistenceType aPersistenceType)221 StorageType PersistenceTypeToStorageType(
222     const PersistenceType aPersistenceType) {
223   const auto maybeStorageType = TypeTo_impl<StorageType>(aPersistenceType);
224   if (maybeStorageType.isNothing()) {
225     BadPersistenceType();
226   }
227   return maybeStorageType.value();
228 }
229 
PersistenceTypeFromStorageType(const StorageType aStorageType)230 PersistenceType PersistenceTypeFromStorageType(const StorageType aStorageType) {
231   const auto maybePersistenceType = TypeFrom_impl(aStorageType);
232   if (maybePersistenceType.isNothing()) {
233     BadPersistenceType();
234   }
235   return maybePersistenceType.value();
236 }
237 
PersistenceTypeFromInt32(const int32_t aInt32,const fallible_t &)238 Maybe<PersistenceType> PersistenceTypeFromInt32(const int32_t aInt32,
239                                                 const fallible_t&) {
240   return TypeFrom_impl(aInt32);
241 }
242 
PersistenceTypeFromFile(nsIFile & aFile,const fallible_t &)243 Maybe<PersistenceType> PersistenceTypeFromFile(nsIFile& aFile,
244                                                const fallible_t&) {
245   return TypeFrom_impl(aFile);
246 }
247 
248 }  // namespace mozilla::dom::quota
249