ImageURL.h 4.2 KB

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