LCOV - code coverage report
Current view: directory - content/base/src - nsDOMFile.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 272 101 37.1 %
Date: 2012-06-02 Functions: 60 17 28.3 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is mozila.org code.
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Mozilla Foundation
      19                 :  * Portions created by the Initial Developer are Copyright (C) 2007
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *   Dave Camp <dcamp@mozilla.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "nsDOMFile.h"
      40                 : 
      41                 : #include "nsCExternalHandlerService.h"
      42                 : #include "nsContentCID.h"
      43                 : #include "nsContentUtils.h"
      44                 : #include "nsDOMClassInfoID.h"
      45                 : #include "nsDOMError.h"
      46                 : #include "nsICharsetDetector.h"
      47                 : #include "nsICharsetConverterManager.h"
      48                 : #include "nsIConverterInputStream.h"
      49                 : #include "nsIDocument.h"
      50                 : #include "nsIDOMDocument.h"
      51                 : #include "nsIFileStreams.h"
      52                 : #include "nsIInputStream.h"
      53                 : #include "nsIIPCSerializable.h"
      54                 : #include "nsIMIMEService.h"
      55                 : #include "nsIPlatformCharset.h"
      56                 : #include "nsISeekableStream.h"
      57                 : #include "nsIUnicharInputStream.h"
      58                 : #include "nsIUnicodeDecoder.h"
      59                 : #include "nsNetCID.h"
      60                 : #include "nsNetUtil.h"
      61                 : #include "nsIUUIDGenerator.h"
      62                 : #include "nsBlobProtocolHandler.h"
      63                 : #include "nsStringStream.h"
      64                 : #include "CheckedInt.h"
      65                 : #include "nsJSUtils.h"
      66                 : #include "mozilla/Preferences.h"
      67                 : 
      68                 : #include "plbase64.h"
      69                 : #include "prmem.h"
      70                 : #include "dombindings.h"
      71                 : 
      72                 : using namespace mozilla;
      73                 : using namespace mozilla::dom;
      74                 : 
      75                 : // XXXkhuey the input stream that we pass out of a DOMFile
      76                 : // can outlive the actual DOMFile object.  Thus, we must
      77                 : // ensure that the buffer underlying the stream we get
      78                 : // from NS_NewByteInputStream is held alive as long as the
      79                 : // stream is.  We do that by passing back this class instead.
      80                 : class DataOwnerAdapter : public nsIInputStream,
      81                 :                          public nsISeekableStream
      82               0 : {
      83                 :   typedef nsDOMMemoryFile::DataOwner DataOwner;
      84                 : public:
      85                 :   static nsresult Create(DataOwner* aDataOwner,
      86                 :                          PRUint32 aStart,
      87                 :                          PRUint32 aLength,
      88                 :                          nsIInputStream** _retval);
      89                 : 
      90                 :   NS_DECL_ISUPPORTS
      91                 : 
      92               0 :   NS_FORWARD_NSIINPUTSTREAM(mStream->)
      93                 : 
      94               0 :   NS_FORWARD_NSISEEKABLESTREAM(mSeekableStream->)
      95                 : 
      96                 : private:
      97               0 :   DataOwnerAdapter(DataOwner* aDataOwner,
      98                 :                    nsIInputStream* aStream)
      99                 :     : mDataOwner(aDataOwner), mStream(aStream),
     100               0 :       mSeekableStream(do_QueryInterface(aStream))
     101                 :   {
     102               0 :     NS_ASSERTION(mSeekableStream, "Somebody gave us the wrong stream!");
     103               0 :   }
     104                 : 
     105                 :   nsRefPtr<DataOwner> mDataOwner;
     106                 :   nsCOMPtr<nsIInputStream> mStream;
     107                 :   nsCOMPtr<nsISeekableStream> mSeekableStream;
     108                 : };
     109                 : 
     110               0 : NS_IMPL_THREADSAFE_ISUPPORTS2(DataOwnerAdapter,
     111                 :                               nsIInputStream,
     112                 :                               nsISeekableStream)
     113                 : 
     114               0 : nsresult DataOwnerAdapter::Create(DataOwner* aDataOwner,
     115                 :                                   PRUint32 aStart,
     116                 :                                   PRUint32 aLength,
     117                 :                                   nsIInputStream** _retval)
     118                 : {
     119                 :   nsresult rv;
     120               0 :   NS_ASSERTION(aDataOwner, "Uh ...");
     121                 : 
     122               0 :   nsCOMPtr<nsIInputStream> stream;
     123                 : 
     124               0 :   rv = NS_NewByteInputStream(getter_AddRefs(stream),
     125                 :                              static_cast<const char*>(aDataOwner->mData) +
     126                 :                              aStart,
     127                 :                              (PRInt32)aLength,
     128               0 :                              NS_ASSIGNMENT_DEPEND);
     129               0 :   NS_ENSURE_SUCCESS(rv, rv);
     130                 : 
     131               0 :   NS_ADDREF(*_retval = new DataOwnerAdapter(aDataOwner, stream));
     132                 : 
     133               0 :   return NS_OK;
     134                 : }
     135                 : 
     136                 : ////////////////////////////////////////////////////////////////////////////
     137                 : // nsDOMFileBase implementation
     138                 : 
     139                 : DOMCI_DATA(File, nsDOMFileBase)
     140                 : DOMCI_DATA(Blob, nsDOMFileBase)
     141                 : 
     142              80 : NS_INTERFACE_MAP_BEGIN(nsDOMFileBase)
     143              80 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFile)
     144              54 :   NS_INTERFACE_MAP_ENTRY(nsIDOMBlob)
     145              48 :   NS_INTERFACE_MAP_ENTRY(nsIDOMBlob_GECKO_13)
     146              48 :   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIDOMFile, mIsFile)
     147              42 :   NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
     148              42 :   NS_INTERFACE_MAP_ENTRY(nsIMutable)
     149              42 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, mIsFile)
     150              34 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !mIsFile)
     151              34 : NS_INTERFACE_MAP_END
     152                 : 
     153                 : // Threadsafe when GetMutable() == false
     154              52 : NS_IMPL_THREADSAFE_ADDREF(nsDOMFileBase)
     155              52 : NS_IMPL_THREADSAFE_RELEASE(nsDOMFileBase)
     156                 : 
     157                 : NS_IMETHODIMP
     158               6 : nsDOMFileBase::GetName(nsAString &aFileName)
     159                 : {
     160               6 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     161               6 :   aFileName = mName;
     162               6 :   return NS_OK;
     163                 : }
     164                 : 
     165                 : NS_IMETHODIMP
     166               0 : nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
     167                 : {
     168               0 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     169                 : 
     170                 :   // It is unsafe to call CallerHasUniversalXPConnect on a non-main thread. If
     171                 :   // you hit the following assertion you need to figure out some other way to
     172                 :   // determine privileges and call GetMozFullPathInternal.
     173               0 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     174                 : 
     175               0 :   if (nsContentUtils::CallerHasUniversalXPConnect()) {
     176               0 :     return GetMozFullPathInternal(aFileName);
     177                 :   }
     178               0 :   aFileName.Truncate();
     179               0 :   return NS_OK;
     180                 : }
     181                 : 
     182                 : NS_IMETHODIMP
     183               0 : nsDOMFileBase::GetMozFullPathInternal(nsAString &aFileName)
     184                 : {
     185               0 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     186               0 :   aFileName.Truncate();
     187               0 :   return NS_OK;
     188                 : }
     189                 : 
     190                 : NS_IMETHODIMP
     191               0 : nsDOMFileBase::GetSize(PRUint64 *aSize)
     192                 : {
     193               0 :   *aSize = mLength;
     194               0 :   return NS_OK;
     195                 : }
     196                 : 
     197                 : NS_IMETHODIMP
     198               0 : nsDOMFileBase::GetType(nsAString &aType)
     199                 : {
     200               0 :   aType = mContentType;
     201               0 :   return NS_OK;
     202                 : }
     203                 : 
     204                 : // Makes sure that aStart and aEnd is less then or equal to aSize and greater
     205                 : // than 0
     206                 : static void
     207               0 : ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
     208                 : {
     209               0 :   CheckedInt64 newStartOffset = aStart;
     210               0 :   if (aStart < -aSize) {
     211               0 :     newStartOffset = 0;
     212                 :   }
     213               0 :   else if (aStart < 0) {
     214               0 :     newStartOffset += aSize;
     215                 :   }
     216               0 :   else if (aStart > aSize) {
     217               0 :     newStartOffset = aSize;
     218                 :   }
     219                 : 
     220               0 :   CheckedInt64 newEndOffset = aEnd;
     221               0 :   if (aEnd < -aSize) {
     222               0 :     newEndOffset = 0;
     223                 :   }
     224               0 :   else if (aEnd < 0) {
     225               0 :     newEndOffset += aSize;
     226                 :   }
     227               0 :   else if (aEnd > aSize) {
     228               0 :     newEndOffset = aSize;
     229                 :   }
     230                 : 
     231               0 :   if (!newStartOffset.valid() || !newEndOffset.valid() ||
     232               0 :       newStartOffset.value() >= newEndOffset.value()) {
     233               0 :     aStart = aEnd = 0;
     234                 :   }
     235                 :   else {
     236               0 :     aStart = newStartOffset.value();
     237               0 :     aEnd = newEndOffset.value();
     238                 :   }
     239               0 : }
     240                 : 
     241                 : NS_IMETHODIMP
     242               0 : nsDOMFileBase::Slice(PRInt64 aStart, PRInt64 aEnd,
     243                 :                      const nsAString& aContentType, PRUint8 optional_argc,
     244                 :                      nsIDOMBlob **aBlob)
     245                 : {
     246               0 :   *aBlob = nsnull;
     247                 : 
     248                 :   // Truncate aStart and aEnd so that we stay within this file.
     249                 :   PRUint64 thisLength;
     250               0 :   nsresult rv = GetSize(&thisLength);
     251               0 :   NS_ENSURE_SUCCESS(rv, rv);
     252                 : 
     253               0 :   if (optional_argc < 2) {
     254               0 :     aEnd = (PRInt64)thisLength;
     255                 :   }
     256                 : 
     257               0 :   ParseSize((PRInt64)thisLength, aStart, aEnd);
     258                 :   
     259                 :   // Create the new file
     260                 :   *aBlob = CreateSlice((PRUint64)aStart, (PRUint64)(aEnd - aStart),
     261               0 :                        aContentType).get();
     262                 : 
     263               0 :   return *aBlob ? NS_OK : NS_ERROR_UNEXPECTED;
     264                 : }
     265                 : 
     266                 : NS_IMETHODIMP
     267               0 : nsDOMFileBase::MozSlice(PRInt64 aStart, PRInt64 aEnd,
     268                 :                         const nsAString& aContentType, PRUint8 optional_argc,
     269                 :                         nsIDOMBlob **aBlob)
     270                 : {
     271               0 :   MOZ_ASSERT(NS_IsMainThread());
     272                 : 
     273               0 :   return Slice(aStart, aEnd, aContentType, optional_argc, aBlob);
     274                 : }
     275                 : 
     276                 : NS_IMETHODIMP
     277               0 : nsDOMFileBase::GetInternalStream(nsIInputStream **aStream)
     278                 : {
     279                 :   // Must be overridden
     280               0 :   NS_NOTREACHED("Must override GetInternalStream");
     281                 :   
     282               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     283                 : }
     284                 : 
     285                 : NS_IMETHODIMP
     286               2 : nsDOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
     287                 : {
     288               2 :   NS_ENSURE_STATE(aPrincipal);
     289                 : 
     290                 :   nsresult rv;
     291                 :   nsCOMPtr<nsIUUIDGenerator> uuidgen =
     292               4 :     do_GetService("@mozilla.org/uuid-generator;1", &rv);
     293               2 :   NS_ENSURE_SUCCESS(rv, rv);
     294                 :   
     295                 :   nsID id;
     296               2 :   rv = uuidgen->GenerateUUIDInPlace(&id);
     297               2 :   NS_ENSURE_SUCCESS(rv, rv);
     298                 :   
     299                 :   char chars[NSID_LENGTH];
     300               2 :   id.ToProvidedString(chars);
     301                 :     
     302               2 :   nsCString url = NS_LITERAL_CSTRING(BLOBURI_SCHEME ":") +
     303               6 :     Substring(chars + 1, chars + NSID_LENGTH - 2);
     304                 : 
     305                 :   nsBlobProtocolHandler::AddFileDataEntry(url, this,
     306               2 :                                               aPrincipal);
     307                 : 
     308               2 :   CopyASCIItoUTF16(url, aURL);
     309                 :   
     310               2 :   return NS_OK;
     311                 : }
     312                 : 
     313                 : NS_IMETHODIMP_(PRInt64)
     314               0 : nsDOMFileBase::GetFileId()
     315                 : {
     316               0 :   PRInt64 id = -1;
     317                 : 
     318               0 :   if (IsStoredFile() && IsWholeFile()) {
     319               0 :     if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
     320               0 :       indexedDB::IndexedDatabaseManager::FileMutex().Lock();
     321                 :     }
     322                 : 
     323               0 :     NS_ASSERTION(!mFileInfos.IsEmpty(),
     324                 :                  "A stored file must have at least one file info!");
     325                 : 
     326               0 :     nsRefPtr<indexedDB::FileInfo>& fileInfo = mFileInfos.ElementAt(0);
     327               0 :     if (fileInfo) {
     328               0 :       id =  fileInfo->Id();
     329                 :     }
     330                 : 
     331               0 :     if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
     332               0 :       indexedDB::IndexedDatabaseManager::FileMutex().Unlock();
     333                 :     }
     334                 :   }
     335                 : 
     336               0 :   return id;
     337                 : }
     338                 : 
     339                 : NS_IMETHODIMP_(void)
     340               0 : nsDOMFileBase::AddFileInfo(indexedDB::FileInfo* aFileInfo)
     341                 : {
     342               0 :   if (indexedDB::IndexedDatabaseManager::IsClosed()) {
     343               0 :     NS_ERROR("Shouldn't be called after shutdown!");
     344               0 :     return;
     345                 :   }
     346                 : 
     347               0 :   nsRefPtr<indexedDB::FileInfo> fileInfo = aFileInfo;
     348                 : 
     349               0 :   MutexAutoLock lock(indexedDB::IndexedDatabaseManager::FileMutex());
     350                 : 
     351               0 :   NS_ASSERTION(!mFileInfos.Contains(aFileInfo),
     352                 :                "Adding the same file info agan?!");
     353                 : 
     354               0 :   nsRefPtr<indexedDB::FileInfo>* element = mFileInfos.AppendElement();
     355               0 :   element->swap(fileInfo);
     356                 : }
     357                 : 
     358                 : NS_IMETHODIMP_(indexedDB::FileInfo*)
     359               0 : nsDOMFileBase::GetFileInfo(indexedDB::FileManager* aFileManager)
     360                 : {
     361               0 :   if (indexedDB::IndexedDatabaseManager::IsClosed()) {
     362               0 :     NS_ERROR("Shouldn't be called after shutdown!");
     363               0 :     return nsnull;
     364                 :   }
     365                 : 
     366                 :   // A slice created from a stored file must keep the file info alive.
     367                 :   // However, we don't support sharing of slices yet, so the slice must be
     368                 :   // copied again. That's why we have to ignore the first file info.
     369               0 :   PRUint32 startIndex = IsStoredFile() && !IsWholeFile() ? 1 : 0;
     370                 : 
     371               0 :   MutexAutoLock lock(indexedDB::IndexedDatabaseManager::FileMutex());
     372                 : 
     373               0 :   for (PRUint32 i = startIndex; i < mFileInfos.Length(); i++) {
     374               0 :     nsRefPtr<indexedDB::FileInfo>& fileInfo = mFileInfos.ElementAt(i);
     375               0 :     if (fileInfo->Manager() == aFileManager) {
     376               0 :       return fileInfo;
     377                 :     }
     378                 :   }
     379                 : 
     380               0 :   return nsnull;
     381                 : }
     382                 : 
     383                 : NS_IMETHODIMP
     384               0 : nsDOMFileBase::GetSendInfo(nsIInputStream** aBody,
     385                 :                            nsACString& aContentType,
     386                 :                            nsACString& aCharset)
     387                 : {
     388                 :   nsresult rv;
     389                 : 
     390               0 :   nsCOMPtr<nsIInputStream> stream;
     391               0 :   rv = this->GetInternalStream(getter_AddRefs(stream));
     392               0 :   NS_ENSURE_SUCCESS(rv, rv);
     393                 : 
     394               0 :   nsString contentType;
     395               0 :   rv = this->GetType(contentType);
     396               0 :   NS_ENSURE_SUCCESS(rv, rv);
     397                 : 
     398               0 :   CopyUTF16toUTF8(contentType, aContentType);
     399                 : 
     400               0 :   aCharset.Truncate();
     401                 : 
     402               0 :   stream.forget(aBody);
     403               0 :   return NS_OK;
     404                 : }
     405                 : 
     406                 : NS_IMETHODIMP
     407               0 : nsDOMFileBase::GetMutable(bool* aMutable)
     408                 : {
     409               0 :   *aMutable = !mImmutable;
     410               0 :   return NS_OK;
     411                 : }
     412                 : 
     413                 : NS_IMETHODIMP
     414               0 : nsDOMFileBase::SetMutable(bool aMutable)
     415                 : {
     416               0 :   nsresult rv = NS_OK;
     417                 : 
     418               0 :   NS_ENSURE_ARG(!mImmutable || !aMutable);
     419                 : 
     420               0 :   if (!mImmutable && !aMutable) {
     421                 :     // Force the content type and size to be cached
     422               0 :     nsString dummyString;
     423               0 :     rv = this->GetType(dummyString);
     424               0 :     NS_ENSURE_SUCCESS(rv, rv);
     425                 : 
     426                 :     PRUint64 dummyInt;
     427               0 :     rv = this->GetSize(&dummyInt);
     428               0 :     NS_ENSURE_SUCCESS(rv, rv);
     429                 :   }
     430                 : 
     431               0 :   mImmutable = !aMutable;
     432               0 :   return rv;
     433                 : }
     434                 : 
     435                 : ////////////////////////////////////////////////////////////////////////////
     436                 : // nsDOMFileFile implementation
     437                 : 
     438             194 : NS_IMPL_ISUPPORTS_INHERITED1(nsDOMFileFile, nsDOMFileBase,
     439                 :                              nsIJSNativeInitializer)
     440                 : 
     441                 : already_AddRefed<nsIDOMBlob>
     442               0 : nsDOMFileFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
     443                 :                            const nsAString& aContentType)
     444                 : {
     445               0 :   nsCOMPtr<nsIDOMBlob> t = new nsDOMFileFile(this, aStart, aLength, aContentType);
     446               0 :   return t.forget();
     447                 : }
     448                 : 
     449                 : /* static */ nsresult
     450              10 : nsDOMFileFile::NewFile(nsISupports* *aNewObject)
     451                 : {
     452              20 :   nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMFileFile());
     453              10 :   file.forget(aNewObject);
     454              10 :   return NS_OK;
     455                 : }
     456                 : 
     457                 : NS_IMETHODIMP
     458               0 : nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
     459                 : {
     460               0 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     461               0 :   return mFile->GetPath(aFilename);
     462                 : }
     463                 : 
     464                 : NS_IMETHODIMP
     465               2 : nsDOMFileFile::GetSize(PRUint64 *aFileSize)
     466                 : {
     467               2 :   if (IsSizeUnknown()) {
     468               2 :     NS_ASSERTION(mWholeFile,
     469                 :                  "Should only use lazy size when using the whole file");
     470                 :     PRInt64 fileSize;
     471               2 :     nsresult rv = mFile->GetFileSize(&fileSize);
     472               2 :     NS_ENSURE_SUCCESS(rv, rv);
     473                 :   
     474               2 :     if (fileSize < 0) {
     475               0 :       return NS_ERROR_FAILURE;
     476                 :     }
     477                 :   
     478               2 :     mLength = fileSize;
     479                 :   }
     480                 : 
     481               2 :   *aFileSize = mLength;
     482                 : 
     483               2 :   return NS_OK;
     484                 : }
     485                 : 
     486                 : NS_IMETHODIMP
     487               2 : nsDOMFileFile::GetType(nsAString &aType)
     488                 : {
     489               2 :   if (mContentType.IsVoid()) {
     490               2 :     NS_ASSERTION(mWholeFile,
     491                 :                  "Should only use lazy ContentType when using the whole file");
     492                 :     nsresult rv;
     493                 :     nsCOMPtr<nsIMIMEService> mimeService =
     494               4 :       do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
     495               2 :     NS_ENSURE_SUCCESS(rv, rv);
     496                 : 
     497               6 :     nsCAutoString mimeType;
     498               2 :     rv = mimeService->GetTypeFromFile(mFile, mimeType);
     499               2 :     if (NS_FAILED(rv)) {
     500               2 :       mimeType.Truncate();
     501                 :     }
     502                 : 
     503               2 :     AppendUTF8toUTF16(mimeType, mContentType);
     504               2 :     mContentType.SetIsVoid(false);
     505                 :   }
     506                 : 
     507               2 :   aType = mContentType;
     508                 : 
     509               2 :   return NS_OK;
     510                 : }
     511                 : 
     512                 : const PRUint32 sFileStreamFlags =
     513                 :   nsIFileInputStream::CLOSE_ON_EOF |
     514                 :   nsIFileInputStream::REOPEN_ON_REWIND |
     515                 :   nsIFileInputStream::DEFER_OPEN;
     516                 : 
     517                 : NS_IMETHODIMP
     518               2 : nsDOMFileFile::GetInternalStream(nsIInputStream **aStream)
     519                 : {
     520                 :   return mWholeFile ?
     521               2 :     NS_NewLocalFileInputStream(aStream, mFile, -1, -1, sFileStreamFlags) :
     522                 :     NS_NewPartialLocalFileInputStream(aStream, mFile, mStart, mLength,
     523               4 :                                       -1, -1, sFileStreamFlags);
     524                 : }
     525                 : 
     526                 : NS_IMETHODIMP
     527              10 : nsDOMFileFile::Initialize(nsISupports* aOwner,
     528                 :                           JSContext* aCx,
     529                 :                           JSObject* aObj,
     530                 :                           PRUint32 aArgc,
     531                 :                           jsval* aArgv)
     532                 : {
     533                 :   nsresult rv;
     534                 : 
     535              10 :   NS_ASSERTION(!mImmutable, "Something went wrong ...");
     536              10 :   NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
     537                 : 
     538              10 :   if (!nsContentUtils::IsCallerChrome()) {
     539               0 :     return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
     540                 :   }
     541                 : 
     542              10 :   NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
     543                 : 
     544                 :   // We expect to get a path to represent as a File object,
     545                 :   // or an nsIFile
     546              20 :   nsCOMPtr<nsIFile> file;
     547              10 :   if (!JSVAL_IS_STRING(aArgv[0])) {
     548                 :     // Lets see if it's an nsIFile
     549               6 :     if (!JSVAL_IS_OBJECT(aArgv[0])) {
     550               0 :       return NS_ERROR_UNEXPECTED; // We're not interested
     551                 :     }
     552                 : 
     553               6 :     JSObject* obj = JSVAL_TO_OBJECT(aArgv[0]);
     554               6 :     NS_ASSERTION(obj, "This is a bit odd");
     555                 : 
     556                 :     // Is it an nsIFile
     557                 :     file = do_QueryInterface(
     558               6 :       nsContentUtils::XPConnect()->
     559               6 :         GetNativeOfWrapper(aCx, obj));
     560               6 :     if (!file)
     561               0 :       return NS_ERROR_UNEXPECTED;
     562                 :   } else {
     563                 :     // It's a string
     564               4 :     JSString* str = JS_ValueToString(aCx, aArgv[0]);
     565               4 :     NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
     566                 : 
     567               8 :     nsDependentJSString xpcomStr;
     568               4 :     if (!xpcomStr.init(aCx, str)) {
     569               0 :       return NS_ERROR_XPC_BAD_CONVERT_JS;
     570                 :     }
     571                 : 
     572               8 :     nsCOMPtr<nsILocalFile> localFile;
     573               4 :     rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(localFile));
     574               4 :     NS_ENSURE_SUCCESS(rv, rv);
     575                 : 
     576               3 :     file = do_QueryInterface(localFile);
     577               3 :     NS_ASSERTION(file, "This should never happen");
     578                 :   }
     579                 : 
     580                 :   bool exists;
     581               9 :   rv = file->Exists(&exists);
     582               9 :   NS_ENSURE_SUCCESS(rv, rv);
     583               9 :   NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
     584                 : 
     585                 :   bool isDir;
     586               9 :   rv = file->IsDirectory(&isDir);
     587               9 :   NS_ENSURE_SUCCESS(rv, rv);
     588               9 :   NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
     589                 : 
     590               8 :   mFile = file;
     591               8 :   file->GetLeafName(mName);
     592                 : 
     593               8 :   return NS_OK;
     594                 : }
     595                 : 
     596                 : ////////////////////////////////////////////////////////////////////////////
     597                 : // nsDOMMemoryFile implementation
     598                 : 
     599                 : already_AddRefed<nsIDOMBlob>
     600               0 : nsDOMMemoryFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
     601                 :                              const nsAString& aContentType)
     602                 : {
     603                 :   nsCOMPtr<nsIDOMBlob> t =
     604               0 :     new nsDOMMemoryFile(this, aStart, aLength, aContentType);
     605               0 :   return t.forget();
     606                 : }
     607                 : 
     608                 : NS_IMETHODIMP
     609               0 : nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
     610                 : {
     611               0 :   if (mLength > PR_INT32_MAX)
     612               0 :     return NS_ERROR_FAILURE;
     613                 : 
     614               0 :   return DataOwnerAdapter::Create(mDataOwner, mStart, mLength, aStream);
     615                 : }
     616                 : 
     617                 : ////////////////////////////////////////////////////////////////////////////
     618                 : // nsDOMFileList implementation
     619                 : 
     620                 : DOMCI_DATA(FileList, nsDOMFileList)
     621                 : 
     622            1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileList)
     623               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMFileList)
     624               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
     625               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     626               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMFileList)
     627               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
     628               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     629               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMFileList)
     630               0 :   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
     631               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     632                 : 
     633               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMFileList)
     634               0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     635               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
     636               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
     637               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileList)
     638               0 : NS_INTERFACE_MAP_END
     639                 : 
     640               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMFileList)
     641               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileList)
     642                 : 
     643                 : JSObject*
     644               0 : nsDOMFileList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
     645                 :                           bool *triedToWrap)
     646                 : {
     647               0 :   return mozilla::dom::binding::FileList::create(cx, scope, this, triedToWrap);
     648                 : }
     649                 : 
     650                 : nsIDOMFile*
     651               0 : nsDOMFileList::GetItemAt(PRUint32 aIndex)
     652                 : {
     653               0 :   return mFiles.SafeObjectAt(aIndex);
     654                 : }
     655                 : 
     656                 : NS_IMETHODIMP
     657               0 : nsDOMFileList::GetLength(PRUint32* aLength)
     658                 : {
     659               0 :   *aLength = mFiles.Count();
     660                 : 
     661               0 :   return NS_OK;
     662                 : }
     663                 : 
     664                 : NS_IMETHODIMP
     665               0 : nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
     666                 : {
     667               0 :   NS_IF_ADDREF(*aFile = nsDOMFileList::GetItemAt(aIndex));
     668                 : 
     669               0 :   return NS_OK;
     670                 : }
     671                 : 
     672                 : ////////////////////////////////////////////////////////////////////////////
     673                 : // nsDOMFileInternalUrlHolder implementation
     674                 : 
     675               2 : nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile,
     676                 :                                                        nsIPrincipal* aPrincipal
     677               2 :                                                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
     678               2 :   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     679               2 :   aFile->GetInternalUrl(aPrincipal, mUrl);
     680               2 : }
     681                 :  
     682               4 : nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() {
     683               2 :   if (!mUrl.IsEmpty()) {
     684               4 :     nsCAutoString narrowUrl;
     685               2 :     CopyUTF16toUTF8(mUrl, narrowUrl);
     686               2 :     nsBlobProtocolHandler::RemoveFileDataEntry(narrowUrl);
     687                 :   }
     688            4394 : }

Generated by: LCOV version 1.7