diff options
Diffstat (limited to 'dom/cache/FileUtilsImpl.h')
-rw-r--r-- | dom/cache/FileUtilsImpl.h | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/dom/cache/FileUtilsImpl.h b/dom/cache/FileUtilsImpl.h new file mode 100644 index 0000000000..f2abc8c4b5 --- /dev/null +++ b/dom/cache/FileUtilsImpl.h @@ -0,0 +1,98 @@ +/* -*- 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 mozilla_dom_cache_FileUtilsImpl_h +#define mozilla_dom_cache_FileUtilsImpl_h + +#include "mozilla/dom/FlippedOnce.h" +#include "mozilla/dom/cache/FileUtils.h" + +namespace mozilla { +namespace dom { +namespace cache { + +template <typename Func> +nsresult BodyTraverseFiles(const QuotaInfo& aQuotaInfo, nsIFile& aBodyDir, + const Func& aHandleFileFunc, + const bool aCanRemoveFiles, const bool aTrackQuota) { +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + { + nsCOMPtr<nsIFile> parentFile; + nsresult rv = aBodyDir.GetParent(getter_AddRefs(parentFile)); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + MOZ_DIAGNOSTIC_ASSERT(parentFile); + + nsAutoCString nativeLeafName; + rv = parentFile->GetNativeLeafName(nativeLeafName); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + + MOZ_DIAGNOSTIC_ASSERT(StringEndsWith(nativeLeafName, "morgue"_ns)); + } +#endif + + FlippedOnce<true> isEmpty; + CACHE_TRY(quota::CollectEachFile( + aBodyDir, + [&isEmpty, &aQuotaInfo, aTrackQuota, &aHandleFileFunc, + aCanRemoveFiles](const nsCOMPtr<nsIFile>& file) -> Result<Ok, nsresult> { + CACHE_TRY_INSPECT(const bool& isDir, + MOZ_TO_RESULT_INVOKE(file, IsDirectory)); + + // If it's a directory somehow, try to remove it and move on + CACHE_TRY(OkIf(!isDir), Ok{}, ([&aQuotaInfo, &file](const auto&) { + DebugOnly<nsresult> result = RemoveNsIFileRecursively( + aQuotaInfo, *file, /* aTrackQuota */ false); + MOZ_ASSERT(NS_SUCCEEDED(result)); + })); + + nsAutoCString leafName; + CACHE_TRY(file->GetNativeLeafName(leafName)); + + // Delete all tmp files regardless of known bodies. These are all + // considered orphans. + if (StringEndsWith(leafName, ".tmp"_ns)) { + if (aCanRemoveFiles) { + DebugOnly<nsresult> result = + RemoveNsIFile(aQuotaInfo, *file, aTrackQuota); + MOZ_ASSERT(NS_SUCCEEDED(result)); + return Ok{}; + } + } else { + CACHE_TRY(OkIf(StringEndsWith(leafName, ".final"_ns)), Ok{}, + ([&aQuotaInfo, &file](const auto&) { + // Otherwise, it must be a .final file. If its not, then + // try to remove it and move on + DebugOnly<nsresult> result = RemoveNsIFile( + aQuotaInfo, *file, /* aTrackQuota */ false); + MOZ_ASSERT(NS_SUCCEEDED(result)); + })); + } + + CACHE_TRY_INSPECT(const bool& fileDeleted, + aHandleFileFunc(*file, leafName)); + if (fileDeleted) { + return Ok{}; + } + + isEmpty.EnsureFlipped(); + + return Ok{}; + })); + + if (isEmpty && aCanRemoveFiles) { + DebugOnly<nsresult> result = + RemoveNsIFileRecursively(aQuotaInfo, aBodyDir, /* aTrackQuota */ false); + MOZ_ASSERT(NS_SUCCEEDED(result)); + } + + return NS_OK; +} + +} // namespace cache +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_cache_FileUtilsImpl_h |