Commit 513c6609 authored by Jan Varga's avatar Jan Varga
Browse files

Bug 726593 - Implement FileHandle. r=bent

parent f0d1bb70
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@
@BINPATH@/components/dom_css.xpt
@BINPATH@/components/dom_devicestorage.xpt
@BINPATH@/components/dom_events.xpt
@BINPATH@/components/dom_file.xpt
@BINPATH@/components/dom_geolocation.xpt
@BINPATH@/components/dom_network.xpt
@BINPATH@/components/dom_notification.xpt
+1 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@
@BINPATH@/components/dom_css.xpt
@BINPATH@/components/dom_devicestorage.xpt
@BINPATH@/components/dom_events.xpt
@BINPATH@/components/dom_file.xpt
@BINPATH@/components/dom_geolocation.xpt
@BINPATH@/components/dom_network.xpt
@BINPATH@/components/dom_notification.xpt
+3 −1
Original line number Diff line number Diff line
@@ -552,6 +552,8 @@ public:
  static bool CheckForBOM(const unsigned char* aBuffer, PRUint32 aLength,
                          nsACString& aCharset, bool *bigEndian = nsnull);

  static nsresult GuessCharset(const char *aData, PRUint32 aDataLen,
                               nsACString &aCharset);

  /**
   * Determine whether aContent is in some way associated with aForm.  If the
+102 −44
Original line number Diff line number Diff line
@@ -43,6 +43,19 @@ class nsDOMFileBase : public nsIDOMFile,
public:
  typedef mozilla::dom::indexedDB::FileInfo FileInfo;

  virtual already_AddRefed<nsIDOMBlob>
  CreateSlice(PRUint64 aStart, PRUint64 aLength,
              const nsAString& aContentType) = 0;

  virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
  GetSubBlobs() const { return nsnull; }

  NS_DECL_NSIDOMBLOB
  NS_DECL_NSIDOMFILE
  NS_DECL_NSIXHRSENDABLE
  NS_DECL_NSIMUTABLE

protected:
  nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
                PRUint64 aLength)
    : mIsFile(true), mImmutable(false), mContentType(aContentType),
@@ -60,8 +73,8 @@ public:
    mContentType.SetIsVoid(false);
  }

  nsDOMFileBase(const nsAString& aContentType,
                PRUint64 aStart, PRUint64 aLength)
  nsDOMFileBase(const nsAString& aContentType, PRUint64 aStart,
                PRUint64 aLength)
    : mIsFile(false), mImmutable(false), mContentType(aContentType),
      mStart(aStart), mLength(aLength)
  {
@@ -73,36 +86,35 @@ public:

  virtual ~nsDOMFileBase() {}

  virtual already_AddRefed<nsIDOMBlob>
  CreateSlice(PRUint64 aStart, PRUint64 aLength,
              const nsAString& aContentType) = 0;

  virtual const nsTArray<nsCOMPtr<nsIDOMBlob> >*
  GetSubBlobs() const { return nsnull; }

  NS_DECL_ISUPPORTS
  NS_DECL_NSIDOMBLOB
  NS_DECL_NSIDOMFILE
  NS_DECL_NSIXHRSENDABLE
  NS_DECL_NSIMUTABLE

protected:
  bool IsSizeUnknown()
  bool IsSizeUnknown() const
  {
    return mLength == UINT64_MAX;
  }

  virtual bool IsStoredFile()
  virtual bool IsStoredFile() const
  {
    return false;
  }

  virtual bool IsWholeFile()
  virtual bool IsWholeFile() const
  {
    NS_NOTREACHED("Should only be called on dom blobs backed by files!");
    return false;
  }

  virtual bool IsSnapshot() const
  {
    return false;
  }

  FileInfo* GetFileInfo() const
  {
    NS_ASSERTION(IsStoredFile(), "Should only be called on stored files!");
    NS_ASSERTION(!mFileInfos.IsEmpty(), "Must have at least one file info!");

    return mFileInfos.ElementAt(0);
  }

  bool mIsFile;
  bool mImmutable;
  nsString mContentType;
@@ -115,13 +127,53 @@ protected:
  nsTArray<nsRefPtr<FileInfo> > mFileInfos;
};

class nsDOMFileFile : public nsDOMFileBase,
class nsDOMFile : public nsDOMFileBase
{
public:
  nsDOMFile(const nsAString& aName, const nsAString& aContentType,
            PRUint64 aLength)
  : nsDOMFileBase(aName, aContentType, aLength)
  { }

  nsDOMFile(const nsAString& aContentType, PRUint64 aLength)
  : nsDOMFileBase(aContentType, aLength)
  { }

  nsDOMFile(const nsAString& aContentType, PRUint64 aStart, PRUint64 aLength)
  : nsDOMFileBase(aContentType, aStart, aLength)
  { }

  NS_DECL_ISUPPORTS
};

class nsDOMFileCC : public nsDOMFileBase
{
public:
  nsDOMFileCC(const nsAString& aName, const nsAString& aContentType,
              PRUint64 aLength)
  : nsDOMFileBase(aName, aContentType, aLength)
  { }

  nsDOMFileCC(const nsAString& aContentType, PRUint64 aLength)
  : nsDOMFileBase(aContentType, aLength)
  { }

  nsDOMFileCC(const nsAString& aContentType, PRUint64 aStart, PRUint64 aLength)
  : nsDOMFileBase(aContentType, aStart, aLength)
  { }

  NS_DECL_CYCLE_COLLECTING_ISUPPORTS

  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMFileCC, nsIDOMFile)
};

class nsDOMFileFile : public nsDOMFile,
                      public nsIJSNativeInitializer
{
public:
  // Create as a file
  nsDOMFileFile(nsIFile *aFile)
    : nsDOMFileBase(EmptyString(), EmptyString(), UINT64_MAX),
    : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
      mFile(aFile), mWholeFile(true), mStoredFile(false)
  {
    NS_ASSERTION(mFile, "must have file");
@@ -130,10 +182,19 @@ public:
    mFile->GetLeafName(mName);
  }

  // Create as a file
  nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
                PRUint64 aLength, nsIFile *aFile)
    : nsDOMFile(aName, aContentType, aLength),
      mFile(aFile), mWholeFile(true), mStoredFile(false)
  {
    NS_ASSERTION(mFile, "must have file");
  }

  // Create as a blob
  nsDOMFileFile(nsIFile *aFile, const nsAString& aContentType,
                nsISupports *aCacheToken)
    : nsDOMFileBase(aContentType, UINT64_MAX),
    : nsDOMFile(aContentType, UINT64_MAX),
      mFile(aFile), mWholeFile(true), mStoredFile(false),
      mCacheToken(aCacheToken)
  {
@@ -142,20 +203,19 @@ public:

  // Create as a file with custom name
  nsDOMFileFile(nsIFile *aFile, const nsAString& aName)
    : nsDOMFileBase(EmptyString(), EmptyString(), UINT64_MAX),
    : nsDOMFile(aName, EmptyString(), UINT64_MAX),
      mFile(aFile), mWholeFile(true), mStoredFile(false)
  {
    NS_ASSERTION(mFile, "must have file");
    // Lazily get the content type and size
    mContentType.SetIsVoid(true);
    mName.Assign(aName);
  }

  // Create as a stored file
  nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
                PRUint64 aLength, nsIFile* aFile,
                FileInfo* aFileInfo)
    : nsDOMFileBase(aName, aContentType, aLength),
    : nsDOMFile(aName, aContentType, aLength),
      mFile(aFile), mWholeFile(true), mStoredFile(true)
  {
    NS_ASSERTION(mFile, "must have file");
@@ -165,7 +225,7 @@ public:
  // Create as a stored blob
  nsDOMFileFile(const nsAString& aContentType, PRUint64 aLength,
                nsIFile* aFile, FileInfo* aFileInfo)
    : nsDOMFileBase(aContentType, aLength),
    : nsDOMFile(aContentType, aLength),
      mFile(aFile), mWholeFile(true), mStoredFile(true)
  {
    NS_ASSERTION(mFile, "must have file");
@@ -174,7 +234,7 @@ public:

  // Create as a file to be later initialized
  nsDOMFileFile()
    : nsDOMFileBase(EmptyString(), EmptyString(), UINT64_MAX),
    : nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
      mWholeFile(true), mStoredFile(false)
  {
    // Lazily get the content type and size
@@ -206,7 +266,7 @@ protected:
  // Create slice
  nsDOMFileFile(const nsDOMFileFile* aOther, PRUint64 aStart, PRUint64 aLength,
                const nsAString& aContentType)
    : nsDOMFileBase(aContentType, aOther->mStart + aStart, aLength),
    : nsDOMFile(aContentType, aOther->mStart + aStart, aLength),
      mFile(aOther->mFile), mWholeFile(false),
      mStoredFile(aOther->mStoredFile), mCacheToken(aOther->mCacheToken)
  {
@@ -216,32 +276,30 @@ protected:
    if (mStoredFile) {
      FileInfo* fileInfo;

      if (!mozilla::dom::indexedDB::IndexedDatabaseManager::IsClosed()) {
        mozilla::dom::indexedDB::IndexedDatabaseManager::FileMutex().Lock();
      }

      NS_ASSERTION(!aOther->mFileInfos.IsEmpty(),
                   "A stored file must have at least one file info!");

      fileInfo = aOther->mFileInfos.ElementAt(0);
      using mozilla::dom::indexedDB::IndexedDatabaseManager;

      if (!mozilla::dom::indexedDB::IndexedDatabaseManager::IsClosed()) {
        mozilla::dom::indexedDB::IndexedDatabaseManager::FileMutex().Unlock();
      if (IndexedDatabaseManager::IsClosed()) {
        fileInfo = aOther->GetFileInfo();
      }
      else {
        mozilla::MutexAutoLock lock(IndexedDatabaseManager::FileMutex());
        fileInfo = aOther->GetFileInfo();
      }

      mFileInfos.AppendElement(fileInfo);
    }
  }

  virtual already_AddRefed<nsIDOMBlob>
  CreateSlice(PRUint64 aStart, PRUint64 aLength,
              const nsAString& aContentType);

  virtual bool IsStoredFile()
  virtual bool IsStoredFile() const
  {
    return mStoredFile;
  }

  virtual bool IsWholeFile()
  virtual bool IsWholeFile() const
  {
    return mWholeFile;
  }
@@ -252,7 +310,7 @@ protected:
  nsCOMPtr<nsISupports> mCacheToken;
};

class nsDOMMemoryFile : public nsDOMFileBase
class nsDOMMemoryFile : public nsDOMFile
{
public:
  // Create as file
@@ -260,7 +318,7 @@ public:
                  PRUint64 aLength,
                  const nsAString& aName,
                  const nsAString& aContentType)
    : nsDOMFileBase(aName, aContentType, aLength),
    : nsDOMFile(aName, aContentType, aLength),
      mDataOwner(new DataOwner(aMemoryBuffer))
  {
    NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
@@ -270,7 +328,7 @@ public:
  nsDOMMemoryFile(void *aMemoryBuffer,
                  PRUint64 aLength,
                  const nsAString& aContentType)
    : nsDOMFileBase(aContentType, aLength),
    : nsDOMFile(aContentType, aLength),
      mDataOwner(new DataOwner(aMemoryBuffer))
  {
    NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
@@ -282,7 +340,7 @@ protected:
  // Create slice
  nsDOMMemoryFile(const nsDOMMemoryFile* aOther, PRUint64 aStart,
                  PRUint64 aLength, const nsAString& aContentType)
    : nsDOMFileBase(aContentType, aOther->mStart + aStart, aLength),
    : nsDOMFile(aContentType, aOther->mStart + aStart, aLength),
      mDataOwner(aOther->mDataOwner)
  {
    NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
+135 −24
Original line number Diff line number Diff line
@@ -178,6 +178,10 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsIDOMDocumentType.h"
#include "nsCharSeparatedTokenizer.h"

#include "nsICharsetDetector.h"
#include "nsICharsetDetectionObserver.h"
#include "nsIPlatformCharset.h"

extern "C" int MOZ_XMLTranslateEntity(const char* ptr, const char* end,
                                      const char** next, PRUnichar* result);
extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end,
@@ -190,21 +194,6 @@ using namespace mozilla;

const char kLoadAsData[] = "loadAsData";

/**
 * Default values for the ViewportInfo structure.
 */
static const float    kViewportMinScale = 0.0;
static const float    kViewportMaxScale = 10.0;
static const PRUint32 kViewportMinWidth = 200;
static const PRUint32 kViewportMaxWidth = 10000;
static const PRUint32 kViewportMinHeight = 223;
static const PRUint32 kViewportMaxHeight = 10000;
static const PRInt32  kViewportDefaultScreenWidth = 980;

static const char kJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);

nsIDOMScriptObjectFactory *nsContentUtils::sDOMScriptObjectFactory = nsnull;
nsIXPConnect *nsContentUtils::sXPConnect;
nsIScriptSecurityManager *nsContentUtils::sSecurityManager;
@@ -260,6 +249,23 @@ nsIParser* nsContentUtils::sXMLFragmentParser = nsnull;
nsIFragmentContentSink* nsContentUtils::sXMLFragmentSink = nsnull;
bool nsContentUtils::sFragmentParsingActive = false;

namespace {

/**
 * Default values for the ViewportInfo structure.
 */
static const float    kViewportMinScale = 0.0;
static const float    kViewportMaxScale = 10.0;
static const PRUint32 kViewportMinWidth = 200;
static const PRUint32 kViewportMaxWidth = 10000;
static const PRUint32 kViewportMinHeight = 223;
static const PRUint32 kViewportMaxHeight = 10000;
static const PRInt32  kViewportDefaultScreenWidth = 980;

static const char kJSStackContractID[] = "@mozilla.org/js/xpc/ContextStack;1";
static NS_DEFINE_CID(kParserServiceCID, NS_PARSERSERVICE_CID);
static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);

static PLDHashTable sEventListenerManagersHash;

class EventListenerManagerMapEntry : public PLDHashEntryHdr
@@ -301,7 +307,7 @@ EventListenerManagerHashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
  lm->~EventListenerManagerMapEntry();
}

class nsSameOriginChecker : public nsIChannelEventSink,
class SameOriginChecker : public nsIChannelEventSink,
                          public nsIInterfaceRequestor
{
  NS_DECL_ISUPPORTS
@@ -309,6 +315,28 @@ class nsSameOriginChecker : public nsIChannelEventSink,
  NS_DECL_NSIINTERFACEREQUESTOR
};

class CharsetDetectionObserver : public nsICharsetDetectionObserver
{
public:
  NS_DECL_ISUPPORTS

  NS_IMETHOD Notify(const char *aCharset, nsDetectionConfident aConf)
  {
    mCharset = aCharset;
    return NS_OK;
  }

  const nsACString& GetResult() const
  {
    return mCharset;
  }

private:
  nsCString mCharset;
};

} // anonymous namespace

/* static */
TimeDuration
nsContentUtils::HandlingUserInputTimeout()
@@ -3536,6 +3564,89 @@ nsContentUtils::CheckForBOM(const unsigned char* aBuffer, PRUint32 aLength,
  return found;
}

NS_IMPL_ISUPPORTS1(CharsetDetectionObserver,
                   nsICharsetDetectionObserver)

/* static */
nsresult
nsContentUtils::GuessCharset(const char *aData, PRUint32 aDataLen,
                             nsACString &aCharset)
{
  // First try the universal charset detector
  nsCOMPtr<nsICharsetDetector> detector =
    do_CreateInstance(NS_CHARSET_DETECTOR_CONTRACTID_BASE
                      "universal_charset_detector");
  if (!detector) {
    // No universal charset detector, try the default charset detector
    const nsAdoptingCString& detectorName =
      Preferences::GetLocalizedCString("intl.charset.detector");
    if (!detectorName.IsEmpty()) {
      nsCAutoString detectorContractID;
      detectorContractID.AssignLiteral(NS_CHARSET_DETECTOR_CONTRACTID_BASE);
      detectorContractID += detectorName;
      detector = do_CreateInstance(detectorContractID.get());
    }
  }

  nsresult rv;

  // The charset detector doesn't work for empty (null) aData. Testing
  // aDataLen instead of aData so that we catch potential errors.
  if (detector && aDataLen) {
    nsRefPtr<CharsetDetectionObserver> observer =
      new CharsetDetectionObserver();

    rv = detector->Init(observer);
    NS_ENSURE_SUCCESS(rv, rv);

    bool dummy;
    rv = detector->DoIt(aData, aDataLen, &dummy);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = detector->Done();
    NS_ENSURE_SUCCESS(rv, rv);

    aCharset = observer->GetResult();
  } else {
    // no charset detector available, check the BOM
    unsigned char sniffBuf[3];
    PRUint32 numRead =
      (aDataLen >= sizeof(sniffBuf) ? sizeof(sniffBuf) : aDataLen);
    memcpy(sniffBuf, aData, numRead);

    bool bigEndian;
    if (CheckForBOM(sniffBuf, numRead, aCharset, &bigEndian) &&
        aCharset.EqualsLiteral("UTF-16")) {
      if (bigEndian) {
        aCharset.AppendLiteral("BE");
      }
      else {
        aCharset.AppendLiteral("LE");
      }
    }
  }

  if (aCharset.IsEmpty()) {
    // no charset detected, default to the system charset
    nsCOMPtr<nsIPlatformCharset> platformCharset =
      do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
    if (NS_SUCCEEDED(rv)) {
      rv = platformCharset->GetCharset(kPlatformCharsetSel_PlainTextInFile,
                                       aCharset);
      if (NS_FAILED(rv)) {
        NS_WARNING("Failed to get the system charset!");
      }
    }
  }

  if (aCharset.IsEmpty()) {
    // no sniffed or default charset, assume UTF-8
    aCharset.AssignLiteral("UTF-8");
  }

  return NS_OK;
}

/* static */
void
nsContentUtils::RegisterShutdownObserver(nsIObserver* aObserver)
@@ -5517,7 +5628,7 @@ nsIInterfaceRequestor*
nsContentUtils::GetSameOriginChecker()
{
  if (!sSameOriginChecker) {
    sSameOriginChecker = new nsSameOriginChecker();
    sSameOriginChecker = new SameOriginChecker();
    NS_IF_ADDREF(sSameOriginChecker);
  }
  return sSameOriginChecker;
@@ -5549,12 +5660,12 @@ nsContentUtils::CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel
  return rv;
}

NS_IMPL_ISUPPORTS2(nsSameOriginChecker,
NS_IMPL_ISUPPORTS2(SameOriginChecker,
                   nsIChannelEventSink,
                   nsIInterfaceRequestor)

NS_IMETHODIMP
nsSameOriginChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
SameOriginChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
                                          nsIChannel *aNewChannel,
                                          PRUint32 aFlags,
                                          nsIAsyncVerifyRedirectCallback *cb)
@@ -5570,7 +5681,7 @@ nsSameOriginChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
}

NS_IMETHODIMP
nsSameOriginChecker::GetInterface(const nsIID & aIID, void **aResult)
SameOriginChecker::GetInterface(const nsIID & aIID, void **aResult)
{
  return QueryInterface(aIID, aResult);
}
Loading