Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : *
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 : #ifndef _nsCacheEntryDescriptor_h_
9 : #define _nsCacheEntryDescriptor_h_
10 :
11 : #include "nsICacheEntryDescriptor.h"
12 : #include "nsCacheEntry.h"
13 : #include "nsIInputStream.h"
14 : #include "nsIOutputStream.h"
15 : #include "nsCacheService.h"
16 : #include "zlib.h"
17 : #include "mozilla/Mutex.h"
18 :
19 : /******************************************************************************
20 : * nsCacheEntryDescriptor
21 : *******************************************************************************/
22 : class nsCacheEntryDescriptor final :
23 : public PRCList,
24 : public nsICacheEntryDescriptor
25 : {
26 : public:
27 : NS_DECL_THREADSAFE_ISUPPORTS
28 : NS_DECL_NSICACHEENTRYDESCRIPTOR
29 : NS_DECL_NSICACHEENTRYINFO
30 :
31 : friend class nsAsyncDoomEvent;
32 : friend class nsCacheService;
33 :
34 : nsCacheEntryDescriptor(nsCacheEntry * entry, nsCacheAccessMode mode);
35 :
36 : /**
37 : * utility method to attempt changing data size of associated entry
38 : */
39 : nsresult RequestDataSizeChange(int32_t deltaSize);
40 :
41 : /**
42 : * methods callbacks for nsCacheService
43 : */
44 0 : nsCacheEntry * CacheEntry(void) { return mCacheEntry; }
45 0 : bool ClearCacheEntry(void)
46 : {
47 0 : NS_ASSERTION(mInputWrappers.IsEmpty(), "Bad state");
48 0 : NS_ASSERTION(!mOutputWrapper, "Bad state");
49 :
50 0 : bool doomEntry = false;
51 : bool asyncDoomPending;
52 : {
53 0 : mozilla::MutexAutoLock lock(mLock);
54 0 : asyncDoomPending = mAsyncDoomPending;
55 : }
56 :
57 0 : if (asyncDoomPending && mCacheEntry) {
58 0 : doomEntry = true;
59 0 : mDoomedOnClose = true;
60 : }
61 0 : mCacheEntry = nullptr;
62 :
63 0 : return doomEntry;
64 : }
65 :
66 : private:
67 : virtual ~nsCacheEntryDescriptor();
68 :
69 : /*************************************************************************
70 : * input stream wrapper class -
71 : *
72 : * The input stream wrapper references the descriptor, but the descriptor
73 : * doesn't need any references to the stream wrapper.
74 : *************************************************************************/
75 : class nsInputStreamWrapper : public nsIInputStream {
76 : friend class nsCacheEntryDescriptor;
77 :
78 : private:
79 : nsCacheEntryDescriptor * mDescriptor;
80 : nsCOMPtr<nsIInputStream> mInput;
81 : uint32_t mStartOffset;
82 : bool mInitialized;
83 : mozilla::Mutex mLock;
84 : public:
85 : NS_DECL_THREADSAFE_ISUPPORTS
86 : NS_DECL_NSIINPUTSTREAM
87 :
88 0 : nsInputStreamWrapper(nsCacheEntryDescriptor * desc, uint32_t off)
89 0 : : mDescriptor(desc)
90 : , mStartOffset(off)
91 : , mInitialized(false)
92 0 : , mLock("nsInputStreamWrapper.mLock")
93 : {
94 0 : NS_ADDREF(mDescriptor);
95 0 : }
96 :
97 : private:
98 0 : virtual ~nsInputStreamWrapper()
99 0 : {
100 0 : NS_IF_RELEASE(mDescriptor);
101 0 : }
102 :
103 : nsresult LazyInit();
104 : nsresult EnsureInit();
105 : nsresult Read_Locked(char *buf, uint32_t count, uint32_t *countRead);
106 : nsresult Close_Locked();
107 : void CloseInternal();
108 : };
109 :
110 :
111 : class nsDecompressInputStreamWrapper : public nsInputStreamWrapper {
112 : private:
113 : unsigned char* mReadBuffer;
114 : uint32_t mReadBufferLen;
115 : z_stream mZstream;
116 : bool mStreamInitialized;
117 : bool mStreamEnded;
118 : public:
119 : NS_DECL_ISUPPORTS_INHERITED
120 :
121 0 : nsDecompressInputStreamWrapper(nsCacheEntryDescriptor * desc,
122 : uint32_t off)
123 0 : : nsInputStreamWrapper(desc, off)
124 : , mReadBuffer(0)
125 : , mReadBufferLen(0)
126 : , mStreamInitialized(false)
127 0 : , mStreamEnded(false)
128 : {
129 0 : }
130 : NS_IMETHOD Read(char* buf, uint32_t count, uint32_t * result) override;
131 : NS_IMETHOD Close() override;
132 : private:
133 0 : virtual ~nsDecompressInputStreamWrapper()
134 0 : {
135 0 : Close();
136 0 : }
137 : nsresult InitZstream();
138 : nsresult EndZstream();
139 : };
140 :
141 :
142 : /*************************************************************************
143 : * output stream wrapper class -
144 : *
145 : * The output stream wrapper references the descriptor, but the descriptor
146 : * doesn't need any references to the stream wrapper.
147 : *************************************************************************/
148 : class nsOutputStreamWrapper : public nsIOutputStream {
149 : friend class nsCacheEntryDescriptor;
150 :
151 : protected:
152 : nsCacheEntryDescriptor * mDescriptor;
153 : nsCOMPtr<nsIOutputStream> mOutput;
154 : uint32_t mStartOffset;
155 : bool mInitialized;
156 : mozilla::Mutex mLock;
157 : public:
158 : NS_DECL_THREADSAFE_ISUPPORTS
159 : NS_DECL_NSIOUTPUTSTREAM
160 :
161 0 : nsOutputStreamWrapper(nsCacheEntryDescriptor * desc, uint32_t off)
162 0 : : mDescriptor(desc)
163 : , mStartOffset(off)
164 : , mInitialized(false)
165 0 : , mLock("nsOutputStreamWrapper.mLock")
166 : {
167 0 : NS_ADDREF(mDescriptor); // owning ref
168 0 : }
169 :
170 : private:
171 0 : virtual ~nsOutputStreamWrapper()
172 0 : {
173 0 : Close();
174 :
175 0 : NS_ASSERTION(!mOutput, "Bad state");
176 0 : NS_ASSERTION(!mDescriptor, "Bad state");
177 0 : }
178 :
179 : nsresult LazyInit();
180 : nsresult EnsureInit();
181 : nsresult OnWrite(uint32_t count);
182 : nsresult Write_Locked(const char * buf,
183 : uint32_t count,
184 : uint32_t * result);
185 : nsresult Close_Locked();
186 : void CloseInternal();
187 : };
188 :
189 :
190 : class nsCompressOutputStreamWrapper : public nsOutputStreamWrapper {
191 : private:
192 : unsigned char* mWriteBuffer;
193 : uint32_t mWriteBufferLen;
194 : z_stream mZstream;
195 : bool mStreamInitialized;
196 : bool mStreamEnded;
197 : uint32_t mUncompressedCount;
198 : public:
199 : NS_DECL_ISUPPORTS_INHERITED
200 :
201 0 : nsCompressOutputStreamWrapper(nsCacheEntryDescriptor * desc,
202 : uint32_t off)
203 0 : : nsOutputStreamWrapper(desc, off)
204 : , mWriteBuffer(0)
205 : , mWriteBufferLen(0)
206 : , mStreamInitialized(false)
207 : , mStreamEnded(false)
208 0 : , mUncompressedCount(0)
209 : {
210 0 : }
211 : NS_IMETHOD Write(const char* buf, uint32_t count, uint32_t * result) override;
212 : NS_IMETHOD Close() override;
213 : private:
214 0 : virtual ~nsCompressOutputStreamWrapper()
215 0 : {
216 0 : Close();
217 0 : }
218 : nsresult InitZstream();
219 : nsresult WriteBuffer();
220 : };
221 :
222 : private:
223 : /**
224 : * nsCacheEntryDescriptor data members
225 : */
226 : nsCacheEntry * mCacheEntry; // we are a child of the entry
227 : nsCacheAccessMode mAccessGranted;
228 : nsTArray<nsInputStreamWrapper*> mInputWrappers;
229 : nsOutputStreamWrapper * mOutputWrapper;
230 : mozilla::Mutex mLock;
231 : bool mAsyncDoomPending;
232 : bool mDoomedOnClose;
233 : bool mClosingDescriptor;
234 : };
235 :
236 :
237 : #endif // _nsCacheEntryDescriptor_h_
|