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 /*
8  * The storage stream provides an internal buffer that can be filled by a
9  * client using a single output stream.  One or more independent input streams
10  * can be created to read the data out non-destructively.  The implementation
11  * uses a segmented buffer internally to avoid realloc'ing of large buffers,
12  * with the attendant performance loss and heap fragmentation.
13  */
14 
15 #ifndef _nsStorageStream_h_
16 #define _nsStorageStream_h_
17 
18 #include "nsIStorageStream.h"
19 #include "nsIOutputStream.h"
20 #include "nsMemory.h"
21 #include "mozilla/Attributes.h"
22 
23 #define NS_STORAGESTREAM_CID                         \
24   { /* 669a9795-6ff7-4ed4-9150-c34ce2971b63 */       \
25     0x669a9795, 0x6ff7, 0x4ed4, {                    \
26       0x91, 0x50, 0xc3, 0x4c, 0xe2, 0x97, 0x1b, 0x63 \
27     }                                                \
28   }
29 
30 #define NS_STORAGESTREAM_CONTRACTID "@mozilla.org/storagestream;1"
31 
32 class nsSegmentedBuffer;
33 
34 class nsStorageStream final : public nsIStorageStream, public nsIOutputStream {
35  public:
36   nsStorageStream();
37 
38   NS_DECL_THREADSAFE_ISUPPORTS
39   NS_DECL_NSISTORAGESTREAM
40   NS_DECL_NSIOUTPUTSTREAM
41 
42   friend class nsStorageInputStream;
43 
44  private:
45   ~nsStorageStream();
46 
47   nsSegmentedBuffer* mSegmentedBuffer;
48   uint32_t
49       mSegmentSize;  // All segments, except possibly the last, are of this size
50                      //   Must be power-of-2
51   uint32_t mSegmentSizeLog2;  // log2(mSegmentSize)
52   bool mWriteInProgress;      // true, if an un-Close'ed output stream exists
53   int32_t mLastSegmentNum;    // Last segment # in use, -1 initially
54   char* mWriteCursor;         // Pointer to next byte to be written
55   char* mSegmentEnd;          // Pointer to one byte after end of segment
56                               //   containing the write cursor
57   uint32_t mLogicalLength;    // Number of bytes written to stream
58 
59   nsresult Seek(int32_t aPosition);
SegNum(uint32_t aPosition)60   uint32_t SegNum(uint32_t aPosition) { return aPosition >> mSegmentSizeLog2; }
SegOffset(uint32_t aPosition)61   uint32_t SegOffset(uint32_t aPosition) {
62     return aPosition & (mSegmentSize - 1);
63   }
64 };
65 
66 #endif  //  _nsStorageStream_h_
67