Coverage Report

Created: 2018-09-25 14:53

/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