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/. */
6 
7 #include "FileStreams.h"
8 
9 // Local includes
10 #include "QuotaCommon.h"
11 #include "QuotaManager.h"
12 #include "QuotaObject.h"
13 
14 // Global includes
15 #include <utility>
16 #include "mozilla/Assertions.h"
17 #include "mozilla/DebugOnly.h"
18 #include "mozilla/Result.h"
19 #include "nsDebug.h"
20 #include "prio.h"
21 
22 namespace mozilla::dom::quota {
23 
24 template <class FileStreamBase>
SetEOF()25 NS_IMETHODIMP FileQuotaStream<FileStreamBase>::SetEOF() {
26   QM_TRY(FileStreamBase::SetEOF());
27 
28   if (mQuotaObject) {
29     int64_t offset;
30     QM_TRY(FileStreamBase::Tell(&offset));
31 
32     DebugOnly<bool> res =
33         mQuotaObject->MaybeUpdateSize(offset, /* aTruncate */ true);
34     MOZ_ASSERT(res);
35   }
36 
37   return NS_OK;
38 }
39 
40 template <class FileStreamBase>
Close()41 NS_IMETHODIMP FileQuotaStream<FileStreamBase>::Close() {
42   QM_TRY(FileStreamBase::Close());
43 
44   mQuotaObject = nullptr;
45 
46   return NS_OK;
47 }
48 
49 template <class FileStreamBase>
DoOpen()50 nsresult FileQuotaStream<FileStreamBase>::DoOpen() {
51   QuotaManager* quotaManager = QuotaManager::Get();
52   NS_ASSERTION(quotaManager, "Shouldn't be null!");
53 
54   NS_ASSERTION(!mQuotaObject, "Creating quota object more than once?");
55   mQuotaObject = quotaManager->GetQuotaObject(
56       mPersistenceType, mOriginMetadata, mClientType,
57       FileStreamBase::mOpenParams.localFile);
58 
59   QM_TRY(FileStreamBase::DoOpen());
60 
61   if (mQuotaObject && (FileStreamBase::mOpenParams.ioFlags & PR_TRUNCATE)) {
62     DebugOnly<bool> res =
63         mQuotaObject->MaybeUpdateSize(0, /* aTruncate */ true);
64     MOZ_ASSERT(res);
65   }
66 
67   return NS_OK;
68 }
69 
70 template <class FileStreamBase>
Write(const char * aBuf,uint32_t aCount,uint32_t * _retval)71 NS_IMETHODIMP FileQuotaStreamWithWrite<FileStreamBase>::Write(
72     const char* aBuf, uint32_t aCount, uint32_t* _retval) {
73   if (FileQuotaStreamWithWrite::mQuotaObject) {
74     int64_t offset;
75     QM_TRY(FileStreamBase::Tell(&offset));
76 
77     MOZ_ASSERT(INT64_MAX - offset >= int64_t(aCount));
78 
79     if (!FileQuotaStreamWithWrite::mQuotaObject->MaybeUpdateSize(
80             offset + int64_t(aCount),
81             /* aTruncate */ false)) {
82       return NS_ERROR_FILE_NO_DEVICE_SPACE;
83     }
84   }
85 
86   QM_TRY(FileStreamBase::Write(aBuf, aCount, _retval));
87 
88   return NS_OK;
89 }
90 
CreateFileInputStream(PersistenceType aPersistenceType,const OriginMetadata & aOriginMetadata,Client::Type aClientType,nsIFile * aFile,int32_t aIOFlags,int32_t aPerm,int32_t aBehaviorFlags)91 Result<NotNull<RefPtr<FileInputStream>>, nsresult> CreateFileInputStream(
92     PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
93     Client::Type aClientType, nsIFile* aFile, int32_t aIOFlags, int32_t aPerm,
94     int32_t aBehaviorFlags) {
95   const auto stream = MakeNotNull<RefPtr<FileInputStream>>(
96       aPersistenceType, aOriginMetadata, aClientType);
97 
98   QM_TRY(stream->Init(aFile, aIOFlags, aPerm, aBehaviorFlags));
99 
100   return stream;
101 }
102 
CreateFileOutputStream(PersistenceType aPersistenceType,const OriginMetadata & aOriginMetadata,Client::Type aClientType,nsIFile * aFile,int32_t aIOFlags,int32_t aPerm,int32_t aBehaviorFlags)103 Result<NotNull<RefPtr<FileOutputStream>>, nsresult> CreateFileOutputStream(
104     PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
105     Client::Type aClientType, nsIFile* aFile, int32_t aIOFlags, int32_t aPerm,
106     int32_t aBehaviorFlags) {
107   const auto stream = MakeNotNull<RefPtr<FileOutputStream>>(
108       aPersistenceType, aOriginMetadata, aClientType);
109 
110   QM_TRY(stream->Init(aFile, aIOFlags, aPerm, aBehaviorFlags));
111 
112   return stream;
113 }
114 
CreateFileStream(PersistenceType aPersistenceType,const OriginMetadata & aOriginMetadata,Client::Type aClientType,nsIFile * aFile,int32_t aIOFlags,int32_t aPerm,int32_t aBehaviorFlags)115 Result<NotNull<RefPtr<FileStream>>, nsresult> CreateFileStream(
116     PersistenceType aPersistenceType, const OriginMetadata& aOriginMetadata,
117     Client::Type aClientType, nsIFile* aFile, int32_t aIOFlags, int32_t aPerm,
118     int32_t aBehaviorFlags) {
119   const auto stream = MakeNotNull<RefPtr<FileStream>>(
120       aPersistenceType, aOriginMetadata, aClientType);
121 
122   QM_TRY(stream->Init(aFile, aIOFlags, aPerm, aBehaviorFlags));
123 
124   return stream;
125 }
126 
127 }  // namespace mozilla::dom::quota
128