Bug 1376964 - Part 5: Add OMT wrapper for nsIURIs useful for font stuff. r=jfkthame draft
authorCameron McCormack <cam@mcc.id.au>
Fri, 07 Jul 2017 17:29:44 +0800
changeset 608077 77e116bc72e976f3b94ec8f003aae3d19c2e3ce4
parent 608076 c42276ebd5fad32867478582b80501153dd950b8
child 608078 52e8b4fc890aa6876889334ec5f90b47fde186b8
push id68174
push userbmo:cam@mcc.id.au
push dateThu, 13 Jul 2017 06:08:51 +0000
reviewersjfkthame
bugs1376964
milestone56.0a1
Bug 1376964 - Part 5: Add OMT wrapper for nsIURIs useful for font stuff. r=jfkthame MozReview-Commit-ID: FkBYOoqC6x6
gfx/thebes/gfxFontSrcURI.cpp
gfx/thebes/gfxFontSrcURI.h
gfx/thebes/moz.build
netwerk/base/nsSimpleURI.cpp
netwerk/base/nsSimpleURI.h
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/gfxFontSrcURI.cpp
@@ -0,0 +1,119 @@
+/* -*- 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/. */
+
+#include "gfxFontSrcURI.h"
+
+#include "nsIProtocolHandler.h"
+#include "nsProxyRelease.h"
+#include "nsNetUtil.h"
+#include "nsSimpleURI.h"
+#include "nsURIHashKey.h"
+
+static bool
+HasFlag(nsIURI* aURI, uint32_t aFlag)
+{
+  nsresult rv;
+  bool value = false;
+  rv = NS_URIChainHasFlags(aURI, aFlag, &value);
+  return NS_SUCCEEDED(rv) && value;
+}
+
+gfxFontSrcURI::gfxFontSrcURI(nsIURI* aURI)
+{
+  MOZ_ASSERT(NS_IsMainThread());
+  MOZ_ASSERT(aURI);
+
+  mURI = aURI;
+
+  // If we have a data: URI, we know that it is backed by an nsSimpleURI,
+  // and that we don't need to serialize it ahead of time.
+  nsCString scheme;
+  mURI->GetScheme(scheme);
+
+  if (scheme.EqualsLiteral("data")) {
+    // We know that nsSimpleURI::From returns us a pointer to the same object,
+    // and we hold a strong reference to the object in mURI, so no need to
+    // hold it strongly here as well.  (And we'd have to NS_ReleaseOnMainThread
+    // it in our destructor anyway.)
+    RefPtr<mozilla::net::nsSimpleURI> simpleURI =
+      mozilla::net::nsSimpleURI::From(aURI);
+    mSimpleURI = simpleURI;
+
+    NS_ASSERTION(mSimpleURI, "Why aren't our data: URLs backed by nsSimpleURI?");
+  } else {
+    mSimpleURI = nullptr;
+  }
+
+  if (!mSimpleURI) {
+    mURI->GetSpec(mSpec);
+  }
+
+  mHash = nsURIHashKey::HashKey(mURI);
+
+  mInheritsSecurityContext =
+    HasFlag(aURI, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT);
+  mSyncLoadIsOK =
+    HasFlag(aURI, nsIProtocolHandler::URI_SYNC_LOAD_IS_OK);
+}
+
+gfxFontSrcURI::~gfxFontSrcURI()
+{
+  NS_ReleaseOnMainThread("gfxFontSrcURI::mURI", mURI.forget());
+}
+
+bool
+gfxFontSrcURI::Equals(gfxFontSrcURI* aOther)
+{
+  if (mSimpleURI) {
+    if (aOther->mSimpleURI) {
+      return mSimpleURI->Equals(aOther->mSimpleURI);
+    }
+
+    // The two URIs are probably different.  Do a quick check on the
+    // schemes before deciding to serialize mSimpleURI (which might be
+    // quite large).
+    {
+      nsCString thisScheme;
+      mSimpleURI->GetScheme(thisScheme);
+
+      nsCString otherScheme;
+      if (!StringBeginsWith(aOther->mSpec, thisScheme,
+                            nsDefaultCStringComparator())) {
+        return false;
+      }
+    }
+
+    nsCString thisSpec;
+    mSimpleURI->GetSpec(thisSpec);
+    return thisSpec == aOther->mSpec;
+  }
+
+  if (aOther->mSimpleURI) {
+    return aOther->Equals(this);
+  }
+
+  return mSpec == aOther->mSpec;
+}
+
+nsresult
+gfxFontSrcURI::GetSpec(nsACString& aResult)
+{
+  if (mSimpleURI) {
+    return mSimpleURI->GetSpec(aResult);
+  }
+
+  aResult = mSpec;
+  return NS_OK;
+}
+
+nsCString
+gfxFontSrcURI::GetSpecOrDefault()
+{
+  if (mSimpleURI) {
+    return mSimpleURI->GetSpecOrDefault();
+  }
+
+  return mSpec;
+}
new file mode 100644
--- /dev/null
+++ b/gfx/thebes/gfxFontSrcURI.h
@@ -0,0 +1,67 @@
+/* -*- 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_GFX_FONTSRCURI_H
+#define MOZILLA_GFX_FONTSRCURI_H
+
+#include "nsCOMPtr.h"
+#include "nsIURI.h"
+#include "PLDHashTable.h"
+
+namespace mozilla {
+namespace net {
+class nsSimpleURI;
+} // namespace net
+} // namespace mozilla
+
+/**
+ * A wrapper for an nsIURI that can be used OMT, which has cached information
+ * useful for the gfxUserFontSet.
+ */
+class gfxFontSrcURI
+{
+public:
+  explicit gfxFontSrcURI(nsIURI* aURI);
+
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(gfxFontSrcURI)
+
+  nsIURI* get() { return mURI; }
+
+  bool Equals(gfxFontSrcURI* aOther);
+  nsresult GetSpec(nsACString& aResult);
+  nsCString GetSpecOrDefault();
+
+  PLDHashNumber Hash() const { return mHash; }
+  bool InheritsSecurityContext() const { return mInheritsSecurityContext; }
+  bool SyncLoadIsOK() const { return mSyncLoadIsOK; }
+
+private:
+  ~gfxFontSrcURI();
+
+  // The URI.
+  nsCOMPtr<nsIURI> mURI;
+
+  // If the nsIURI is an nsSimpleURI for a data: URL, this is a pointer to it.
+  // (Just a weak reference since mURI holds the strong reference.)
+  //
+  // We store this so that we don't duplicate the URL spec for data: URLs,
+  // which can be much larger than other URLs.
+  mozilla::net::nsSimpleURI* mSimpleURI;
+
+  // If the nsIURI is not an nsSimpleURI, this is its spec.
+  nsCString mSpec;
+
+  // Precomputed hash for mURI.
+  PLDHashNumber mHash;
+
+  // Whether the nsIURI's protocol handler has the URI_INHERITS_SECURITY_CONTEXT
+  // flag.
+  bool mInheritsSecurityContext;
+
+  // Whether the nsIURI's protocol handler has teh URI_SYNC_LOAD_IS_OK flag.
+  bool mSyncLoadIsOK;
+};
+
+#endif // MOZILLA_GFX_FONTSRCURI_H
--- a/gfx/thebes/moz.build
+++ b/gfx/thebes/moz.build
@@ -25,16 +25,17 @@ EXPORTS += [
     'gfxFailure.h',
     'gfxFont.h',
     'gfxFontConstants.h',
     'gfxFontEntry.h',
     'gfxFontFamilyList.h',
     'gfxFontFeatures.h',
     'gfxFontInfoLoader.h',
     'gfxFontPrefLangList.h',
+    'gfxFontSrcURI.h',
     'gfxFontUtils.h',
     'gfxFontVariations.h',
     'gfxGradientCache.h',
     'gfxImageSurface.h',
     'gfxLineSegment.h',
     'gfxMathTable.h',
     'gfxMatrix.h',
     'gfxPattern.h',
@@ -187,16 +188,17 @@ UNIFIED_SOURCES += [
     'gfxBaseSharedMemorySurface.cpp',
     'gfxBlur.cpp',
     'gfxContext.cpp',
     'gfxFont.cpp',
     'gfxFontEntry.cpp',
     'gfxFontFeatures.cpp',
     'gfxFontInfoLoader.cpp',
     'gfxFontMissingGlyphs.cpp',
+    'gfxFontSrcURI.cpp',
     'gfxGlyphExtents.cpp',
     'gfxGradientCache.cpp',
     'gfxGraphiteShaper.cpp',
     'gfxHarfBuzzShaper.cpp',
     'gfxImageSurface.cpp',
     'gfxMathTable.cpp',
     'gfxPattern.cpp',
     'gfxPlatformFontList.cpp',
--- a/netwerk/base/nsSimpleURI.cpp
+++ b/netwerk/base/nsSimpleURI.cpp
@@ -26,16 +26,29 @@ using namespace mozilla::ipc;
 
 namespace mozilla {
 namespace net {
 
 static NS_DEFINE_CID(kThisSimpleURIImplementationCID,
                      NS_THIS_SIMPLEURI_IMPLEMENTATION_CID);
 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
 
+/* static */ already_AddRefed<nsSimpleURI>
+nsSimpleURI::From(nsIURI* aURI)
+{
+    RefPtr<nsSimpleURI> uri;
+    nsresult rv = aURI->QueryInterface(kThisSimpleURIImplementationCID,
+                                       getter_AddRefs(uri));
+    if (NS_FAILED(rv)) {
+        return nullptr;
+    }
+
+    return uri.forget();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // nsSimpleURI methods:
 
 nsSimpleURI::nsSimpleURI()
     : mMutable(true)
     , mIsRefValid(false)
     , mIsQueryValid(false)
 {
--- a/netwerk/base/nsSimpleURI.h
+++ b/netwerk/base/nsSimpleURI.h
@@ -40,20 +40,27 @@ protected:
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIURI
     NS_DECL_NSISERIALIZABLE
     NS_DECL_NSICLASSINFO
     NS_DECL_NSIMUTABLE
     NS_DECL_NSIIPCSERIALIZABLEURI
 
+    static already_AddRefed<nsSimpleURI> From(nsIURI* aURI);
+
     // nsSimpleURI methods:
 
     nsSimpleURI();
 
+    bool Equals(nsSimpleURI* aOther)
+    {
+      return EqualsInternal(aOther, eHonorRef);
+    }
+
     // nsISizeOf
     // Among the sub-classes that inherit (directly or indirectly) from
     // nsSimpleURI, measurement of the following members may be added later if
     // DMD finds it is worthwhile:
     // - nsJSURI: mBaseURI
     // - nsSimpleNestedURI: mInnerURI
     // - nsBlobURI: mPrincipal
     virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;