|
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 #ifndef _nsCacheEntry_h_ |
|
8 #define _nsCacheEntry_h_ |
|
9 |
|
10 #include "nsICache.h" |
|
11 #include "nsICacheEntryDescriptor.h" |
|
12 #include "nsIThread.h" |
|
13 #include "nsCacheMetaData.h" |
|
14 |
|
15 #include "nspr.h" |
|
16 #include "pldhash.h" |
|
17 #include "nsAutoPtr.h" |
|
18 #include "nscore.h" |
|
19 #include "nsCOMPtr.h" |
|
20 #include "nsString.h" |
|
21 #include "nsAString.h" |
|
22 |
|
23 class nsCacheDevice; |
|
24 class nsCacheMetaData; |
|
25 class nsCacheRequest; |
|
26 class nsCacheEntryDescriptor; |
|
27 |
|
28 /****************************************************************************** |
|
29 * nsCacheEntry |
|
30 *******************************************************************************/ |
|
31 class nsCacheEntry : public PRCList |
|
32 { |
|
33 public: |
|
34 |
|
35 nsCacheEntry(const nsACString & key, |
|
36 bool streamBased, |
|
37 nsCacheStoragePolicy storagePolicy); |
|
38 ~nsCacheEntry(); |
|
39 |
|
40 |
|
41 static nsresult Create( const char * key, |
|
42 bool streamBased, |
|
43 nsCacheStoragePolicy storagePolicy, |
|
44 nsCacheDevice * device, |
|
45 nsCacheEntry ** result); |
|
46 |
|
47 nsCString * Key() { return &mKey; } |
|
48 |
|
49 int32_t FetchCount() { return mFetchCount; } |
|
50 void SetFetchCount( int32_t count) { mFetchCount = count; } |
|
51 void Fetched(); |
|
52 |
|
53 uint32_t LastFetched() { return mLastFetched; } |
|
54 void SetLastFetched( uint32_t lastFetched) { mLastFetched = lastFetched; } |
|
55 |
|
56 uint32_t LastModified() { return mLastModified; } |
|
57 void SetLastModified( uint32_t lastModified) { mLastModified = lastModified; } |
|
58 |
|
59 uint32_t ExpirationTime() { return mExpirationTime; } |
|
60 void SetExpirationTime( uint32_t expires) { mExpirationTime = expires; } |
|
61 |
|
62 uint32_t Size() |
|
63 { return mDataSize + mMetaData.Size() + mKey.Length() ; } |
|
64 |
|
65 nsCacheDevice * CacheDevice() { return mCacheDevice; } |
|
66 void SetCacheDevice( nsCacheDevice * device) { mCacheDevice = device; } |
|
67 void SetCustomCacheDevice( nsCacheDevice * device ) |
|
68 { mCustomDevice = device; } |
|
69 nsCacheDevice * CustomCacheDevice() { return mCustomDevice; } |
|
70 const char * GetDeviceID(); |
|
71 |
|
72 /** |
|
73 * Data accessors |
|
74 */ |
|
75 nsISupports *Data() { return mData; } |
|
76 void SetData( nsISupports * data); |
|
77 |
|
78 int64_t PredictedDataSize() { return mPredictedDataSize; } |
|
79 void SetPredictedDataSize(int64_t size) { mPredictedDataSize = size; } |
|
80 |
|
81 uint32_t DataSize() { return mDataSize; } |
|
82 void SetDataSize( uint32_t size) { mDataSize = size; } |
|
83 |
|
84 void TouchData(); |
|
85 |
|
86 /** |
|
87 * Meta data accessors |
|
88 */ |
|
89 const char * GetMetaDataElement( const char * key) { return mMetaData.GetElement(key); } |
|
90 nsresult SetMetaDataElement( const char * key, |
|
91 const char * value) { return mMetaData.SetElement(key, value); } |
|
92 nsresult VisitMetaDataElements( nsICacheMetaDataVisitor * visitor) { return mMetaData.VisitElements(visitor); } |
|
93 nsresult FlattenMetaData(char * buffer, uint32_t bufSize) { return mMetaData.FlattenMetaData(buffer, bufSize); } |
|
94 nsresult UnflattenMetaData(const char * buffer, uint32_t bufSize) { return mMetaData.UnflattenMetaData(buffer, bufSize); } |
|
95 uint32_t MetaDataSize() { return mMetaData.Size(); } |
|
96 |
|
97 void TouchMetaData(); |
|
98 |
|
99 |
|
100 /** |
|
101 * Security Info accessors |
|
102 */ |
|
103 nsISupports* SecurityInfo() { return mSecurityInfo; } |
|
104 void SetSecurityInfo( nsISupports * info) { mSecurityInfo = info; } |
|
105 |
|
106 |
|
107 // XXX enumerate MetaData method |
|
108 |
|
109 |
|
110 enum CacheEntryFlags { |
|
111 eStoragePolicyMask = 0x000000FF, |
|
112 eDoomedMask = 0x00000100, |
|
113 eEntryDirtyMask = 0x00000200, |
|
114 eDataDirtyMask = 0x00000400, |
|
115 eMetaDataDirtyMask = 0x00000800, |
|
116 eStreamDataMask = 0x00001000, |
|
117 eActiveMask = 0x00002000, |
|
118 eInitializedMask = 0x00004000, |
|
119 eValidMask = 0x00008000, |
|
120 eBindingMask = 0x00010000, |
|
121 ePrivateMask = 0x00020000 |
|
122 }; |
|
123 |
|
124 void MarkBinding() { mFlags |= eBindingMask; } |
|
125 void ClearBinding() { mFlags &= ~eBindingMask; } |
|
126 bool IsBinding() { return (mFlags & eBindingMask) != 0; } |
|
127 |
|
128 void MarkEntryDirty() { mFlags |= eEntryDirtyMask; } |
|
129 void MarkEntryClean() { mFlags &= ~eEntryDirtyMask; } |
|
130 void MarkDataDirty() { mFlags |= eDataDirtyMask; } |
|
131 void MarkDataClean() { mFlags &= ~eDataDirtyMask; } |
|
132 void MarkMetaDataDirty() { mFlags |= eMetaDataDirtyMask; } |
|
133 void MarkMetaDataClean() { mFlags &= ~eMetaDataDirtyMask; } |
|
134 void MarkStreamData() { mFlags |= eStreamDataMask; } |
|
135 void MarkValid() { mFlags |= eValidMask; } |
|
136 void MarkInvalid() { mFlags &= ~eValidMask; } |
|
137 void MarkPrivate() { mFlags |= ePrivateMask; } |
|
138 void MarkPublic() { mFlags &= ~ePrivateMask; } |
|
139 // void MarkAllowedInMemory() { mFlags |= eAllowedInMemoryMask; } |
|
140 // void MarkAllowedOnDisk() { mFlags |= eAllowedOnDiskMask; } |
|
141 |
|
142 bool IsDoomed() { return (mFlags & eDoomedMask) != 0; } |
|
143 bool IsEntryDirty() { return (mFlags & eEntryDirtyMask) != 0; } |
|
144 bool IsDataDirty() { return (mFlags & eDataDirtyMask) != 0; } |
|
145 bool IsMetaDataDirty() { return (mFlags & eMetaDataDirtyMask) != 0; } |
|
146 bool IsStreamData() { return (mFlags & eStreamDataMask) != 0; } |
|
147 bool IsActive() { return (mFlags & eActiveMask) != 0; } |
|
148 bool IsInitialized() { return (mFlags & eInitializedMask) != 0; } |
|
149 bool IsValid() { return (mFlags & eValidMask) != 0; } |
|
150 bool IsInvalid() { return (mFlags & eValidMask) == 0; } |
|
151 bool IsInUse() { return IsBinding() || |
|
152 !(PR_CLIST_IS_EMPTY(&mRequestQ) && |
|
153 PR_CLIST_IS_EMPTY(&mDescriptorQ)); } |
|
154 bool IsNotInUse() { return !IsInUse(); } |
|
155 bool IsPrivate() { return (mFlags & ePrivateMask) != 0; } |
|
156 |
|
157 |
|
158 bool IsAllowedInMemory() |
|
159 { |
|
160 return (StoragePolicy() == nsICache::STORE_ANYWHERE) || |
|
161 (StoragePolicy() == nsICache::STORE_IN_MEMORY); |
|
162 } |
|
163 |
|
164 bool IsAllowedOnDisk() |
|
165 { |
|
166 return !IsPrivate() && ((StoragePolicy() == nsICache::STORE_ANYWHERE) || |
|
167 (StoragePolicy() == nsICache::STORE_ON_DISK)); |
|
168 } |
|
169 |
|
170 bool IsAllowedOffline() |
|
171 { |
|
172 return (StoragePolicy() == nsICache::STORE_OFFLINE); |
|
173 } |
|
174 |
|
175 nsCacheStoragePolicy StoragePolicy() |
|
176 { |
|
177 return (nsCacheStoragePolicy)(mFlags & eStoragePolicyMask); |
|
178 } |
|
179 |
|
180 void SetStoragePolicy(nsCacheStoragePolicy policy) |
|
181 { |
|
182 NS_ASSERTION(policy <= 0xFF, "too many bits in nsCacheStoragePolicy"); |
|
183 mFlags &= ~eStoragePolicyMask; // clear storage policy bits |
|
184 mFlags |= policy; |
|
185 } |
|
186 |
|
187 |
|
188 // methods for nsCacheService |
|
189 nsresult RequestAccess( nsCacheRequest * request, nsCacheAccessMode *accessGranted); |
|
190 nsresult CreateDescriptor( nsCacheRequest * request, |
|
191 nsCacheAccessMode accessGranted, |
|
192 nsICacheEntryDescriptor ** result); |
|
193 |
|
194 bool RemoveRequest( nsCacheRequest * request); |
|
195 bool RemoveDescriptor( nsCacheEntryDescriptor * descriptor, |
|
196 bool * doomEntry); |
|
197 |
|
198 void GetDescriptors(nsTArray<nsRefPtr<nsCacheEntryDescriptor> > &outDescriptors); |
|
199 |
|
200 private: |
|
201 friend class nsCacheEntryHashTable; |
|
202 friend class nsCacheService; |
|
203 |
|
204 void DetachDescriptors(); |
|
205 |
|
206 // internal methods |
|
207 void MarkDoomed() { mFlags |= eDoomedMask; } |
|
208 void MarkStreamBased() { mFlags |= eStreamDataMask; } |
|
209 void MarkInitialized() { mFlags |= eInitializedMask; } |
|
210 void MarkActive() { mFlags |= eActiveMask; } |
|
211 void MarkInactive() { mFlags &= ~eActiveMask; } |
|
212 |
|
213 nsCString mKey; |
|
214 uint32_t mFetchCount; // 4 |
|
215 uint32_t mLastFetched; // 4 |
|
216 uint32_t mLastModified; // 4 |
|
217 uint32_t mLastValidated; // 4 |
|
218 uint32_t mExpirationTime; // 4 |
|
219 uint32_t mFlags; // 4 |
|
220 int64_t mPredictedDataSize; // Size given by ContentLength. |
|
221 uint32_t mDataSize; // 4 |
|
222 nsCacheDevice * mCacheDevice; // 4 |
|
223 nsCacheDevice * mCustomDevice; // 4 |
|
224 nsCOMPtr<nsISupports> mSecurityInfo; // |
|
225 nsISupports * mData; // strong ref |
|
226 nsCOMPtr<nsIThread> mThread; |
|
227 nsCacheMetaData mMetaData; // 4 |
|
228 PRCList mRequestQ; // 8 |
|
229 PRCList mDescriptorQ; // 8 |
|
230 }; |
|
231 |
|
232 |
|
233 /****************************************************************************** |
|
234 * nsCacheEntryInfo |
|
235 *******************************************************************************/ |
|
236 class nsCacheEntryInfo : public nsICacheEntryInfo { |
|
237 public: |
|
238 NS_DECL_ISUPPORTS |
|
239 NS_DECL_NSICACHEENTRYINFO |
|
240 |
|
241 nsCacheEntryInfo(nsCacheEntry* entry) |
|
242 : mCacheEntry(entry) |
|
243 { |
|
244 } |
|
245 |
|
246 virtual ~nsCacheEntryInfo() {} |
|
247 void DetachEntry() { mCacheEntry = nullptr; } |
|
248 |
|
249 private: |
|
250 nsCacheEntry * mCacheEntry; |
|
251 }; |
|
252 |
|
253 |
|
254 /****************************************************************************** |
|
255 * nsCacheEntryHashTable |
|
256 *******************************************************************************/ |
|
257 typedef struct { |
|
258 PLDHashNumber keyHash; |
|
259 nsCacheEntry *cacheEntry; |
|
260 } nsCacheEntryHashTableEntry; |
|
261 |
|
262 |
|
263 class nsCacheEntryHashTable |
|
264 { |
|
265 public: |
|
266 nsCacheEntryHashTable(); |
|
267 ~nsCacheEntryHashTable(); |
|
268 |
|
269 nsresult Init(); |
|
270 void Shutdown(); |
|
271 |
|
272 nsCacheEntry *GetEntry( const nsCString * key); |
|
273 nsresult AddEntry( nsCacheEntry *entry); |
|
274 void RemoveEntry( nsCacheEntry *entry); |
|
275 |
|
276 void VisitEntries( PLDHashEnumerator etor, void *arg); |
|
277 |
|
278 private: |
|
279 // PLDHashTable operation callbacks |
|
280 static PLDHashNumber HashKey( PLDHashTable *table, const void *key); |
|
281 |
|
282 static bool MatchEntry( PLDHashTable * table, |
|
283 const PLDHashEntryHdr * entry, |
|
284 const void * key); |
|
285 |
|
286 static void MoveEntry( PLDHashTable *table, |
|
287 const PLDHashEntryHdr *from, |
|
288 PLDHashEntryHdr *to); |
|
289 |
|
290 static void ClearEntry( PLDHashTable *table, PLDHashEntryHdr *entry); |
|
291 |
|
292 static void Finalize( PLDHashTable *table); |
|
293 |
|
294 static |
|
295 PLDHashOperator FreeCacheEntries(PLDHashTable * table, |
|
296 PLDHashEntryHdr * hdr, |
|
297 uint32_t number, |
|
298 void * arg); |
|
299 static |
|
300 PLDHashOperator VisitEntry(PLDHashTable * table, |
|
301 PLDHashEntryHdr * hdr, |
|
302 uint32_t number, |
|
303 void * arg); |
|
304 |
|
305 // member variables |
|
306 static const PLDHashTableOps ops; |
|
307 PLDHashTable table; |
|
308 bool initialized; |
|
309 }; |
|
310 |
|
311 #endif // _nsCacheEntry_h_ |