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_FileUtils_h
8 #define mozilla_dom_cache_FileUtils_h
10 #include "mozilla/Attributes.h"
11 #include "mozilla/dom/cache/Types.h"
12 #include "CacheCommon.h"
13 #include "mozIStorageConnection.h"
14 #include "nsStreamUtils.h"
15 #include "nsTArrayForwardDeclare.h"
20 namespace mozilla::dom::cache
{
22 #define PADDING_FILE_NAME u".padding"
23 #define PADDING_TMP_FILE_NAME u".padding-tmp"
25 enum class DirPaddingFile
{ FILE, TMP_FILE
};
27 nsresult
BodyCreateDir(nsIFile
& aBaseDir
);
29 // Note that this function can only be used during the initialization of the
30 // database. We're unlikely to be able to delete the DB successfully past
31 // that point due to the file being in use.
32 nsresult
BodyDeleteDir(const CacheDirectoryMetadata
& aDirectoryMetadata
,
35 // Returns a Result with a success value with the body id and, optionally, the
37 Result
<std::pair
<nsID
, nsCOMPtr
<nsISupports
>>, nsresult
> BodyStartWriteStream(
38 const CacheDirectoryMetadata
& aDirectoryMetadata
, nsIFile
& aBaseDir
,
39 nsIInputStream
& aSource
, void* aClosure
, nsAsyncCopyCallbackFun aCallback
);
41 void BodyCancelWrite(nsISupports
& aCopyContext
);
43 nsresult
BodyFinalizeWrite(nsIFile
& aBaseDir
, const nsID
& aId
);
45 Result
<MovingNotNull
<nsCOMPtr
<nsIInputStream
>>, nsresult
> BodyOpen(
46 const CacheDirectoryMetadata
& aDirectoryMetadata
, nsIFile
& aBaseDir
,
49 nsresult
BodyMaybeUpdatePaddingSize(
50 const CacheDirectoryMetadata
& aDirectoryMetadata
, nsIFile
& aBaseDir
,
51 const nsID
& aId
, uint32_t aPaddingInfo
, int64_t* aPaddingSizeInOut
);
53 nsresult
BodyDeleteFiles(const CacheDirectoryMetadata
& aDirectoryMetadata
,
54 nsIFile
& aBaseDir
, const nsTArray
<nsID
>& aIdList
);
56 nsresult
BodyDeleteOrphanedFiles(
57 const CacheDirectoryMetadata
& aDirectoryMetadata
, nsIFile
& aBaseDir
,
58 const nsTArray
<nsID
>& aKnownBodyIdList
);
60 // If aCanRemoveFiles is true, that means we are safe to touch the files which
61 // can be accessed in other threads.
62 // If it's not, that means we cannot remove the files which are possible to
63 // created by other threads. Note that if the files are not expected, we should
64 // be safe to remove them in any case.
65 template <typename Func
>
66 nsresult
BodyTraverseFiles(
67 const Maybe
<CacheDirectoryMetadata
>& aDirectoryMetadata
, nsIFile
& aBodyDir
,
68 const Func
& aHandleFileFunc
, bool aCanRemoveFiles
, bool aTrackQuota
= true);
70 // XXX Remove this method when all callers properly wrap aClientMetadata with
72 template <typename Func
>
73 nsresult
BodyTraverseFiles(const CacheDirectoryMetadata
& aDirectoryMetadata
,
74 nsIFile
& aBodyDir
, const Func
& aHandleFileFunc
,
75 bool aCanRemoveFiles
, bool aTrackQuota
= true) {
76 return BodyTraverseFiles(Some(aDirectoryMetadata
), aBodyDir
, aHandleFileFunc
,
77 aCanRemoveFiles
, aTrackQuota
);
80 nsresult
CreateMarkerFile(const CacheDirectoryMetadata
& aDirectoryMetadata
);
82 nsresult
DeleteMarkerFile(const CacheDirectoryMetadata
& aDirectoryMetadata
);
84 bool MarkerFileExists(const CacheDirectoryMetadata
& aDirectoryMetadata
);
86 nsresult
RemoveNsIFileRecursively(
87 const Maybe
<CacheDirectoryMetadata
>& aDirectoryMetadata
, nsIFile
& aFile
,
88 bool aTrackQuota
= true);
90 // XXX Remove this method when all callers properly wrap aClientMetadata with
92 inline nsresult
RemoveNsIFileRecursively(
93 const CacheDirectoryMetadata
& aDirectoryMetadata
, nsIFile
& aFile
,
94 bool aTrackQuota
= true) {
95 return RemoveNsIFileRecursively(Some(aDirectoryMetadata
), aFile
, aTrackQuota
);
98 // Delete a file that you think exists. If the file doesn't exist, an error
99 // will not be returned, but warning telemetry will be generated! So only call
100 // this on files that you know exist (idempotent usage, but it's not
102 nsresult
RemoveNsIFile(const Maybe
<CacheDirectoryMetadata
>& aDirectoryMetadata
,
103 nsIFile
& aFile
, bool aTrackQuota
= true);
105 // XXX Remove this method when all callers properly wrap aClientMetadata with
107 inline nsresult
RemoveNsIFile(const CacheDirectoryMetadata
& aDirectoryMetadata
,
108 nsIFile
& aFile
, bool aTrackQuota
= true) {
109 return RemoveNsIFile(Some(aDirectoryMetadata
), aFile
, aTrackQuota
);
112 void DecreaseUsageForDirectoryMetadata(
113 const CacheDirectoryMetadata
& aDirectoryMetadata
, int64_t aUpdatingSize
);
116 * This function is used to check if the directory padding file is existed.
118 bool DirectoryPaddingFileExists(nsIFile
& aBaseDir
,
119 DirPaddingFile aPaddingFileType
);
123 * The functions below are used to read/write/delete the directory padding file
124 * after acquiring the mutex lock. The mutex lock is held by
125 * CacheQuotaClient to prevent multi-thread accessing issue. To avoid deadlock,
126 * these functions should only access by static functions in
127 * dom/cache/QuotaClient.cpp.
131 // Returns a Result with a success value denoting the padding size.
132 Result
<int64_t, nsresult
> DirectoryPaddingGet(nsIFile
& aBaseDir
);
134 nsresult
DirectoryPaddingInit(nsIFile
& aBaseDir
);
136 nsresult
UpdateDirectoryPaddingFile(nsIFile
& aBaseDir
,
137 mozIStorageConnection
& aConn
,
138 int64_t aIncreaseSize
,
139 int64_t aDecreaseSize
,
140 bool aTemporaryFileExist
);
142 nsresult
DirectoryPaddingFinalizeWrite(nsIFile
& aBaseDir
);
144 // Returns a Result with a success value denoting the padding size.
145 Result
<int64_t, nsresult
> DirectoryPaddingRestore(nsIFile
& aBaseDir
,
146 mozIStorageConnection
& aConn
,
149 nsresult
DirectoryPaddingDeleteFile(nsIFile
& aBaseDir
,
150 DirPaddingFile aPaddingFileType
);
151 } // namespace mozilla::dom::cache
153 #endif // mozilla_dom_cache_FileUtils_h