Bug 664254: Make DOM File objects implement nsIMutable so they can be immutabilized for sharing across threads. r=sicking
authorKyle Huey <khuey@kylehuey.com>
Tue, 19 Jul 2011 09:27:46 -0700
changeset 73174 398402eabdb09416fb7d9755f5cb06af15e73c1d
parent 73173 09b2569edec202c1fdb1e8885a784ce7c2b412fc
child 73175 85f7679fd5eb481ea62fa3a047136969c3660586
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssicking
bugs664254
milestone8.0a1
Bug 664254: Make DOM File objects implement nsIMutable so they can be immutabilized for sharing across threads. r=sicking
content/base/public/nsDOMFile.h
content/base/src/nsDOMFile.cpp
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -41,16 +41,17 @@
 
 #include "nsICharsetDetectionObserver.h"
 #include "nsIFile.h"
 #include "nsIDOMFile.h"
 #include "nsIDOMFileList.h"
 #include "nsIDOMFileError.h"
 #include "nsIInputStream.h"
 #include "nsIJSNativeInitializer.h"
+#include "nsIMutable.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "mozilla/AutoRestore.h"
 #include "nsString.h"
 #include "nsIXMLHttpRequest.h"
 #include "prmem.h"
 #include "nsAutoPtr.h"
 
@@ -61,40 +62,41 @@
 class nsIFile;
 class nsIInputStream;
 class nsIClassInfo;
 class nsIBlobBuilder;
 
 nsresult NS_NewBlobBuilder(nsISupports* *aSupports);
 
 class nsDOMFileBase : public nsIDOMFile,
-                      public nsIXHRSendable
+                      public nsIXHRSendable,
+                      public nsIMutable
 {
 public:
 
   nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
                 PRUint64 aLength)
-    : mIsFile(true), mContentType(aContentType), mName(aName),
-      mStart(0), mLength(aLength)
+    : mIsFile(true), mImmutable(false), mContentType(aContentType),
+      mName(aName), mStart(0), mLength(aLength)
   {
     // Ensure non-null mContentType by default
     mContentType.SetIsVoid(PR_FALSE);
   }
 
   nsDOMFileBase(const nsAString& aContentType, PRUint64 aLength)
-    : mIsFile(false), mContentType(aContentType),
+    : mIsFile(false), mImmutable(false), mContentType(aContentType),
       mStart(0), mLength(aLength)
   {
     // Ensure non-null mContentType by default
     mContentType.SetIsVoid(PR_FALSE);
   }
 
   nsDOMFileBase(const nsAString& aContentType,
                 PRUint64 aStart, PRUint64 aLength)
-    : mIsFile(false), mContentType(aContentType),
+    : mIsFile(false), mImmutable(false), mContentType(aContentType),
       mStart(aStart), mLength(aLength)
   {
     NS_ASSERTION(aLength != PR_UINT64_MAX,
                  "Must know length when creating slice");
     // Ensure non-null mContentType by default
     mContentType.SetIsVoid(PR_FALSE);
   }
 
@@ -103,24 +105,26 @@ public:
   virtual already_AddRefed<nsIDOMBlob>
   CreateSlice(PRUint64 aStart, PRUint64 aLength,
               const nsAString& aContentType) = 0;
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIDOMBLOB
   NS_DECL_NSIDOMFILE
   NS_DECL_NSIXHRSENDABLE
+  NS_DECL_NSIMUTABLE
 
 protected:
   bool IsSizeUnknown()
   {
     return mLength == PR_UINT64_MAX;
   }
 
   bool mIsFile;
+  bool mImmutable;
   nsString mContentType;
   nsString mName;
 
   PRUint64 mStart;
   PRUint64 mLength;
 };
 
 class nsDOMFileFile : public nsDOMFileBase,
@@ -181,16 +185,17 @@ protected:
   // Create slice
   nsDOMFileFile(const nsDOMFileFile* aOther, PRUint64 aStart, PRUint64 aLength,
                 const nsAString& aContentType)
     : nsDOMFileBase(aContentType, aOther->mStart + aStart, aLength),
       mFile(aOther->mFile), mWholeFile(false),
       mCacheToken(aOther->mCacheToken)
   {
     NS_ASSERTION(mFile, "must have file");
+    mImmutable = aOther->mImmutable;
   }
   virtual already_AddRefed<nsIDOMBlob>
   CreateSlice(PRUint64 aStart, PRUint64 aLength,
               const nsAString& aContentType);
 
   nsCOMPtr<nsIFile> mFile;
   bool mWholeFile;
   nsCOMPtr<nsISupports> mCacheToken;
@@ -225,16 +230,17 @@ public:
 protected:
   // Create slice
   nsDOMMemoryFile(const nsDOMMemoryFile* aOther, PRUint64 aStart,
                   PRUint64 aLength, const nsAString& aContentType)
     : nsDOMFileBase(aContentType, aOther->mStart + aStart, aLength),
       mDataOwner(aOther->mDataOwner)
   {
     NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
+    mImmutable = aOther->mImmutable;
   }
   virtual already_AddRefed<nsIDOMBlob>
   CreateSlice(PRUint64 aStart, PRUint64 aLength,
               const nsAString& aContentType);
 
   friend class DataOwnerAdapter; // Needs to see DataOwner
   class DataOwner {
   public:
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -138,16 +138,17 @@ nsresult DataOwnerAdapter::Create(DataOw
 DOMCI_DATA(File, nsDOMFileBase)
 DOMCI_DATA(Blob, nsDOMFileBase)
 
 NS_INTERFACE_MAP_BEGIN(nsDOMFileBase)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
   NS_INTERFACE_MAP_ENTRY(nsIDOMBlob)
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, mIsFile)
   NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
+  NS_INTERFACE_MAP_ENTRY(nsIMutable)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, mIsFile)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !mIsFile)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(nsDOMFileBase)
 NS_IMPL_RELEASE(nsDOMFileBase)
 
 NS_IMETHODIMP
@@ -308,16 +309,45 @@ nsDOMFileBase::GetSendInfo(nsIInputStrea
   CopyUTF16toUTF8(contentType, aContentType);
 
   aCharset.Truncate();
 
   stream.forget(aBody);
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDOMFileBase::GetMutable(PRBool* aMutable)
+{
+  *aMutable = !mImmutable;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsDOMFileBase::SetMutable(PRBool aMutable)
+{
+  nsresult rv = NS_OK;
+
+  NS_ENSURE_ARG(!mImmutable || !aMutable);
+
+  if (!mImmutable && !aMutable) {
+    // Force the content type and size to be cached
+    nsString dummyString;
+    rv = this->GetType(dummyString);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    PRUint64 dummyInt;
+    rv = this->GetSize(&dummyInt);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  mImmutable = !aMutable;
+  return rv;
+}
+
 ////////////////////////////////////////////////////////////////////////////
 // nsDOMFileFile implementation
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsDOMFileFile, nsDOMFileBase,
                              nsIJSNativeInitializer)
 
 already_AddRefed<nsIDOMBlob>
 nsDOMFileFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
@@ -408,16 +438,19 @@ NS_IMETHODIMP
 nsDOMFileFile::Initialize(nsISupports* aOwner,
                           JSContext* aCx,
                           JSObject* aObj,
                           PRUint32 aArgc,
                           jsval* aArgv)
 {
   nsresult rv;
 
+  NS_ASSERTION(!mImmutable, "Something went wrong ...");
+  NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
+
   if (!nsContentUtils::IsCallerChrome()) {
     return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
   }
 
   NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
 
   // We expect to get a path to represent as a File object,
   // or an nsIFile