Line data Source code
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/. */
5 :
6 : #ifndef mozilla_image_ImageURL_h
7 : #define mozilla_image_ImageURL_h
8 :
9 : #include "nsIURI.h"
10 : #include "MainThreadUtils.h"
11 : #include "nsNetUtil.h"
12 : #include "mozilla/HashFunctions.h"
13 : #include "nsHashKeys.h"
14 : #include "nsProxyRelease.h"
15 :
16 : namespace mozilla {
17 : namespace image {
18 :
19 : class ImageCacheKey;
20 :
21 : /** ImageURL
22 : *
23 : * nsStandardURL is not threadsafe, so this class is created to hold only the
24 : * necessary URL data required for image loading and decoding.
25 : *
26 : * Note: Although several APIs have the same or similar prototypes as those
27 : * found in nsIURI/nsStandardURL, the class does not implement nsIURI. This is
28 : * intentional; functionality is limited, and is only useful for imagelib code.
29 : * By not implementing nsIURI, external code cannot unintentionally be given an
30 : * nsIURI pointer with this limited class behind it; instead, conversion to a
31 : * fully implemented nsIURI is required (e.g. through NS_NewURI).
32 : */
33 : class ImageURL
34 : {
35 : public:
36 86 : explicit ImageURL(nsIURI* aURI, nsresult& aRv)
37 172 : : mURI(new nsMainThreadPtrHolder<nsIURI>("ImageURL::mURI", aURI))
38 : {
39 86 : MOZ_ASSERT(NS_IsMainThread(), "Cannot use nsIURI off main thread!");
40 :
41 86 : aRv = aURI->GetSpec(mSpec);
42 86 : NS_ENSURE_SUCCESS_VOID(aRv);
43 :
44 86 : aRv = aURI->GetScheme(mScheme);
45 86 : NS_ENSURE_SUCCESS_VOID(aRv);
46 :
47 86 : aRv = aURI->GetRef(mRef);
48 86 : NS_ENSURE_SUCCESS_VOID(aRv);
49 : }
50 :
51 522 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageURL)
52 :
53 510 : nsresult GetSpec(nsACString& result)
54 : {
55 510 : result = mSpec;
56 510 : return NS_OK;
57 : }
58 :
59 : /// A weak pointer to the URI spec for this ImageURL. For logging only.
60 83 : const char* Spec() const { return mSpec.get(); }
61 :
62 : enum TruncatedSpecStatus {
63 : FitsInto1k,
64 : TruncatedTo1k
65 : };
66 0 : TruncatedSpecStatus GetSpecTruncatedTo1k(nsACString& result)
67 : {
68 : static const size_t sMaxTruncatedLength = 1024;
69 :
70 0 : if (sMaxTruncatedLength >= mSpec.Length()) {
71 0 : result = mSpec;
72 0 : return FitsInto1k;
73 : }
74 :
75 0 : result = Substring(mSpec, 0, sMaxTruncatedLength);
76 0 : return TruncatedTo1k;
77 : }
78 :
79 : nsresult GetScheme(nsACString& result)
80 : {
81 : result = mScheme;
82 : return NS_OK;
83 : }
84 :
85 172 : nsresult SchemeIs(const char* scheme, bool* result)
86 : {
87 172 : NS_PRECONDITION(scheme, "scheme is null");
88 172 : NS_PRECONDITION(result, "result is null");
89 :
90 172 : *result = mScheme.Equals(scheme);
91 172 : return NS_OK;
92 : }
93 :
94 : nsresult GetRef(nsACString& result)
95 : {
96 : result = mRef;
97 : return NS_OK;
98 : }
99 :
100 272 : already_AddRefed<nsIURI> ToIURI()
101 : {
102 544 : nsCOMPtr<nsIURI> newURI = mURI.get();
103 544 : return newURI.forget();
104 : }
105 :
106 46 : bool operator==(const ImageURL& aOther) const
107 : {
108 : // Note that we don't need to consider mScheme and mRef, because they're
109 : // already represented in mSpec.
110 46 : return mSpec == aOther.mSpec;
111 : }
112 :
113 0 : bool HasSameRef(const ImageURL& aOther) const
114 : {
115 0 : return mRef == aOther.mRef;
116 : }
117 :
118 : private:
119 : friend class ImageCacheKey;
120 :
121 45 : PLDHashNumber ComputeHash(const Maybe<uint64_t>& aBlobSerial) const
122 : {
123 45 : if (aBlobSerial) {
124 : // For blob URIs, we hash the serial number of the underlying blob, so that
125 : // different blob URIs which point to the same blob share a cache entry. We
126 : // also include the ref portion of the URI to support media fragments which
127 : // requires us to create different Image objects even if the source data is
128 : // the same.
129 0 : return HashGeneric(*aBlobSerial, HashString(mRef));
130 : }
131 : // For non-blob URIs, we hash the URI spec.
132 45 : return HashString(mSpec);
133 : }
134 :
135 : nsMainThreadPtrHandle<nsIURI> mURI;
136 :
137 : // Since this is a basic storage class, no duplication of spec parsing is
138 : // included in the functionality. Instead, the class depends upon the
139 : // parsing implementation in the nsIURI class used in object construction.
140 : // This means each field is stored separately, but since only a few are
141 : // required, this small memory tradeoff for threadsafe usage should be ok.
142 : nsAutoCString mSpec;
143 : nsAutoCString mScheme;
144 : nsAutoCString mRef;
145 :
146 6 : ~ImageURL() { }
147 : };
148 :
149 : } // namespace image
150 : } // namespace mozilla
151 :
152 : #endif // mozilla_image_ImageURL_h
|