tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsBufferedStreams.h (5873B)


      1 /* -*- Mode: C++; tab-width: 2; 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/. */
      5 
      6 #ifndef nsBufferedStreams_h__
      7 #define nsBufferedStreams_h__
      8 
      9 #include "nsIBufferedStreams.h"
     10 #include "nsIInputStream.h"
     11 #include "nsIOutputStream.h"
     12 #include "nsISafeOutputStream.h"
     13 #include "nsISeekableStream.h"
     14 #include "nsIStreamBufferAccess.h"
     15 #include "nsCOMPtr.h"
     16 #include "nsIIPCSerializableInputStream.h"
     17 #include "nsIAsyncInputStream.h"
     18 #include "nsICloneableInputStream.h"
     19 #include "nsIInputStreamLength.h"
     20 #include "mozilla/Mutex.h"
     21 #include "mozilla/RecursiveMutex.h"
     22 
     23 ////////////////////////////////////////////////////////////////////////////////
     24 
     25 class nsBufferedStream : public nsISeekableStream {
     26 public:
     27  NS_DECL_THREADSAFE_ISUPPORTS
     28  NS_DECL_NSISEEKABLESTREAM
     29  NS_DECL_NSITELLABLESTREAM
     30 
     31  nsBufferedStream() = default;
     32 
     33  void Close();
     34 
     35 protected:
     36  virtual ~nsBufferedStream();
     37 
     38  nsresult Init(nsISupports* stream, uint32_t bufferSize);
     39  nsresult GetData(nsISupports** aResult);
     40  NS_IMETHOD Fill() = 0;
     41  NS_IMETHOD Flush() = 0;
     42 
     43  uint32_t mBufferSize{0};
     44  char* mBuffer MOZ_GUARDED_BY(mBufferMutex){nullptr};
     45 
     46  mozilla::RecursiveMutex mBufferMutex{"nsBufferedStream::mBufferMutex"};
     47 
     48  // mBufferStartOffset is the offset relative to the start of mStream.
     49  int64_t mBufferStartOffset{0};
     50 
     51  // mCursor is the read cursor for input streams, or write cursor for
     52  // output streams, and is relative to mBufferStartOffset.
     53  uint32_t mCursor{0};
     54 
     55  // mFillPoint is the amount available in the buffer for input streams,
     56  // or the high watermark of bytes written into the buffer, and therefore
     57  // is relative to mBufferStartOffset.
     58  uint32_t mFillPoint{0};
     59 
     60  nsCOMPtr<nsISupports> mStream;  // cast to appropriate subclass
     61 
     62  bool mBufferDisabled{false};
     63  bool mEOF{false};  // True if mStream is at EOF
     64  bool mSeekable{true};
     65  uint8_t mGetBufferCount{0};
     66 };
     67 
     68 ////////////////////////////////////////////////////////////////////////////////
     69 
     70 class nsBufferedInputStream final : public nsBufferedStream,
     71                                    public nsIBufferedInputStream,
     72                                    public nsIStreamBufferAccess,
     73                                    public nsIIPCSerializableInputStream,
     74                                    public nsIAsyncInputStream,
     75                                    public nsIInputStreamCallback,
     76                                    public nsICloneableInputStream,
     77                                    public nsIInputStreamLength,
     78                                    public nsIAsyncInputStreamLength,
     79                                    public nsIInputStreamLengthCallback {
     80 public:
     81  NS_DECL_ISUPPORTS_INHERITED
     82  NS_DECL_NSIINPUTSTREAM
     83  NS_DECL_NSIBUFFEREDINPUTSTREAM
     84  NS_DECL_NSISTREAMBUFFERACCESS
     85  NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
     86  NS_DECL_NSIASYNCINPUTSTREAM
     87  NS_DECL_NSIINPUTSTREAMCALLBACK
     88  NS_DECL_NSICLONEABLEINPUTSTREAM
     89  NS_DECL_NSIINPUTSTREAMLENGTH
     90  NS_DECL_NSIASYNCINPUTSTREAMLENGTH
     91  NS_DECL_NSIINPUTSTREAMLENGTHCALLBACK
     92 
     93  nsBufferedInputStream() = default;
     94 
     95  static nsresult Create(REFNSIID aIID, void** aResult);
     96 
     97  nsIInputStream* Source() { return (nsIInputStream*)mStream.get(); }
     98 
     99  /**
    100   * If there's a reference/pointer to an nsBufferedInputStream BEFORE calling
    101   * Init() AND the intent is to ultimately convert/assign that
    102   * reference/pointer to an nsIInputStream, DO NOT use that initial
    103   * reference/pointer. Instead, use the value of QueryInterface-ing to an
    104   * nsIInputStream (and, again, the QueryInterface must be performed after
    105   * Init()). This is because nsBufferedInputStream has multiple underlying
    106   * nsIInputStreams (one from nsIBufferedInputStream and one from
    107   * nsIAsyncInputStream), and the correct base nsIInputStream to use will be
    108   * unknown until the final value of mIsAsyncInputStream is set in Init().
    109   *
    110   * This method, however, does just that but also hides the QI details and
    111   * will assert if called before Init().
    112   */
    113  already_AddRefed<nsIInputStream> GetInputStream();
    114 
    115 protected:
    116  virtual ~nsBufferedInputStream() = default;
    117 
    118  NS_IMETHOD Fill() override;
    119  NS_IMETHOD Flush() override { return NS_OK; }  // no-op for input streams
    120 
    121  mozilla::Mutex mMutex MOZ_UNANNOTATED{"nsBufferedInputStream::mMutex"};
    122 
    123  // This value is protected by mutex.
    124  nsCOMPtr<nsIInputStreamCallback> mAsyncWaitCallback;
    125 
    126  // This value is protected by mutex.
    127  nsCOMPtr<nsIInputStreamLengthCallback> mAsyncInputStreamLengthCallback;
    128 
    129  bool mIsIPCSerializable{true};
    130  bool mIsAsyncInputStream{false};
    131  bool mIsCloneableInputStream{false};
    132  bool mIsInputStreamLength{false};
    133  bool mIsAsyncInputStreamLength{false};
    134 };
    135 
    136 ////////////////////////////////////////////////////////////////////////////////
    137 
    138 class nsBufferedOutputStream : public nsBufferedStream,
    139                               public nsISafeOutputStream,
    140                               public nsIBufferedOutputStream,
    141                               public nsIStreamBufferAccess {
    142 public:
    143  NS_DECL_ISUPPORTS_INHERITED
    144  NS_DECL_NSIOUTPUTSTREAM
    145  NS_DECL_NSISAFEOUTPUTSTREAM
    146  NS_DECL_NSIBUFFEREDOUTPUTSTREAM
    147  NS_DECL_NSISTREAMBUFFERACCESS
    148 
    149  nsBufferedOutputStream() = default;
    150 
    151  static nsresult Create(REFNSIID aIID, void** aResult);
    152 
    153  nsIOutputStream* Sink() { return (nsIOutputStream*)mStream.get(); }
    154 
    155 protected:
    156  virtual ~nsBufferedOutputStream() { nsBufferedOutputStream::Close(); }
    157 
    158  NS_IMETHOD Fill() override { return NS_OK; }  // no-op for output streams
    159 
    160  nsCOMPtr<nsISafeOutputStream> mSafeStream;  // QI'd from mStream
    161 };
    162 
    163 ////////////////////////////////////////////////////////////////////////////////
    164 
    165 #endif  // nsBufferedStreams_h__