123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef mozilla_image_ImageURL_h
- #define mozilla_image_ImageURL_h
- #include "nsIURI.h"
- #include "MainThreadUtils.h"
- #include "nsNetUtil.h"
- #include "mozilla/HashFunctions.h"
- #include "nsHashKeys.h"
- namespace mozilla {
- namespace image {
- class ImageCacheKey;
- /** ImageURL
- *
- * nsStandardURL is not threadsafe, so this class is created to hold only the
- * necessary URL data required for image loading and decoding.
- *
- * Note: Although several APIs have the same or similar prototypes as those
- * found in nsIURI/nsStandardURL, the class does not implement nsIURI. This is
- * intentional; functionality is limited, and is only useful for imagelib code.
- * By not implementing nsIURI, external code cannot unintentionally be given an
- * nsIURI pointer with this limited class behind it; instead, conversion to a
- * fully implemented nsIURI is required (e.g. through NS_NewURI).
- */
- class ImageURL
- {
- public:
- explicit ImageURL(nsIURI* aURI, nsresult& aRv)
- {
- MOZ_ASSERT(NS_IsMainThread(), "Cannot use nsIURI off main thread!");
- aRv = aURI->GetSpec(mSpec);
- NS_ENSURE_SUCCESS_VOID(aRv);
- aRv = aURI->GetScheme(mScheme);
- NS_ENSURE_SUCCESS_VOID(aRv);
- aRv = aURI->GetRef(mRef);
- NS_ENSURE_SUCCESS_VOID(aRv);
- }
- NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ImageURL)
- nsresult GetSpec(nsACString& result)
- {
- result = mSpec;
- return NS_OK;
- }
- /// A weak pointer to the URI spec for this ImageURL. For logging only.
- const char* Spec() const { return mSpec.get(); }
- enum TruncatedSpecStatus {
- FitsInto1k,
- TruncatedTo1k
- };
- TruncatedSpecStatus GetSpecTruncatedTo1k(nsACString& result)
- {
- static const size_t sMaxTruncatedLength = 1024;
- if (sMaxTruncatedLength >= mSpec.Length()) {
- result = mSpec;
- return FitsInto1k;
- }
- result = Substring(mSpec, 0, sMaxTruncatedLength);
- return TruncatedTo1k;
- }
- nsresult GetScheme(nsACString& result)
- {
- result = mScheme;
- return NS_OK;
- }
- nsresult SchemeIs(const char* scheme, bool* result)
- {
- NS_PRECONDITION(scheme, "scheme is null");
- NS_PRECONDITION(result, "result is null");
- *result = mScheme.Equals(scheme);
- return NS_OK;
- }
- nsresult GetRef(nsACString& result)
- {
- result = mRef;
- return NS_OK;
- }
- already_AddRefed<nsIURI> ToIURI()
- {
- MOZ_ASSERT(NS_IsMainThread(),
- "Convert to nsIURI on main thread only; it is not threadsafe.");
- nsCOMPtr<nsIURI> newURI;
- NS_NewURI(getter_AddRefs(newURI), mSpec);
- return newURI.forget();
- }
- bool operator==(const ImageURL& aOther) const
- {
- // Note that we don't need to consider mScheme and mRef, because they're
- // already represented in mSpec.
- return mSpec == aOther.mSpec;
- }
- bool HasSameRef(const ImageURL& aOther) const
- {
- return mRef == aOther.mRef;
- }
- private:
- friend class ImageCacheKey;
- uint32_t ComputeHash(const Maybe<uint64_t>& aBlobSerial) const
- {
- if (aBlobSerial) {
- // For blob URIs, we hash the serial number of the underlying blob, so that
- // different blob URIs which point to the same blob share a cache entry. We
- // also include the ref portion of the URI to support media fragments which
- // requires us to create different Image objects even if the source data is
- // the same.
- return HashGeneric(*aBlobSerial, HashString(mRef));
- }
- // For non-blob URIs, we hash the URI spec.
- return HashString(mSpec);
- }
- // Since this is a basic storage class, no duplication of spec parsing is
- // included in the functionality. Instead, the class depends upon the
- // parsing implementation in the nsIURI class used in object construction.
- // This means each field is stored separately, but since only a few are
- // required, this small memory tradeoff for threadsafe usage should be ok.
- nsAutoCString mSpec;
- nsAutoCString mScheme;
- nsAutoCString mRef;
- ~ImageURL() { }
- };
- } // namespace image
- } // namespace mozilla
- #endif // mozilla_image_ImageURL_h
|