Backed out changeset 177eae915693 (bug 1206581) for bustage
[gecko.git] / image / ImageCacheKey.cpp
blob32037ba94f608c523e4e9f7bdf69c91aa08e02cf
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "ImageCacheKey.h"
8 #include "mozilla/Move.h"
9 #include "File.h"
10 #include "ImageURL.h"
11 #include "nsHostObjectProtocolHandler.h"
12 #include "nsString.h"
14 namespace mozilla {
16 using namespace dom;
18 namespace image {
20 bool
21 URISchemeIs(ImageURL* aURI, const char* aScheme)
23 bool schemeMatches = false;
24 if (NS_WARN_IF(NS_FAILED(aURI->SchemeIs(aScheme, &schemeMatches)))) {
25 return false;
27 return schemeMatches;
30 static Maybe<uint64_t>
31 BlobSerial(ImageURL* aURI)
33 nsAutoCString spec;
34 aURI->GetSpec(spec);
36 RefPtr<BlobImpl> blob;
37 if (NS_SUCCEEDED(NS_GetBlobForBlobURISpec(spec, getter_AddRefs(blob))) &&
38 blob) {
39 return Some(blob->GetSerialNumber());
42 return Nothing();
45 ImageCacheKey::ImageCacheKey(nsIURI* aURI)
46 : mURI(new ImageURL(aURI))
47 , mIsChrome(URISchemeIs(mURI, "chrome"))
49 MOZ_ASSERT(NS_IsMainThread());
51 if (URISchemeIs(mURI, "blob")) {
52 mBlobSerial = BlobSerial(mURI);
55 mHash = ComputeHash(mURI, mBlobSerial);
58 ImageCacheKey::ImageCacheKey(ImageURL* aURI)
59 : mURI(aURI)
60 , mIsChrome(URISchemeIs(mURI, "chrome"))
62 MOZ_ASSERT(aURI);
64 if (URISchemeIs(mURI, "blob")) {
65 mBlobSerial = BlobSerial(mURI);
68 mHash = ComputeHash(mURI, mBlobSerial);
71 ImageCacheKey::ImageCacheKey(const ImageCacheKey& aOther)
72 : mURI(aOther.mURI)
73 , mBlobSerial(aOther.mBlobSerial)
74 , mHash(aOther.mHash)
75 , mIsChrome(aOther.mIsChrome)
76 { }
78 ImageCacheKey::ImageCacheKey(ImageCacheKey&& aOther)
79 : mURI(Move(aOther.mURI))
80 , mBlobSerial(Move(aOther.mBlobSerial))
81 , mHash(aOther.mHash)
82 , mIsChrome(aOther.mIsChrome)
83 { }
85 bool
86 ImageCacheKey::operator==(const ImageCacheKey& aOther) const
88 if (mBlobSerial || aOther.mBlobSerial) {
89 // If at least one of us has a blob serial, just compare the blob serial and
90 // the ref portion of the URIs.
91 return mBlobSerial == aOther.mBlobSerial &&
92 mURI->HasSameRef(*aOther.mURI);
95 // For non-blob URIs, compare the URIs.
96 return *mURI == *aOther.mURI;
99 const char*
100 ImageCacheKey::Spec() const
102 return mURI->Spec();
105 /* static */ uint32_t
106 ImageCacheKey::ComputeHash(ImageURL* aURI,
107 const Maybe<uint64_t>& aBlobSerial)
109 // Since we frequently call Hash() several times in a row on the same
110 // ImageCacheKey, as an optimization we compute our hash once and store it.
112 if (aBlobSerial) {
113 // For blob URIs, we hash the serial number of the underlying blob, so that
114 // different blob URIs which point to the same blob share a cache entry. We
115 // also include the ref portion of the URI to support -moz-samplesize, which
116 // requires us to create different Image objects even if the source data is
117 // the same.
118 nsAutoCString ref;
119 aURI->GetRef(ref);
120 return HashGeneric(*aBlobSerial, HashString(ref));
123 // For non-blob URIs, we hash the URI spec.
124 nsAutoCString spec;
125 aURI->GetSpec(spec);
126 return HashString(spec);
129 } // namespace image
130 } // namespace mozilla