Bug 1563023 - Part 5: Rationalize Client::TypeToText and Client::TypeFromText methods; r=asuth
authorJan Varga <jan.varga@gmail.com>
Fri, 23 Aug 2019 04:49:14 +0000
changeset 489564 b62dd021e1700bed1e51dfcaa5ecc5dcfe1dc399
parent 489563 a82e5f008873bfae613dde49f1ef44a439050c5b
child 489565 b70ad16ea2aedd286a84fe0935a18176a59c61a3
push id93440
push userjvarga@mozilla.com
push dateFri, 23 Aug 2019 07:23:18 +0000
treeherderautoland@b70ad16ea2ae [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1563023
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1563023 - Part 5: Rationalize Client::TypeToText and Client::TypeFromText methods; r=asuth This patch makes it easier to create new Client::TypeTo and Client::TypeFrom variations by creating generic reusable helpers. Differential Revision: https://phabricator.services.mozilla.com/D38628
dom/quota/ActorsParent.cpp
dom/quota/Client.cpp
dom/quota/Client.h
dom/quota/QuotaManagerService.cpp
dom/quota/moz.build
--- a/dom/quota/ActorsParent.cpp
+++ b/dom/quota/ActorsParent.cpp
@@ -3796,18 +3796,18 @@ already_AddRefed<QuotaObject> QuotaManag
   nsCOMPtr<nsIFile> directory;
   rv = GetDirectoryForOrigin(aPersistenceType, aOrigin,
                              getter_AddRefs(directory));
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
   nsAutoString clientType;
-  rv = Client::TypeToText(aClientType, clientType);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
+  bool ok = Client::TypeToText(aClientType, clientType, fallible);
+  if (NS_WARN_IF(!ok)) {
     return nullptr;
   }
 
   rv = directory->Append(clientType);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return nullptr;
   }
 
@@ -4374,18 +4374,18 @@ nsresult QuotaManager::InitializeOrigin(
           leafName, 1);
 #endif
 
       RECORD_IN_NIGHTLY(statusKeeper, NS_ERROR_UNEXPECTED);
       CONTINUE_IN_NIGHTLY_RETURN_IN_OTHERS(NS_ERROR_UNEXPECTED);
     }
 
     Client::Type clientType;
-    rv = Client::TypeFromText(leafName, clientType);
-    if (NS_FAILED(rv)) {
+    bool ok = Client::TypeFromText(leafName, clientType, fallible);
+    if (!ok) {
       UNKNOWN_FILE_WARNING(leafName);
       REPORT_TELEMETRY_INIT_ERR(kQuotaInternalError, Ori_UnexpectedClient);
       RECORD_IN_NIGHTLY(statusKeeper, NS_ERROR_UNEXPECTED);
 
       // Our upgrade process should have attempted to delete the deprecated
       // client directory and failed to upgrade if it could not be deleted. So
       // if we're here, either a) there's a bug in our code or b) a user copied
       // over parts of an old profile into a new profile for some reason and the
@@ -7801,18 +7801,18 @@ nsresult QuotaUsageRequestBase::GetUsage
         UNKNOWN_FILE_WARNING(leafName);
         if (!initialized) {
           return NS_ERROR_UNEXPECTED;
         }
         continue;
       }
 
       Client::Type clientType;
-      rv = Client::TypeFromText(leafName, clientType);
-      if (NS_FAILED(rv)) {
+      bool ok = Client::TypeFromText(leafName, clientType, fallible);
+      if (!ok) {
         UNKNOWN_FILE_WARNING(leafName);
         if (!initialized) {
           return NS_ERROR_UNEXPECTED;
         }
         continue;
       }
 
       Client* client = aQuotaManager->GetClient(clientType);
@@ -8455,32 +8455,33 @@ void ClearRequestBase::DeleteFiles(Quota
 
         nsString leafName;
         rv = clientFile->GetLeafName(leafName);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return;
         }
 
         Client::Type clientType;
-        rv = Client::TypeFromText(leafName, clientType);
-        if (NS_FAILED(rv)) {
+        bool ok = Client::TypeFromText(leafName, clientType, fallible);
+        if (!ok) {
           UNKNOWN_FILE_WARNING(leafName);
           continue;
         }
 
         if (clientType != mClientType.Value()) {
           hasOtherClient = true;
           break;
         }
       }
 
       if (hasOtherClient) {
         nsAutoString clientDirectoryName;
-        rv = Client::TypeToText(mClientType.Value(), clientDirectoryName);
-        if (NS_WARN_IF(NS_FAILED(rv))) {
+        bool ok = Client::TypeToText(mClientType.Value(), clientDirectoryName,
+                                     fallible);
+        if (NS_WARN_IF(!ok)) {
           return;
         }
 
         rv = file->Append(clientDirectoryName);
         if (NS_WARN_IF(NS_FAILED(rv))) {
           return;
         }
 
@@ -9934,18 +9935,18 @@ nsresult RepositoryOperationBase::MaybeU
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     if (removed) {
       continue;
     }
 
     Client::Type clientType;
-    rv = Client::TypeFromText(leafName, clientType);
-    if (NS_FAILED(rv)) {
+    bool ok = Client::TypeFromText(leafName, clientType, fallible);
+    if (!ok) {
       UNKNOWN_FILE_WARNING(leafName);
       continue;
     }
 
     Client* client = quotaManager->GetClient(clientType);
     MOZ_ASSERT(client);
 
     rv = (client->*aMethod)(file);
@@ -9987,18 +9988,18 @@ nsresult CreateOrUpgradeDirectoryMetadat
     return rv;
   }
 
   if (!exists) {
     // Directory structure upgrade needed.
     // Move all files to IDB specific directory.
 
     nsString idbDirectoryName;
-    rv = Client::TypeToText(Client::IDB, idbDirectoryName);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
+    bool ok = Client::TypeToText(Client::IDB, idbDirectoryName, fallible);
+    if (NS_WARN_IF(!ok)) {
       return rv;
     }
 
     nsCOMPtr<nsIFile> idbDirectory;
     rv = aDirectory->Clone(getter_AddRefs(idbDirectory));
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
new file mode 100644
--- /dev/null
+++ b/dom/quota/Client.cpp
@@ -0,0 +1,176 @@
+/* -*- 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/. */
+
+#include "Client.h"
+
+namespace mozilla {
+namespace dom {
+namespace quota {
+
+namespace {
+
+template <Client::Type type>
+struct ClientTypeTraits;
+
+template <>
+struct ClientTypeTraits<Client::Type::IDB> {
+  template <typename T>
+  static void To(T& aData) {
+    aData.AssignLiteral(IDB_DIRECTORY_NAME);
+  }
+
+  template <typename T>
+  static bool From(const T& aData) {
+    return aData.EqualsLiteral(IDB_DIRECTORY_NAME);
+  }
+};
+
+template <>
+struct ClientTypeTraits<Client::Type::DOMCACHE> {
+  template <typename T>
+  static void To(T& aData) {
+    aData.AssignLiteral(DOMCACHE_DIRECTORY_NAME);
+  }
+
+  template <typename T>
+  static bool From(const T& aData) {
+    return aData.EqualsLiteral(DOMCACHE_DIRECTORY_NAME);
+  }
+};
+
+template <>
+struct ClientTypeTraits<Client::Type::SDB> {
+  template <typename T>
+  static void To(T& aData) {
+    aData.AssignLiteral(SDB_DIRECTORY_NAME);
+  }
+
+  template <typename T>
+  static bool From(const T& aData) {
+    return aData.EqualsLiteral(SDB_DIRECTORY_NAME);
+  }
+};
+
+template <>
+struct ClientTypeTraits<Client::Type::LS> {
+  template <typename T>
+  static void To(T& aData) {
+    aData.AssignLiteral(LS_DIRECTORY_NAME);
+  }
+
+  template <typename T>
+  static bool From(const T& aData) {
+    return aData.EqualsLiteral(LS_DIRECTORY_NAME);
+  }
+};
+
+template <typename T>
+bool TypeTo_impl(Client::Type aType, T& aData) {
+  switch (aType) {
+    case Client::IDB:
+      ClientTypeTraits<Client::Type::IDB>::To(aData);
+      return true;
+
+    case Client::DOMCACHE:
+      ClientTypeTraits<Client::Type::DOMCACHE>::To(aData);
+      return true;
+
+    case Client::SDB:
+      ClientTypeTraits<Client::Type::SDB>::To(aData);
+      return true;
+
+    case Client::LS:
+      if (CachedNextGenLocalStorageEnabled()) {
+        ClientTypeTraits<Client::Type::LS>::To(aData);
+        return true;
+      }
+      MOZ_FALLTHROUGH;
+
+    case Client::TYPE_MAX:
+    default:
+      return false;
+  }
+
+  MOZ_CRASH("Should never get here!");
+}
+
+template <typename T>
+bool TypeFrom_impl(const T& aData, Client::Type& aType) {
+  if (ClientTypeTraits<Client::Type::IDB>::From(aData)) {
+    aType = Client::IDB;
+    return true;
+  }
+
+  if (ClientTypeTraits<Client::Type::DOMCACHE>::From(aData)) {
+    aType = Client::DOMCACHE;
+    return true;
+  }
+
+  if (ClientTypeTraits<Client::Type::SDB>::From(aData)) {
+    aType = Client::SDB;
+    return true;
+  }
+
+  if (CachedNextGenLocalStorageEnabled() &&
+      ClientTypeTraits<Client::Type::LS>::From(aData)) {
+    aType = Client::LS;
+    return true;
+  }
+
+  return false;
+}
+
+void BadType() { MOZ_CRASH("Bad client type value!"); }
+
+}  // namespace
+
+// static
+bool Client::TypeToText(Type aType, nsAString& aText, const fallible_t&) {
+  nsString text;
+  if (!TypeTo_impl(aType, text)) {
+    return false;
+  }
+  aText = text;
+  return true;
+}
+
+// static
+void Client::TypeToText(Type aType, nsAString& aText) {
+  if (!TypeTo_impl(aType, aText)) {
+    BadType();
+  }
+}
+
+// static
+void Client::TypeToText(Type aType, nsACString& aText) {
+  if (!TypeTo_impl(aType, aText)) {
+    BadType();
+  }
+}
+
+// static
+bool Client::TypeFromText(const nsAString& aText, Type& aType,
+                          const fallible_t&) {
+  Type type;
+  if (!TypeFrom_impl(aText, type)) {
+    return false;
+  }
+  aType = type;
+  return true;
+}
+
+// static
+Client::Type Client::TypeFromText(const nsACString& aText) {
+  Type type;
+  if (!TypeFrom_impl(aText, type)) {
+    BadType();
+  }
+  return type;
+}
+
+}  // namespace quota
+}  // namespace dom
+}  // namespace mozilla
--- a/dom/quota/Client.h
+++ b/dom/quota/Client.h
@@ -33,152 +33,51 @@ class UsageInfo;
 
 // An abstract interface for quota manager clients.
 // Each storage API must provide an implementation of this interface in order
 // to participate in centralized quota and storage handling.
 class Client {
  public:
   typedef mozilla::Atomic<bool> AtomicBool;
 
-  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
-
   enum Type {
     IDB = 0,
     // APPCACHE,
     DOMCACHE,
     SDB,
     LS,
     TYPE_MAX
   };
 
   static Type TypeMax() {
     if (CachedNextGenLocalStorageEnabled()) {
       return TYPE_MAX;
     }
     return LS;
   }
 
-  virtual Type GetType() = 0;
-
-  static void TypeToText(Type aType, nsACString& aText) {
-    switch (aType) {
-      case IDB:
-        aText.AssignLiteral(IDB_DIRECTORY_NAME);
-        return;
-
-      case DOMCACHE:
-        aText.AssignLiteral(DOMCACHE_DIRECTORY_NAME);
-        return;
-
-      case SDB:
-        aText.AssignLiteral(SDB_DIRECTORY_NAME);
-        return;
-
-      case LS:
-        if (CachedNextGenLocalStorageEnabled()) {
-          aText.AssignLiteral(LS_DIRECTORY_NAME);
-          return;
-        }
-        MOZ_FALLTHROUGH;
+  static bool TypeToText(Type aType, nsAString& aText, const fallible_t&);
 
-      case TYPE_MAX:
-      default:
-        MOZ_CRASH("Bad client type value!");
-    }
-  }
-
-  static nsresult TypeToText(Type aType, nsAString& aText) {
-    switch (aType) {
-      case IDB:
-        aText.AssignLiteral(IDB_DIRECTORY_NAME);
-        break;
-
-      case DOMCACHE:
-        aText.AssignLiteral(DOMCACHE_DIRECTORY_NAME);
-        break;
-
-      case SDB:
-        aText.AssignLiteral(SDB_DIRECTORY_NAME);
-        break;
-
-      case LS:
-        if (CachedNextGenLocalStorageEnabled()) {
-          aText.AssignLiteral(LS_DIRECTORY_NAME);
-          break;
-        }
-        MOZ_FALLTHROUGH;
-
-      case TYPE_MAX:
-      default:
-        MOZ_ASSERT_UNREACHABLE("Bad id value!");
-        return NS_ERROR_UNEXPECTED;
-    }
+  static void TypeToText(Type aType, nsAString& aText);
 
-    return NS_OK;
-  }
-
-  static Type TypeFromText(const nsACString& aText) {
-    if (aText.EqualsLiteral(IDB_DIRECTORY_NAME)) {
-      return IDB;
-    }
-
-    if (aText.EqualsLiteral(DOMCACHE_DIRECTORY_NAME)) {
-      return DOMCACHE;
-    }
-
-    if (aText.EqualsLiteral(SDB_DIRECTORY_NAME)) {
-      return SDB;
-    }
-
-    if (CachedNextGenLocalStorageEnabled() &&
-        aText.EqualsLiteral(LS_DIRECTORY_NAME)) {
-      return LS;
-    }
-
-    MOZ_CRASH("Should never get here!");
-  }
+  static void TypeToText(Type aType, nsACString& aText);
 
-  static nsresult TypeFromText(const nsAString& aText, Type& aType) {
-    if (aText.EqualsLiteral(IDB_DIRECTORY_NAME)) {
-      aType = IDB;
-    } else if (aText.EqualsLiteral(DOMCACHE_DIRECTORY_NAME)) {
-      aType = DOMCACHE;
-    } else if (aText.EqualsLiteral(SDB_DIRECTORY_NAME)) {
-      aType = SDB;
-    } else if (CachedNextGenLocalStorageEnabled() &&
-               aText.EqualsLiteral(LS_DIRECTORY_NAME)) {
-      aType = LS;
-    } else {
-      return NS_ERROR_FAILURE;
-    }
-
-    return NS_OK;
-  }
+  static bool TypeFromText(const nsAString& aText, Type& aType,
+                           const fallible_t&);
 
-  static nsresult NullableTypeFromText(const nsAString& aText,
-                                       Nullable<Type>* aType) {
-    if (aText.IsVoid()) {
-      *aType = Nullable<Type>();
-      return NS_OK;
-    }
-
-    Type type;
-    nsresult rv = TypeFromText(aText, type);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return rv;
-    }
-
-    *aType = Nullable<Type>(type);
-    return NS_OK;
-  }
+  static Type TypeFromText(const nsACString& aText);
 
   static bool IsDeprecatedClient(const nsAString& aText) {
     return aText.EqualsLiteral(ASMJSCACHE_DIRECTORY_NAME);
   }
 
+  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+
+  virtual Type GetType() = 0;
+
   // Methods which are called on the IO thread.
   virtual nsresult UpgradeStorageFrom1_0To2_0(nsIFile* aDirectory) {
     return NS_OK;
   }
 
   virtual nsresult UpgradeStorageFrom2_0To2_1(nsIFile* aDirectory) {
     return NS_OK;
   }
--- a/dom/quota/QuotaManagerService.cpp
+++ b/dom/quota/QuotaManagerService.cpp
@@ -87,26 +87,26 @@ nsresult GetClearResetOriginParams(nsIPr
 
   if (persistenceType.IsNull()) {
     aParams.persistenceTypeIsExplicit() = false;
   } else {
     aParams.persistenceType() = persistenceType.Value();
     aParams.persistenceTypeIsExplicit() = true;
   }
 
-  Nullable<Client::Type> clientType;
-  rv = Client::NullableTypeFromText(aClientType, &clientType);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return NS_ERROR_INVALID_ARG;
-  }
-
-  if (clientType.IsNull()) {
+  if (aClientType.IsVoid()) {
     aParams.clientTypeIsExplicit() = false;
   } else {
-    aParams.clientType() = clientType.Value();
+    Client::Type clientType;
+    bool ok = Client::TypeFromText(aClientType, clientType, fallible);
+    if (NS_WARN_IF(!ok)) {
+      return NS_ERROR_INVALID_ARG;
+    }
+
+    aParams.clientType() = clientType;
     aParams.clientTypeIsExplicit() = true;
   }
 
   aParams.matchAll() = aMatchAll;
 
   return NS_OK;
 }
 
--- a/dom/quota/moz.build
+++ b/dom/quota/moz.build
@@ -52,16 +52,17 @@ EXPORTS.mozilla.dom.quota += [
 
 XPCOM_MANIFESTS += [
     'components.conf',
 ]
 
 UNIFIED_SOURCES += [
     'ActorsChild.cpp',
     'ActorsParent.cpp',
+    'Client.cpp',
     'FileStreams.cpp',
     'MemoryOutputStream.cpp',
     'nsIndexedDBProtocolHandler.cpp',
     'QuotaCommon.cpp',
     'QuotaManagerService.cpp',
     'QuotaRequests.cpp',
     'QuotaResults.cpp',
     'StorageManager.cpp',