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 #ifndef mozilla_dom_cache_FileUtilsImpl_h
8 #define mozilla_dom_cache_FileUtilsImpl_h
10 #include "mozilla/dom/FlippedOnce.h"
11 #include "mozilla/dom/cache/FileUtils.h"
12 #include "mozilla/dom/quota/ResultExtensions.h"
14 namespace mozilla::dom::cache
{
16 template <typename Func
>
17 nsresult
BodyTraverseFiles(
18 const Maybe
<CacheDirectoryMetadata
>& aDirectoryMetadata
, nsIFile
& aBodyDir
,
19 const Func
& aHandleFileFunc
, const bool aCanRemoveFiles
,
20 const bool aTrackQuota
) {
21 // XXX This assertion proves that we can remove aTrackQuota and just check
22 // aClientMetadata.isSome()
23 MOZ_DIAGNOSTIC_ASSERT_IF(aTrackQuota
, aDirectoryMetadata
);
25 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
27 nsCOMPtr
<nsIFile
> parentFile
;
28 nsresult rv
= aBodyDir
.GetParent(getter_AddRefs(parentFile
));
29 MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv
));
30 MOZ_DIAGNOSTIC_ASSERT(parentFile
);
32 nsAutoCString nativeLeafName
;
33 rv
= parentFile
->GetNativeLeafName(nativeLeafName
);
34 MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv
));
36 MOZ_DIAGNOSTIC_ASSERT(StringEndsWith(nativeLeafName
, "morgue"_ns
));
40 FlippedOnce
<true> isEmpty
;
41 QM_TRY(quota::CollectEachFile(
43 [&isEmpty
, &aDirectoryMetadata
, aTrackQuota
, &aHandleFileFunc
,
44 aCanRemoveFiles
](const nsCOMPtr
<nsIFile
>& file
) -> Result
<Ok
, nsresult
> {
45 QM_TRY_INSPECT(const auto& dirEntryKind
, quota::GetDirEntryKind(*file
));
47 switch (dirEntryKind
) {
48 case quota::nsIFileKind::ExistsAsDirectory
: {
49 // If it's a directory somehow, try to remove it and move on
50 DebugOnly
<nsresult
> result
= RemoveNsIFileRecursively(
51 aDirectoryMetadata
, *file
, /* aTrackQuota */ false);
52 MOZ_ASSERT(NS_SUCCEEDED(result
));
56 case quota::nsIFileKind::ExistsAsFile
: {
57 nsAutoCString leafName
;
58 QM_TRY(MOZ_TO_RESULT(file
->GetNativeLeafName(leafName
)));
60 // Delete all tmp files regardless of known bodies. These are all
61 // considered orphans.
62 if (StringEndsWith(leafName
, ".tmp"_ns
)) {
63 if (aCanRemoveFiles
) {
64 DebugOnly
<nsresult
> result
=
65 RemoveNsIFile(aDirectoryMetadata
, *file
, aTrackQuota
);
66 MOZ_ASSERT(NS_SUCCEEDED(result
));
70 // Otherwise, it must be a .final file.
71 QM_WARNONLY_TRY_UNWRAP(
72 const auto maybeEndingOk
,
73 OkIf(StringEndsWith(leafName
, ".final"_ns
)));
75 // If its not, try to remove it and move on.
77 DebugOnly
<nsresult
> result
= RemoveNsIFile(
78 aDirectoryMetadata
, *file
, /* aTrackQuota */ false);
79 MOZ_ASSERT(NS_SUCCEEDED(result
));
84 QM_TRY_INSPECT(const bool& fileDeleted
,
85 aHandleFileFunc(*file
, leafName
));
90 isEmpty
.EnsureFlipped();
94 case quota::nsIFileKind::DoesNotExist
:
95 // Ignore files that got removed externally while iterating.
102 if (isEmpty
&& aCanRemoveFiles
) {
103 DebugOnly
<nsresult
> result
= RemoveNsIFileRecursively(
104 aDirectoryMetadata
, aBodyDir
, /* aTrackQuota */ false);
105 MOZ_ASSERT(NS_SUCCEEDED(result
));
111 } // namespace mozilla::dom::cache
113 #endif // mozilla_dom_cache_FileUtilsImpl_h