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 #include "FileStreams.h"
10 #include "QuotaCommon.h"
11 #include "QuotaManager.h"
12 #include "QuotaObject.h"
13 #include "RemoteQuotaObject.h"
17 #include "mozilla/Assertions.h"
18 #include "mozilla/DebugOnly.h"
19 #include "mozilla/Result.h"
20 #include "mozilla/dom/quota/ResultExtensions.h"
21 #include "mozilla/ipc/RandomAccessStreamParams.h"
25 namespace mozilla::dom::quota
{
27 template <class FileStreamBase
>
28 NS_IMETHODIMP FileQuotaStream
<FileStreamBase
>::SetEOF() {
29 // If the stream is not quota tracked, or on an early or late stage in the
30 // lifecycle, mQuotaObject is null. Under these circumstances,
31 // we don't check the quota limit in order to avoid breakage.
34 QM_TRY(MOZ_TO_RESULT(FileStreamBase::Tell(&offset
)));
36 QM_TRY(OkIf(mQuotaObject
->MaybeUpdateSize(offset
, /* aTruncate */ true)),
37 NS_ERROR_FILE_NO_DEVICE_SPACE
);
40 QM_TRY(MOZ_TO_RESULT(FileStreamBase::SetEOF()));
45 template <class FileStreamBase
>
46 NS_IMETHODIMP FileQuotaStream
<FileStreamBase
>::Close() {
47 QM_TRY(MOZ_TO_RESULT(FileStreamBase::Close()));
50 if (auto* remoteQuotaObject
= mQuotaObject
->AsRemoteQuotaObject()) {
51 remoteQuotaObject
->Close();
54 mQuotaObject
= nullptr;
60 template <class FileStreamBase
>
61 nsresult FileQuotaStream
<FileStreamBase
>::DoOpen() {
62 MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
63 MOZ_RELEASE_ASSERT(!mDeserialized
);
65 QuotaManager
* quotaManager
= QuotaManager::Get();
66 MOZ_ASSERT(quotaManager
, "Shouldn't be null!");
68 MOZ_ASSERT(!mQuotaObject
, "Creating quota object more than once?");
69 mQuotaObject
= quotaManager
->GetQuotaObject(
70 mPersistenceType
, mOriginMetadata
, mClientType
,
71 FileStreamBase::mOpenParams
.localFile
);
73 QM_TRY(MOZ_TO_RESULT(FileStreamBase::DoOpen()));
75 if (mQuotaObject
&& (FileStreamBase::mOpenParams
.ioFlags
& PR_TRUNCATE
)) {
77 mQuotaObject
->MaybeUpdateSize(0, /* aTruncate */ true);
84 template <class FileStreamBase
>
85 NS_IMETHODIMP FileQuotaStreamWithWrite
<FileStreamBase
>::Write(
86 const char* aBuf
, uint32_t aCount
, uint32_t* _retval
) {
87 if (FileQuotaStreamWithWrite::mQuotaObject
) {
89 QM_TRY(MOZ_TO_RESULT(FileStreamBase::Tell(&offset
)));
91 MOZ_ASSERT(INT64_MAX
- offset
>= int64_t(aCount
));
93 if (!FileQuotaStreamWithWrite::mQuotaObject
->MaybeUpdateSize(
94 offset
+ int64_t(aCount
),
95 /* aTruncate */ false)) {
97 return NS_ERROR_FILE_NO_DEVICE_SPACE
;
101 QM_TRY(MOZ_TO_RESULT(FileStreamBase::Write(aBuf
, aCount
, _retval
)));
106 mozilla::ipc::RandomAccessStreamParams
FileRandomAccessStream::Serialize(
107 nsIInterfaceRequestor
* aCallbacks
) {
108 MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
109 MOZ_RELEASE_ASSERT(!mDeserialized
);
110 MOZ_ASSERT(mOpenParams
.localFile
);
112 QuotaManager
* quotaManager
= QuotaManager::Get();
113 MOZ_ASSERT(quotaManager
);
115 RefPtr
<QuotaObject
> quotaObject
= quotaManager
->GetQuotaObject(
116 mPersistenceType
, mOriginMetadata
, mClientType
, mOpenParams
.localFile
);
117 MOZ_ASSERT(quotaObject
);
119 IPCQuotaObject ipcQuotaObject
= quotaObject
->Serialize(aCallbacks
);
121 mozilla::ipc::RandomAccessStreamParams randomAccessStreamParams
=
122 nsFileRandomAccessStream::Serialize(aCallbacks
);
125 randomAccessStreamParams
.type() ==
126 mozilla::ipc::RandomAccessStreamParams::TFileRandomAccessStreamParams
);
128 mozilla::ipc::LimitingFileRandomAccessStreamParams
129 limitingFileRandomAccessStreamParams
;
130 limitingFileRandomAccessStreamParams
.fileRandomAccessStreamParams() =
131 std::move(randomAccessStreamParams
);
132 limitingFileRandomAccessStreamParams
.quotaObject() =
133 std::move(ipcQuotaObject
);
135 return limitingFileRandomAccessStreamParams
;
138 bool FileRandomAccessStream::Deserialize(
139 mozilla::ipc::RandomAccessStreamParams
& aParams
) {
140 MOZ_ASSERT(aParams
.type() == mozilla::ipc::RandomAccessStreamParams::
141 TLimitingFileRandomAccessStreamParams
);
143 auto& params
= aParams
.get_LimitingFileRandomAccessStreamParams();
145 mozilla::ipc::RandomAccessStreamParams
randomAccessStreamParams(
146 std::move(params
.fileRandomAccessStreamParams()));
148 QM_TRY(MOZ_TO_RESULT(
149 nsFileRandomAccessStream::Deserialize(randomAccessStreamParams
)),
152 mQuotaObject
= QuotaObject::Deserialize(params
.quotaObject());
157 Result
<MovingNotNull
<nsCOMPtr
<nsIInputStream
>>, nsresult
> CreateFileInputStream(
158 PersistenceType aPersistenceType
, const OriginMetadata
& aOriginMetadata
,
159 Client::Type aClientType
, nsIFile
* aFile
, int32_t aIOFlags
, int32_t aPerm
,
160 int32_t aBehaviorFlags
) {
161 auto stream
= MakeRefPtr
<FileInputStream
>(aPersistenceType
, aOriginMetadata
,
164 QM_TRY(MOZ_TO_RESULT(stream
->Init(aFile
, aIOFlags
, aPerm
, aBehaviorFlags
)));
166 return WrapMovingNotNullUnchecked(
167 nsCOMPtr
<nsIInputStream
>(std::move(stream
)));
170 Result
<MovingNotNull
<nsCOMPtr
<nsIOutputStream
>>, nsresult
>
171 CreateFileOutputStream(PersistenceType aPersistenceType
,
172 const OriginMetadata
& aOriginMetadata
,
173 Client::Type aClientType
, nsIFile
* aFile
,
174 int32_t aIOFlags
, int32_t aPerm
,
175 int32_t aBehaviorFlags
) {
176 auto stream
= MakeRefPtr
<FileOutputStream
>(aPersistenceType
, aOriginMetadata
,
179 QM_TRY(MOZ_TO_RESULT(stream
->Init(aFile
, aIOFlags
, aPerm
, aBehaviorFlags
)));
181 return WrapMovingNotNullUnchecked(
182 nsCOMPtr
<nsIOutputStream
>(std::move(stream
)));
185 Result
<MovingNotNull
<nsCOMPtr
<nsIRandomAccessStream
>>, nsresult
>
186 CreateFileRandomAccessStream(PersistenceType aPersistenceType
,
187 const OriginMetadata
& aOriginMetadata
,
188 Client::Type aClientType
, nsIFile
* aFile
,
189 int32_t aIOFlags
, int32_t aPerm
,
190 int32_t aBehaviorFlags
) {
191 auto stream
= MakeRefPtr
<FileRandomAccessStream
>(
192 aPersistenceType
, aOriginMetadata
, aClientType
);
194 QM_TRY(MOZ_TO_RESULT(stream
->Init(aFile
, aIOFlags
, aPerm
, aBehaviorFlags
)));
196 return WrapMovingNotNullUnchecked(
197 nsCOMPtr
<nsIRandomAccessStream
>(std::move(stream
)));
200 } // namespace mozilla::dom::quota