1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsFileStreams_h__
7 #define nsFileStreams_h__
9 #include "mozilla/UniquePtr.h"
10 #include "nsIFileStreams.h"
12 #include "nsICloneableInputStream.h"
13 #include "nsIInputStream.h"
14 #include "nsIOutputStream.h"
15 #include "nsIRandomAccessStream.h"
16 #include "nsISafeOutputStream.h"
17 #include "nsISeekableStream.h"
18 #include "nsILineInputStream.h"
20 #include "nsIIPCSerializableInputStream.h"
21 #include "nsReadLine.h"
28 } // namespace mozilla
30 ////////////////////////////////////////////////////////////////////////////////
32 class nsFileStreamBase
: public nsISeekableStream
, public nsIFileMetadata
{
34 NS_DECL_THREADSAFE_ISUPPORTS
35 NS_DECL_NSISEEKABLESTREAM
36 NS_DECL_NSITELLABLESTREAM
37 NS_DECL_NSIFILEMETADATA
39 nsFileStreamBase() = default;
42 virtual ~nsFileStreamBase();
45 nsresult
Available(uint64_t* aResult
);
46 nsresult
Read(char* aBuf
, uint32_t aCount
, uint32_t* aResult
);
47 nsresult
ReadSegments(nsWriteSegmentFun aWriter
, void* aClosure
,
48 uint32_t aCount
, uint32_t* _retval
);
49 nsresult
IsNonBlocking(bool* aNonBlocking
);
51 nsresult
StreamStatus();
52 nsresult
Write(const char* aBuf
, uint32_t aCount
, uint32_t* result
);
53 nsresult
WriteFrom(nsIInputStream
* aFromStream
, uint32_t aCount
,
55 nsresult
WriteSegments(nsReadSegmentFun aReader
, void* aClosure
,
56 uint32_t aCount
, uint32_t* _retval
);
58 PRFileDesc
* mFD
{nullptr};
61 * Flags describing our behavior. See the IDL file for possible values.
63 int32_t mBehaviorFlags
{0};
66 // This is the default value. It will be changed by Deserialize or Init.
68 // The opening has been deferred. See DEFER_OPEN.
70 // The file has been opened. mFD is not null.
72 // The file has been closed. mFD is null.
74 // Something bad happen in the Open() or in Deserialize(). The actual
75 // error value is stored in mErrorValue.
77 } mState
{eUnitialized
};
80 nsCOMPtr
<nsIFile
> localFile
;
86 * Data we need to do an open.
88 OpenParams mOpenParams
;
90 nsresult mErrorValue
{NS_ERROR_FAILURE
};
93 * Prepares the data we need to open the file, and either does the open now
94 * by calling DoOpen(), or leaves it to be opened later by a call to
97 nsresult
MaybeOpen(nsIFile
* aFile
, int32_t aIoFlags
, int32_t aPerm
,
101 * Cleans up data prepared in MaybeOpen.
106 * Open the file. This is called either from MaybeOpen (during Init)
107 * or from DoPendingOpen (if DEFER_OPEN is used when initializing this
108 * stream). The default behavior of DoOpen is to open the file and save the
111 virtual nsresult
DoOpen();
114 * Based on mState, this method does the opening, return an error, or do
115 * nothing. If the return value is not NS_OK, please, return it back to the
118 inline nsresult
DoPendingOpen();
121 ////////////////////////////////////////////////////////////////////////////////
123 // nsFileInputStream is cloneable only on the parent process because only there
124 // it can open the same file multiple times.
126 class nsFileInputStream
: public nsFileStreamBase
,
127 public nsIFileInputStream
,
128 public nsILineInputStream
,
129 public nsIIPCSerializableInputStream
,
130 public nsICloneableInputStream
{
132 NS_DECL_ISUPPORTS_INHERITED
133 NS_DECL_NSIFILEINPUTSTREAM
134 NS_DECL_NSILINEINPUTSTREAM
135 NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
136 NS_DECL_NSICLONEABLEINPUTSTREAM
138 NS_IMETHOD
Close() override
;
139 NS_IMETHOD
Tell(int64_t* aResult
) override
;
140 NS_IMETHOD
Available(uint64_t* _retval
) override
;
141 NS_IMETHOD
StreamStatus() override
;
142 NS_IMETHOD
Read(char* aBuf
, uint32_t aCount
, uint32_t* _retval
) override
;
143 NS_IMETHOD
ReadSegments(nsWriteSegmentFun aWriter
, void* aClosure
,
144 uint32_t aCount
, uint32_t* _retval
) override
{
145 return nsFileStreamBase::ReadSegments(aWriter
, aClosure
, aCount
, _retval
);
147 NS_IMETHOD
IsNonBlocking(bool* _retval
) override
{
148 return nsFileStreamBase::IsNonBlocking(_retval
);
151 // Overrided from nsFileStreamBase
152 NS_IMETHOD
Seek(int32_t aWhence
, int64_t aOffset
) override
;
154 nsFileInputStream() : mLineBuffer(nullptr) {}
156 static nsresult
Create(REFNSIID aIID
, void** aResult
);
159 virtual ~nsFileInputStream() = default;
161 nsresult
SeekInternal(int32_t aWhence
, int64_t aOffset
,
162 bool aClearBuf
= true);
164 mozilla::UniquePtr
<nsLineBuffer
<char>> mLineBuffer
;
167 * The file being opened.
169 nsCOMPtr
<nsIFile
> mFile
;
171 * The IO flags passed to Init() for the file open.
175 * The permissions passed to Init() for the file open.
180 * Cached position for Tell for automatically reopening streams.
182 int64_t mCachedPosition
{0};
186 * Internal, called to open a file. Parameters are the same as their
189 nsresult
Open(nsIFile
* file
, int32_t ioFlags
, int32_t perm
);
191 bool IsCloneable() const;
194 ////////////////////////////////////////////////////////////////////////////////
196 class nsFileOutputStream
: public nsFileStreamBase
, public nsIFileOutputStream
{
198 NS_DECL_ISUPPORTS_INHERITED
199 NS_DECL_NSIFILEOUTPUTSTREAM
200 NS_FORWARD_NSIOUTPUTSTREAM(nsFileStreamBase::)
202 static nsresult
Create(REFNSIID aIID
, void** aResult
);
203 nsresult
InitWithFileDescriptor(const mozilla::ipc::FileDescriptor
& aFd
);
206 virtual ~nsFileOutputStream() = default;
209 ////////////////////////////////////////////////////////////////////////////////
212 * A safe file output stream that overwrites the destination file only
213 * once writing is complete. This protects against incomplete writes
214 * due to the process or the thread being interrupted or crashed.
216 class nsAtomicFileOutputStream
: public nsFileOutputStream
,
217 public nsISafeOutputStream
{
219 NS_DECL_ISUPPORTS_INHERITED
220 NS_DECL_NSISAFEOUTPUTSTREAM
222 nsAtomicFileOutputStream() = default;
224 virtual nsresult
DoOpen() override
;
226 NS_IMETHOD
Close() override
;
227 NS_IMETHOD
Write(const char* buf
, uint32_t count
, uint32_t* result
) override
;
228 NS_IMETHOD
Init(nsIFile
* file
, int32_t ioFlags
, int32_t perm
,
229 int32_t behaviorFlags
) override
;
232 virtual ~nsAtomicFileOutputStream() = default;
234 nsCOMPtr
<nsIFile
> mTargetFile
;
235 nsCOMPtr
<nsIFile
> mTempFile
;
237 bool mTargetFileExists
{true};
238 nsresult mWriteResult
{NS_OK
}; // Internally set in Write()
241 ////////////////////////////////////////////////////////////////////////////////
244 * A safe file output stream that overwrites the destination file only
245 * once writing + flushing is complete. This protects against more
246 * classes of software/hardware errors than nsAtomicFileOutputStream,
247 * at the expense of being more costly to the disk, OS and battery.
249 class nsSafeFileOutputStream
: public nsAtomicFileOutputStream
{
251 NS_IMETHOD
Finish() override
;
254 ////////////////////////////////////////////////////////////////////////////////
256 class nsFileRandomAccessStream
: public nsFileStreamBase
,
257 public nsIFileRandomAccessStream
,
258 public nsIInputStream
,
259 public nsIOutputStream
{
261 static nsresult
Create(REFNSIID aIID
, void** aResult
);
263 NS_DECL_ISUPPORTS_INHERITED
264 NS_FORWARD_NSITELLABLESTREAM(nsFileStreamBase::)
265 NS_FORWARD_NSISEEKABLESTREAM(nsFileStreamBase::)
266 NS_DECL_NSIRANDOMACCESSSTREAM
267 NS_DECL_NSIFILERANDOMACCESSSTREAM
268 NS_FORWARD_NSIINPUTSTREAM(nsFileStreamBase::)
270 // Can't use NS_FORWARD_NSIOUTPUTSTREAM due to overlapping methods
271 // Close() and IsNonBlocking()
272 NS_IMETHOD
Flush() override
{ return nsFileStreamBase::Flush(); }
273 NS_IMETHOD
Write(const char* aBuf
, uint32_t aCount
,
274 uint32_t* _retval
) override
{
275 return nsFileStreamBase::Write(aBuf
, aCount
, _retval
);
277 NS_IMETHOD
WriteFrom(nsIInputStream
* aFromStream
, uint32_t aCount
,
278 uint32_t* _retval
) override
{
279 return nsFileStreamBase::WriteFrom(aFromStream
, aCount
, _retval
);
281 NS_IMETHOD
WriteSegments(nsReadSegmentFun aReader
, void* aClosure
,
282 uint32_t aCount
, uint32_t* _retval
) override
{
283 return nsFileStreamBase::WriteSegments(aReader
, aClosure
, aCount
, _retval
);
287 virtual ~nsFileRandomAccessStream() = default;
290 ////////////////////////////////////////////////////////////////////////////////
292 #endif // nsFileStreams_h__