/src/mozilla-central/netwerk/cache2/CacheFileMetadata.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #ifndef CacheFileMetadata__h__ |
6 | | #define CacheFileMetadata__h__ |
7 | | |
8 | | #include "CacheFileIOManager.h" |
9 | | #include "CacheStorageService.h" |
10 | | #include "CacheHashUtils.h" |
11 | | #include "CacheObserver.h" |
12 | | #include "mozilla/EndianUtils.h" |
13 | | #include "mozilla/BasePrincipal.h" |
14 | | #include "nsAutoPtr.h" |
15 | | #include "nsString.h" |
16 | | |
17 | | class nsICacheEntryMetaDataVisitor; |
18 | | |
19 | | namespace mozilla { |
20 | | namespace net { |
21 | | |
22 | | // Flags stored in CacheFileMetadataHeader.mFlags |
23 | | |
24 | | // Whether an entry is a pinned entry (created with |
25 | | // nsICacheStorageService.pinningCacheStorage.) |
26 | | static const uint32_t kCacheEntryIsPinned = 1 << 0; |
27 | | |
28 | | // By multiplying with the current half-life we convert the frecency |
29 | | // to time independent of half-life value. The range fits 32bits. |
30 | | // When decay time changes on next run of the browser, we convert |
31 | | // the frecency value to a correct internal representation again. |
32 | | // It might not be 100% accurate, but for the purpose it suffice. |
33 | | #define FRECENCY2INT(aFrecency) \ |
34 | 0 | ((uint32_t)((aFrecency) * CacheObserver::HalfLifeSeconds())) |
35 | | #define INT2FRECENCY(aInt) \ |
36 | 0 | ((double)(aInt) / (double)CacheObserver::HalfLifeSeconds()) |
37 | | |
38 | | |
39 | 0 | #define kCacheEntryVersion 3 |
40 | | |
41 | | |
42 | | #pragma pack(push) |
43 | | #pragma pack(1) |
44 | | |
45 | | class CacheFileMetadataHeader { |
46 | | public: |
47 | | uint32_t mVersion; |
48 | | uint32_t mFetchCount; |
49 | | uint32_t mLastFetched; |
50 | | uint32_t mLastModified; |
51 | | uint32_t mFrecency; |
52 | | uint32_t mExpirationTime; |
53 | | uint32_t mKeySize; |
54 | | uint32_t mFlags; |
55 | | |
56 | | void WriteToBuf(void *aBuf) |
57 | 0 | { |
58 | 0 | EnsureCorrectClassSize(); |
59 | 0 |
|
60 | 0 | uint8_t* ptr = static_cast<uint8_t*>(aBuf); |
61 | 0 | MOZ_ASSERT(mVersion == kCacheEntryVersion); |
62 | 0 | NetworkEndian::writeUint32(ptr, mVersion); ptr += sizeof(uint32_t); |
63 | 0 | NetworkEndian::writeUint32(ptr, mFetchCount); ptr += sizeof(uint32_t); |
64 | 0 | NetworkEndian::writeUint32(ptr, mLastFetched); ptr += sizeof(uint32_t); |
65 | 0 | NetworkEndian::writeUint32(ptr, mLastModified); ptr += sizeof(uint32_t); |
66 | 0 | NetworkEndian::writeUint32(ptr, mFrecency); ptr += sizeof(uint32_t); |
67 | 0 | NetworkEndian::writeUint32(ptr, mExpirationTime); ptr += sizeof(uint32_t); |
68 | 0 | NetworkEndian::writeUint32(ptr, mKeySize); ptr += sizeof(uint32_t); |
69 | 0 | NetworkEndian::writeUint32(ptr, mFlags); |
70 | 0 | } |
71 | | |
72 | | void ReadFromBuf(const void *aBuf) |
73 | 0 | { |
74 | 0 | EnsureCorrectClassSize(); |
75 | 0 |
|
76 | 0 | const uint8_t* ptr = static_cast<const uint8_t*>(aBuf); |
77 | 0 | mVersion = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
78 | 0 | mFetchCount = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
79 | 0 | mLastFetched = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
80 | 0 | mLastModified = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
81 | 0 | mFrecency = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
82 | 0 | mExpirationTime = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
83 | 0 | mKeySize = BigEndian::readUint32(ptr); ptr += sizeof(uint32_t); |
84 | 0 | if (mVersion >= 2) { |
85 | 0 | mFlags = BigEndian::readUint32(ptr); |
86 | 0 | } else { |
87 | 0 | mFlags = 0; |
88 | 0 | } |
89 | 0 | } |
90 | | |
91 | | inline void EnsureCorrectClassSize() |
92 | 0 | { |
93 | 0 | static_assert((sizeof(mVersion) + sizeof(mFetchCount) + |
94 | 0 | sizeof(mLastFetched) + sizeof(mLastModified) + sizeof(mFrecency) + |
95 | 0 | sizeof(mExpirationTime) + sizeof(mKeySize)) + sizeof(mFlags) == |
96 | 0 | sizeof(CacheFileMetadataHeader), |
97 | 0 | "Unexpected sizeof(CacheFileMetadataHeader)!"); |
98 | 0 | } |
99 | | }; |
100 | | |
101 | | #pragma pack(pop) |
102 | | |
103 | | |
104 | | #define CACHEFILEMETADATALISTENER_IID \ |
105 | | { /* a9e36125-3f01-4020-9540-9dafa8d31ba7 */ \ |
106 | | 0xa9e36125, \ |
107 | | 0x3f01, \ |
108 | | 0x4020, \ |
109 | | {0x95, 0x40, 0x9d, 0xaf, 0xa8, 0xd3, 0x1b, 0xa7} \ |
110 | | } |
111 | | |
112 | | class CacheFileMetadataListener : public nsISupports |
113 | | { |
114 | | public: |
115 | | NS_DECLARE_STATIC_IID_ACCESSOR(CACHEFILEMETADATALISTENER_IID) |
116 | | |
117 | | NS_IMETHOD OnMetadataRead(nsresult aResult) = 0; |
118 | | NS_IMETHOD OnMetadataWritten(nsresult aResult) = 0; |
119 | | virtual bool IsKilled() = 0; |
120 | | }; |
121 | | |
122 | | NS_DEFINE_STATIC_IID_ACCESSOR(CacheFileMetadataListener, |
123 | | CACHEFILEMETADATALISTENER_IID) |
124 | | |
125 | | |
126 | | class CacheFileMetadata final |
127 | | : public CacheFileIOListener |
128 | | , public CacheMemoryConsumer |
129 | | { |
130 | | public: |
131 | | NS_DECL_THREADSAFE_ISUPPORTS |
132 | | |
133 | | CacheFileMetadata(CacheFileHandle *aHandle, |
134 | | const nsACString &aKey); |
135 | | CacheFileMetadata(bool aMemoryOnly, |
136 | | bool aPinned, |
137 | | const nsACString &aKey); |
138 | | CacheFileMetadata(); |
139 | | |
140 | | void SetHandle(CacheFileHandle *aHandle); |
141 | | |
142 | | nsresult GetKey(nsACString &_retval); |
143 | | |
144 | | nsresult ReadMetadata(CacheFileMetadataListener *aListener); |
145 | | uint32_t CalcMetadataSize(uint32_t aElementsSize, uint32_t aHashCount); |
146 | | nsresult WriteMetadata(uint32_t aOffset, |
147 | | CacheFileMetadataListener *aListener); |
148 | | nsresult SyncReadMetadata(nsIFile *aFile); |
149 | | |
150 | 0 | bool IsAnonymous() const { return mAnonymous; } |
151 | 0 | mozilla::OriginAttributes const & OriginAttributes() const { return mOriginAttributes; } |
152 | 0 | bool Pinned() const { return !!(mMetaHdr.mFlags & kCacheEntryIsPinned); } |
153 | | |
154 | | const char * GetElement(const char *aKey); |
155 | | nsresult SetElement(const char *aKey, const char *aValue); |
156 | | nsresult Visit(nsICacheEntryMetaDataVisitor *aVisitor); |
157 | | |
158 | | CacheHash::Hash16_t GetHash(uint32_t aIndex); |
159 | | nsresult SetHash(uint32_t aIndex, CacheHash::Hash16_t aHash); |
160 | | nsresult RemoveHash(uint32_t aIndex); |
161 | | |
162 | | nsresult AddFlags(uint32_t aFlags); |
163 | | nsresult RemoveFlags(uint32_t aFlags); |
164 | | nsresult GetFlags(uint32_t *_retval); |
165 | | nsresult SetExpirationTime(uint32_t aExpirationTime); |
166 | | nsresult GetExpirationTime(uint32_t *_retval); |
167 | | nsresult SetFrecency(uint32_t aFrecency); |
168 | | nsresult GetFrecency(uint32_t *_retval); |
169 | | nsresult GetLastModified(uint32_t *_retval); |
170 | | nsresult GetLastFetched(uint32_t *_retval); |
171 | | nsresult GetFetchCount(uint32_t *_retval); |
172 | | // Called by upper layers to indicate the entry this metadata belongs |
173 | | // with has been fetched, i.e. delivered to the consumer. |
174 | | nsresult OnFetched(); |
175 | | |
176 | 0 | int64_t Offset() { return mOffset; } |
177 | 0 | uint32_t ElementsSize() { return mElementsSize; } |
178 | | void MarkDirty(bool aUpdateLastModified = true); |
179 | 0 | bool IsDirty() { return mIsDirty; } |
180 | 0 | uint32_t MemoryUsage() { return sizeof(CacheFileMetadata) + mHashArraySize + mBufSize; } |
181 | | |
182 | | NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) override; |
183 | | NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, |
184 | | nsresult aResult) override; |
185 | | NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) override; |
186 | | NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult) override; |
187 | | NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) override; |
188 | | NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) override; |
189 | 0 | virtual bool IsKilled() override { return mListener && mListener->IsKilled(); } |
190 | | void InitEmptyMetadata(); |
191 | | |
192 | | // Memory reporting |
193 | | size_t SizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const; |
194 | | size_t SizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf) const; |
195 | | |
196 | | private: |
197 | | virtual ~CacheFileMetadata(); |
198 | | |
199 | | nsresult ParseMetadata(uint32_t aMetaOffset, uint32_t aBufOffset, bool aHaveKey); |
200 | | nsresult CheckElements(const char *aBuf, uint32_t aSize); |
201 | | nsresult EnsureBuffer(uint32_t aSize); |
202 | | nsresult ParseKey(const nsACString &aKey); |
203 | | |
204 | | RefPtr<CacheFileHandle> mHandle; |
205 | | nsCString mKey; |
206 | | CacheHash::Hash16_t *mHashArray; |
207 | | uint32_t mHashArraySize; |
208 | | uint32_t mHashCount; |
209 | | int64_t mOffset; |
210 | | char *mBuf; // used for parsing, then points |
211 | | // to elements |
212 | | uint32_t mBufSize; |
213 | | char *mWriteBuf; |
214 | | CacheFileMetadataHeader mMetaHdr; |
215 | | uint32_t mElementsSize; |
216 | | bool mIsDirty : 1; |
217 | | bool mAnonymous : 1; |
218 | | bool mAllocExactSize : 1; |
219 | | bool mFirstRead : 1; |
220 | | mozilla::OriginAttributes mOriginAttributes; |
221 | | mozilla::TimeStamp mReadStart; |
222 | | nsCOMPtr<CacheFileMetadataListener> mListener; |
223 | | }; |
224 | | |
225 | | |
226 | | } // namespace net |
227 | | } // namespace mozilla |
228 | | |
229 | | #endif |