netwerk/base/src/nsFileStreams.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     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 "nsAutoPtr.h"
    10 #include "nsIFileStreams.h"
    11 #include "nsIFile.h"
    12 #include "nsIInputStream.h"
    13 #include "nsIOutputStream.h"
    14 #include "nsISafeOutputStream.h"
    15 #include "nsISeekableStream.h"
    16 #include "nsILineInputStream.h"
    17 #include "nsCOMPtr.h"
    18 #include "nsIIPCSerializableInputStream.h"
    19 #include "nsReadLine.h"
    20 #include <algorithm>
    23 ////////////////////////////////////////////////////////////////////////////////
    25 class nsFileStreamBase : public nsISeekableStream,
    26                          public nsIFileMetadata
    27 {
    28 public:
    29     NS_DECL_THREADSAFE_ISUPPORTS
    30     NS_DECL_NSISEEKABLESTREAM
    31     NS_DECL_NSIFILEMETADATA
    33     nsFileStreamBase();
    34     virtual ~nsFileStreamBase();
    36 protected:
    37     nsresult Close();
    38     nsresult Available(uint64_t* _retval);
    39     nsresult Read(char* aBuf, uint32_t aCount, uint32_t* _retval);
    40     nsresult ReadSegments(nsWriteSegmentFun aWriter, void* aClosure,
    41                           uint32_t aCount, uint32_t* _retval);
    42     nsresult IsNonBlocking(bool* _retval);
    43     nsresult Flush();
    44     nsresult Write(const char* aBuf, uint32_t aCount, uint32_t* _retval);
    45     nsresult WriteFrom(nsIInputStream* aFromStream, uint32_t aCount,
    46                        uint32_t* _retval);
    47     nsresult WriteSegments(nsReadSegmentFun aReader, void* aClosure,
    48                            uint32_t aCount, uint32_t* _retval);
    50     PRFileDesc* mFD;
    52     /**
    53      * Flags describing our behavior.  See the IDL file for possible values.
    54      */
    55     int32_t mBehaviorFlags;
    57     /**
    58      * Whether we have a pending open (see DEFER_OPEN in the IDL file).
    59      */
    60     bool mDeferredOpen;
    62     struct OpenParams {
    63         nsCOMPtr<nsIFile> localFile;
    64         int32_t ioFlags;
    65         int32_t perm;
    66     };
    68     /**
    69      * Data we need to do an open.
    70      */
    71     OpenParams mOpenParams;
    73     /**
    74      * Prepares the data we need to open the file, and either does the open now
    75      * by calling DoOpen(), or leaves it to be opened later by a call to
    76      * DoPendingOpen().
    77      */
    78     nsresult MaybeOpen(nsIFile* aFile, int32_t aIoFlags, int32_t aPerm,
    79                        bool aDeferred);
    81     /**
    82      * Cleans up data prepared in MaybeOpen.
    83      */
    84     void CleanUpOpen();
    86     /**
    87      * Open the file. This is called either from MaybeOpen (during Init)
    88      * or from DoPendingOpen (if DEFER_OPEN is used when initializing this
    89      * stream). The default behavior of DoOpen is to open the file and save the
    90      * file descriptor.
    91      */
    92     virtual nsresult DoOpen();
    94     /**
    95      * If there is a pending open, do it now. It's important for this to be
    96      * inline since we do it in almost every stream API call.
    97      */
    98     inline nsresult DoPendingOpen();
    99 };
   101 ////////////////////////////////////////////////////////////////////////////////
   103 class nsFileInputStream : public nsFileStreamBase,
   104                           public nsIFileInputStream,
   105                           public nsILineInputStream,
   106                           public nsIIPCSerializableInputStream
   107 {
   108 public:
   109     NS_DECL_ISUPPORTS_INHERITED
   110     NS_DECL_NSIFILEINPUTSTREAM
   111     NS_DECL_NSILINEINPUTSTREAM
   112     NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
   114     NS_IMETHOD Close();
   115     NS_IMETHOD Tell(int64_t *aResult);
   116     NS_IMETHOD Available(uint64_t* _retval);
   117     NS_IMETHOD Read(char* aBuf, uint32_t aCount, uint32_t* _retval);
   118     NS_IMETHOD ReadSegments(nsWriteSegmentFun aWriter, void *aClosure,
   119                             uint32_t aCount, uint32_t* _retval)
   120     {
   121         return nsFileStreamBase::ReadSegments(aWriter, aClosure, aCount,
   122                                               _retval);
   123     }
   124     NS_IMETHOD IsNonBlocking(bool* _retval)
   125     {
   126         return nsFileStreamBase::IsNonBlocking(_retval);
   127     }
   129     // Overrided from nsFileStreamBase
   130     NS_IMETHOD Seek(int32_t aWhence, int64_t aOffset);
   132     nsFileInputStream()
   133       : mLineBuffer(nullptr), mIOFlags(0), mPerm(0), mCachedPosition(0)
   134     {}
   136     virtual ~nsFileInputStream()
   137     {
   138         Close();
   139     }
   141     static nsresult
   142     Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
   144 protected:
   145     nsAutoPtr<nsLineBuffer<char> > mLineBuffer;
   147     /**
   148      * The file being opened.
   149      */
   150     nsCOMPtr<nsIFile> mFile;
   151     /**
   152      * The IO flags passed to Init() for the file open.
   153      */
   154     int32_t mIOFlags;
   155     /**
   156      * The permissions passed to Init() for the file open.
   157      */
   158     int32_t mPerm;
   160     /**
   161      * Cached position for Tell for automatically reopening streams.
   162      */
   163     int64_t mCachedPosition;
   165 protected:
   166     /**
   167      * Internal, called to open a file.  Parameters are the same as their
   168      * Init() analogues.
   169      */
   170     nsresult Open(nsIFile* file, int32_t ioFlags, int32_t perm);
   171 };
   173 ////////////////////////////////////////////////////////////////////////////////
   175 class nsPartialFileInputStream : public nsFileInputStream,
   176                                  public nsIPartialFileInputStream
   177 {
   178 public:
   179     using nsFileInputStream::Init;
   180     using nsFileInputStream::Read;
   181     NS_DECL_ISUPPORTS_INHERITED
   182     NS_DECL_NSIPARTIALFILEINPUTSTREAM
   183     NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
   185     nsPartialFileInputStream()
   186       : mStart(0), mLength(0), mPosition(0)
   187     { }
   189     NS_IMETHOD Tell(int64_t *aResult);
   190     NS_IMETHOD Available(uint64_t *aResult);
   191     NS_IMETHOD Read(char* aBuf, uint32_t aCount, uint32_t* aResult);
   192     NS_IMETHOD Seek(int32_t aWhence, int64_t aOffset);
   194     static nsresult
   195     Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
   197 private:
   198     uint64_t TruncateSize(uint64_t aSize) {
   199           return std::min<uint64_t>(mLength - mPosition, aSize);
   200     }
   202     uint64_t mStart;
   203     uint64_t mLength;
   204     uint64_t mPosition;
   205 };
   207 ////////////////////////////////////////////////////////////////////////////////
   209 class nsFileOutputStream : public nsFileStreamBase,
   210                            public nsIFileOutputStream
   211 {
   212 public:
   213     NS_DECL_ISUPPORTS_INHERITED
   214     NS_DECL_NSIFILEOUTPUTSTREAM
   215     NS_FORWARD_NSIOUTPUTSTREAM(nsFileStreamBase::)
   217     virtual ~nsFileOutputStream()
   218     {
   219         Close();
   220     }
   222     static nsresult
   223     Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
   224 };
   226 ////////////////////////////////////////////////////////////////////////////////
   228 /**
   229  * A safe file output stream that overwrites the destination file only
   230  * once writing is complete. This protects against incomplete writes
   231  * due to the process or the thread being interrupted or crashed.
   232  */
   233 class nsAtomicFileOutputStream : public nsFileOutputStream,
   234                                  public nsISafeOutputStream
   235 {
   236 public:
   237     NS_DECL_ISUPPORTS_INHERITED
   238     NS_DECL_NSISAFEOUTPUTSTREAM
   240     nsAtomicFileOutputStream() :
   241         mTargetFileExists(true),
   242         mWriteResult(NS_OK) {}
   244     virtual ~nsAtomicFileOutputStream()
   245     {
   246         Close();
   247     }
   249     virtual nsresult DoOpen() MOZ_OVERRIDE;
   251     NS_IMETHODIMP Close();
   252     NS_IMETHODIMP Write(const char *buf, uint32_t count, uint32_t *result);
   253     NS_IMETHODIMP Init(nsIFile* file, int32_t ioFlags, int32_t perm, int32_t behaviorFlags);
   255 protected:
   256     nsCOMPtr<nsIFile>         mTargetFile;
   257     nsCOMPtr<nsIFile>         mTempFile;
   259     bool     mTargetFileExists;
   260     nsresult mWriteResult; // Internally set in Write()
   262 };
   264 ////////////////////////////////////////////////////////////////////////////////
   266 /**
   267  * A safe file output stream that overwrites the destination file only
   268  * once writing + flushing is complete. This protects against more
   269  * classes of software/hardware errors than nsAtomicFileOutputStream,
   270  * at the expense of being more costly to the disk, OS and battery.
   271  */
   272 class nsSafeFileOutputStream : public nsAtomicFileOutputStream
   273 {
   274 public:
   276     NS_IMETHOD Finish();
   277 };
   279 ////////////////////////////////////////////////////////////////////////////////
   281 class nsFileStream : public nsFileStreamBase,
   282                      public nsIInputStream,
   283                      public nsIOutputStream,
   284                      public nsIFileStream
   285 {
   286 public:
   287     NS_DECL_ISUPPORTS_INHERITED
   288     NS_DECL_NSIFILESTREAM
   289     NS_FORWARD_NSIINPUTSTREAM(nsFileStreamBase::)
   291     // Can't use NS_FORWARD_NSIOUTPUTSTREAM due to overlapping methods
   292     // Close() and IsNonBlocking() 
   293     NS_IMETHOD Flush()
   294     {
   295         return nsFileStreamBase::Flush();
   296     }
   297     NS_IMETHOD Write(const char* aBuf, uint32_t aCount, uint32_t* _retval)
   298     {
   299         return nsFileStreamBase::Write(aBuf, aCount, _retval);
   300     }
   301     NS_IMETHOD WriteFrom(nsIInputStream* aFromStream, uint32_t aCount,
   302                          uint32_t* _retval)
   303     {
   304         return nsFileStreamBase::WriteFrom(aFromStream, aCount, _retval);
   305     }
   306     NS_IMETHOD WriteSegments(nsReadSegmentFun aReader, void* aClosure,
   307                              uint32_t aCount, uint32_t* _retval)
   308     {
   309         return nsFileStreamBase::WriteSegments(aReader, aClosure, aCount,
   310                                                _retval);
   311     }
   313     virtual ~nsFileStream()
   314     {
   315         Close();
   316     }
   317 };
   319 ////////////////////////////////////////////////////////////////////////////////
   321 #endif // nsFileStreams_h__

mercurial