LCOV - code coverage report
Current view: directory - content/base/src - nsDOMFile.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 268 100 37.3 %
Date: 2012-04-21 Functions: 59 17 28.8 %

       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_CONDITIONAL(nsIDOMFile, mIsFile)
     146              42 :   NS_INTERFACE_MAP_ENTRY(nsIXHRSendable)
     147              42 :   NS_INTERFACE_MAP_ENTRY(nsIMutable)
     148              42 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(File, mIsFile)
     149              34 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(Blob, !mIsFile)
     150              34 : NS_INTERFACE_MAP_END
     151                 : 
     152                 : // Threadsafe when GetMutable() == false
     153              52 : NS_IMPL_THREADSAFE_ADDREF(nsDOMFileBase)
     154              52 : NS_IMPL_THREADSAFE_RELEASE(nsDOMFileBase)
     155                 : 
     156                 : NS_IMETHODIMP
     157               6 : nsDOMFileBase::GetName(nsAString &aFileName)
     158                 : {
     159               6 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     160               6 :   aFileName = mName;
     161               6 :   return NS_OK;
     162                 : }
     163                 : 
     164                 : NS_IMETHODIMP
     165               0 : nsDOMFileBase::GetMozFullPath(nsAString &aFileName)
     166                 : {
     167               0 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     168                 : 
     169                 :   // It is unsafe to call CallerHasUniversalXPConnect on a non-main thread. If
     170                 :   // you hit the following assertion you need to figure out some other way to
     171                 :   // determine privileges and call GetMozFullPathInternal.
     172               0 :   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
     173                 : 
     174               0 :   if (nsContentUtils::CallerHasUniversalXPConnect()) {
     175               0 :     return GetMozFullPathInternal(aFileName);
     176                 :   }
     177               0 :   aFileName.Truncate();
     178               0 :   return NS_OK;
     179                 : }
     180                 : 
     181                 : NS_IMETHODIMP
     182               0 : nsDOMFileBase::GetMozFullPathInternal(nsAString &aFileName)
     183                 : {
     184               0 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     185               0 :   aFileName.Truncate();
     186               0 :   return NS_OK;
     187                 : }
     188                 : 
     189                 : NS_IMETHODIMP
     190               0 : nsDOMFileBase::GetSize(PRUint64 *aSize)
     191                 : {
     192               0 :   *aSize = mLength;
     193               0 :   return NS_OK;
     194                 : }
     195                 : 
     196                 : NS_IMETHODIMP
     197               0 : nsDOMFileBase::GetType(nsAString &aType)
     198                 : {
     199               0 :   aType = mContentType;
     200               0 :   return NS_OK;
     201                 : }
     202                 : 
     203                 : // Makes sure that aStart and aEnd is less then or equal to aSize and greater
     204                 : // than 0
     205                 : static void
     206               0 : ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
     207                 : {
     208               0 :   CheckedInt64 newStartOffset = aStart;
     209               0 :   if (aStart < -aSize) {
     210               0 :     newStartOffset = 0;
     211                 :   }
     212               0 :   else if (aStart < 0) {
     213               0 :     newStartOffset += aSize;
     214                 :   }
     215               0 :   else if (aStart > aSize) {
     216               0 :     newStartOffset = aSize;
     217                 :   }
     218                 : 
     219               0 :   CheckedInt64 newEndOffset = aEnd;
     220               0 :   if (aEnd < -aSize) {
     221               0 :     newEndOffset = 0;
     222                 :   }
     223               0 :   else if (aEnd < 0) {
     224               0 :     newEndOffset += aSize;
     225                 :   }
     226               0 :   else if (aEnd > aSize) {
     227               0 :     newEndOffset = aSize;
     228                 :   }
     229                 : 
     230               0 :   if (!newStartOffset.valid() || !newEndOffset.valid() ||
     231               0 :       newStartOffset.value() >= newEndOffset.value()) {
     232               0 :     aStart = aEnd = 0;
     233                 :   }
     234                 :   else {
     235               0 :     aStart = newStartOffset.value();
     236               0 :     aEnd = newEndOffset.value();
     237                 :   }
     238               0 : }
     239                 : 
     240                 : NS_IMETHODIMP
     241               0 : nsDOMFileBase::Slice(PRInt64 aStart, PRInt64 aEnd,
     242                 :                      const nsAString& aContentType, PRUint8 optional_argc,
     243                 :                      nsIDOMBlob **aBlob)
     244                 : {
     245               0 :   *aBlob = nsnull;
     246                 : 
     247                 :   // Truncate aStart and aEnd so that we stay within this file.
     248                 :   PRUint64 thisLength;
     249               0 :   nsresult rv = GetSize(&thisLength);
     250               0 :   NS_ENSURE_SUCCESS(rv, rv);
     251                 : 
     252               0 :   if (optional_argc < 2) {
     253               0 :     aEnd = (PRInt64)thisLength;
     254                 :   }
     255                 : 
     256               0 :   ParseSize((PRInt64)thisLength, aStart, aEnd);
     257                 :   
     258                 :   // Create the new file
     259                 :   *aBlob = CreateSlice((PRUint64)aStart, (PRUint64)(aEnd - aStart),
     260               0 :                        aContentType).get();
     261                 : 
     262               0 :   return *aBlob ? NS_OK : NS_ERROR_UNEXPECTED;
     263                 : }
     264                 : 
     265                 : NS_IMETHODIMP
     266               0 : nsDOMFileBase::GetInternalStream(nsIInputStream **aStream)
     267                 : {
     268                 :   // Must be overridden
     269               0 :   NS_NOTREACHED("Must override GetInternalStream");
     270                 :   
     271               0 :   return NS_ERROR_NOT_IMPLEMENTED;
     272                 : }
     273                 : 
     274                 : NS_IMETHODIMP
     275               2 : nsDOMFileBase::GetInternalUrl(nsIPrincipal* aPrincipal, nsAString& aURL)
     276                 : {
     277               2 :   NS_ENSURE_STATE(aPrincipal);
     278                 : 
     279                 :   nsresult rv;
     280                 :   nsCOMPtr<nsIUUIDGenerator> uuidgen =
     281               4 :     do_GetService("@mozilla.org/uuid-generator;1", &rv);
     282               2 :   NS_ENSURE_SUCCESS(rv, rv);
     283                 :   
     284                 :   nsID id;
     285               2 :   rv = uuidgen->GenerateUUIDInPlace(&id);
     286               2 :   NS_ENSURE_SUCCESS(rv, rv);
     287                 :   
     288                 :   char chars[NSID_LENGTH];
     289               2 :   id.ToProvidedString(chars);
     290                 :     
     291               2 :   nsCString url = NS_LITERAL_CSTRING(BLOBURI_SCHEME ":") +
     292               6 :     Substring(chars + 1, chars + NSID_LENGTH - 2);
     293                 : 
     294                 :   nsBlobProtocolHandler::AddFileDataEntry(url, this,
     295               2 :                                               aPrincipal);
     296                 : 
     297               2 :   CopyASCIItoUTF16(url, aURL);
     298                 :   
     299               2 :   return NS_OK;
     300                 : }
     301                 : 
     302                 : NS_IMETHODIMP_(PRInt64)
     303               0 : nsDOMFileBase::GetFileId()
     304                 : {
     305               0 :   PRInt64 id = -1;
     306                 : 
     307               0 :   if (IsStoredFile() && IsWholeFile()) {
     308               0 :     if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
     309               0 :       indexedDB::IndexedDatabaseManager::FileMutex().Lock();
     310                 :     }
     311                 : 
     312               0 :     NS_ASSERTION(!mFileInfos.IsEmpty(),
     313                 :                  "A stored file must have at least one file info!");
     314                 : 
     315               0 :     nsRefPtr<indexedDB::FileInfo>& fileInfo = mFileInfos.ElementAt(0);
     316               0 :     if (fileInfo) {
     317               0 :       id =  fileInfo->Id();
     318                 :     }
     319                 : 
     320               0 :     if (!indexedDB::IndexedDatabaseManager::IsClosed()) {
     321               0 :       indexedDB::IndexedDatabaseManager::FileMutex().Unlock();
     322                 :     }
     323                 :   }
     324                 : 
     325               0 :   return id;
     326                 : }
     327                 : 
     328                 : NS_IMETHODIMP_(void)
     329               0 : nsDOMFileBase::AddFileInfo(indexedDB::FileInfo* aFileInfo)
     330                 : {
     331               0 :   if (indexedDB::IndexedDatabaseManager::IsClosed()) {
     332               0 :     NS_ERROR("Shouldn't be called after shutdown!");
     333               0 :     return;
     334                 :   }
     335                 : 
     336               0 :   nsRefPtr<indexedDB::FileInfo> fileInfo = aFileInfo;
     337                 : 
     338               0 :   MutexAutoLock lock(indexedDB::IndexedDatabaseManager::FileMutex());
     339                 : 
     340               0 :   NS_ASSERTION(!mFileInfos.Contains(aFileInfo),
     341                 :                "Adding the same file info agan?!");
     342                 : 
     343               0 :   nsRefPtr<indexedDB::FileInfo>* element = mFileInfos.AppendElement();
     344               0 :   element->swap(fileInfo);
     345                 : }
     346                 : 
     347                 : NS_IMETHODIMP_(indexedDB::FileInfo*)
     348               0 : nsDOMFileBase::GetFileInfo(indexedDB::FileManager* aFileManager)
     349                 : {
     350               0 :   if (indexedDB::IndexedDatabaseManager::IsClosed()) {
     351               0 :     NS_ERROR("Shouldn't be called after shutdown!");
     352               0 :     return nsnull;
     353                 :   }
     354                 : 
     355                 :   // A slice created from a stored file must keep the file info alive.
     356                 :   // However, we don't support sharing of slices yet, so the slice must be
     357                 :   // copied again. That's why we have to ignore the first file info.
     358               0 :   PRUint32 startIndex = IsStoredFile() && !IsWholeFile() ? 1 : 0;
     359                 : 
     360               0 :   MutexAutoLock lock(indexedDB::IndexedDatabaseManager::FileMutex());
     361                 : 
     362               0 :   for (PRUint32 i = startIndex; i < mFileInfos.Length(); i++) {
     363               0 :     nsRefPtr<indexedDB::FileInfo>& fileInfo = mFileInfos.ElementAt(i);
     364               0 :     if (fileInfo->Manager() == aFileManager) {
     365               0 :       return fileInfo;
     366                 :     }
     367                 :   }
     368                 : 
     369               0 :   return nsnull;
     370                 : }
     371                 : 
     372                 : NS_IMETHODIMP
     373               0 : nsDOMFileBase::GetSendInfo(nsIInputStream** aBody,
     374                 :                            nsACString& aContentType,
     375                 :                            nsACString& aCharset)
     376                 : {
     377                 :   nsresult rv;
     378                 : 
     379               0 :   nsCOMPtr<nsIInputStream> stream;
     380               0 :   rv = this->GetInternalStream(getter_AddRefs(stream));
     381               0 :   NS_ENSURE_SUCCESS(rv, rv);
     382                 : 
     383               0 :   nsString contentType;
     384               0 :   rv = this->GetType(contentType);
     385               0 :   NS_ENSURE_SUCCESS(rv, rv);
     386                 : 
     387               0 :   CopyUTF16toUTF8(contentType, aContentType);
     388                 : 
     389               0 :   aCharset.Truncate();
     390                 : 
     391               0 :   stream.forget(aBody);
     392               0 :   return NS_OK;
     393                 : }
     394                 : 
     395                 : NS_IMETHODIMP
     396               0 : nsDOMFileBase::GetMutable(bool* aMutable)
     397                 : {
     398               0 :   *aMutable = !mImmutable;
     399               0 :   return NS_OK;
     400                 : }
     401                 : 
     402                 : NS_IMETHODIMP
     403               0 : nsDOMFileBase::SetMutable(bool aMutable)
     404                 : {
     405               0 :   nsresult rv = NS_OK;
     406                 : 
     407               0 :   NS_ENSURE_ARG(!mImmutable || !aMutable);
     408                 : 
     409               0 :   if (!mImmutable && !aMutable) {
     410                 :     // Force the content type and size to be cached
     411               0 :     nsString dummyString;
     412               0 :     rv = this->GetType(dummyString);
     413               0 :     NS_ENSURE_SUCCESS(rv, rv);
     414                 : 
     415                 :     PRUint64 dummyInt;
     416               0 :     rv = this->GetSize(&dummyInt);
     417               0 :     NS_ENSURE_SUCCESS(rv, rv);
     418                 :   }
     419                 : 
     420               0 :   mImmutable = !aMutable;
     421               0 :   return rv;
     422                 : }
     423                 : 
     424                 : ////////////////////////////////////////////////////////////////////////////
     425                 : // nsDOMFileFile implementation
     426                 : 
     427             194 : NS_IMPL_ISUPPORTS_INHERITED1(nsDOMFileFile, nsDOMFileBase,
     428                 :                              nsIJSNativeInitializer)
     429                 : 
     430                 : already_AddRefed<nsIDOMBlob>
     431               0 : nsDOMFileFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
     432                 :                            const nsAString& aContentType)
     433                 : {
     434               0 :   nsCOMPtr<nsIDOMBlob> t = new nsDOMFileFile(this, aStart, aLength, aContentType);
     435               0 :   return t.forget();
     436                 : }
     437                 : 
     438                 : /* static */ nsresult
     439              10 : nsDOMFileFile::NewFile(nsISupports* *aNewObject)
     440                 : {
     441              20 :   nsCOMPtr<nsISupports> file = do_QueryObject(new nsDOMFileFile());
     442              10 :   file.forget(aNewObject);
     443              10 :   return NS_OK;
     444                 : }
     445                 : 
     446                 : NS_IMETHODIMP
     447               0 : nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
     448                 : {
     449               0 :   NS_ASSERTION(mIsFile, "Should only be called on files");
     450               0 :   return mFile->GetPath(aFilename);
     451                 : }
     452                 : 
     453                 : NS_IMETHODIMP
     454               2 : nsDOMFileFile::GetSize(PRUint64 *aFileSize)
     455                 : {
     456               2 :   if (IsSizeUnknown()) {
     457               2 :     NS_ASSERTION(mWholeFile,
     458                 :                  "Should only use lazy size when using the whole file");
     459                 :     PRInt64 fileSize;
     460               2 :     nsresult rv = mFile->GetFileSize(&fileSize);
     461               2 :     NS_ENSURE_SUCCESS(rv, rv);
     462                 :   
     463               2 :     if (fileSize < 0) {
     464               0 :       return NS_ERROR_FAILURE;
     465                 :     }
     466                 :   
     467               2 :     mLength = fileSize;
     468                 :   }
     469                 : 
     470               2 :   *aFileSize = mLength;
     471                 : 
     472               2 :   return NS_OK;
     473                 : }
     474                 : 
     475                 : NS_IMETHODIMP
     476               2 : nsDOMFileFile::GetType(nsAString &aType)
     477                 : {
     478               2 :   if (mContentType.IsVoid()) {
     479               2 :     NS_ASSERTION(mWholeFile,
     480                 :                  "Should only use lazy ContentType when using the whole file");
     481                 :     nsresult rv;
     482                 :     nsCOMPtr<nsIMIMEService> mimeService =
     483               4 :       do_GetService(NS_MIMESERVICE_CONTRACTID, &rv);
     484               2 :     NS_ENSURE_SUCCESS(rv, rv);
     485                 : 
     486               6 :     nsCAutoString mimeType;
     487               2 :     rv = mimeService->GetTypeFromFile(mFile, mimeType);
     488               2 :     if (NS_FAILED(rv)) {
     489               2 :       mimeType.Truncate();
     490                 :     }
     491                 : 
     492               2 :     AppendUTF8toUTF16(mimeType, mContentType);
     493               2 :     mContentType.SetIsVoid(false);
     494                 :   }
     495                 : 
     496               2 :   aType = mContentType;
     497                 : 
     498               2 :   return NS_OK;
     499                 : }
     500                 : 
     501                 : const PRUint32 sFileStreamFlags =
     502                 :   nsIFileInputStream::CLOSE_ON_EOF |
     503                 :   nsIFileInputStream::REOPEN_ON_REWIND |
     504                 :   nsIFileInputStream::DEFER_OPEN;
     505                 : 
     506                 : NS_IMETHODIMP
     507               2 : nsDOMFileFile::GetInternalStream(nsIInputStream **aStream)
     508                 : {
     509                 :   return mWholeFile ?
     510               2 :     NS_NewLocalFileInputStream(aStream, mFile, -1, -1, sFileStreamFlags) :
     511                 :     NS_NewPartialLocalFileInputStream(aStream, mFile, mStart, mLength,
     512               4 :                                       -1, -1, sFileStreamFlags);
     513                 : }
     514                 : 
     515                 : NS_IMETHODIMP
     516              10 : nsDOMFileFile::Initialize(nsISupports* aOwner,
     517                 :                           JSContext* aCx,
     518                 :                           JSObject* aObj,
     519                 :                           PRUint32 aArgc,
     520                 :                           jsval* aArgv)
     521                 : {
     522                 :   nsresult rv;
     523                 : 
     524              10 :   NS_ASSERTION(!mImmutable, "Something went wrong ...");
     525              10 :   NS_ENSURE_TRUE(!mImmutable, NS_ERROR_UNEXPECTED);
     526                 : 
     527              10 :   if (!nsContentUtils::IsCallerChrome()) {
     528               0 :     return NS_ERROR_DOM_SECURITY_ERR; // Real short trip
     529                 :   }
     530                 : 
     531              10 :   NS_ENSURE_TRUE(aArgc > 0, NS_ERROR_UNEXPECTED);
     532                 : 
     533                 :   // We expect to get a path to represent as a File object,
     534                 :   // or an nsIFile
     535              20 :   nsCOMPtr<nsIFile> file;
     536              10 :   if (!JSVAL_IS_STRING(aArgv[0])) {
     537                 :     // Lets see if it's an nsIFile
     538               6 :     if (!JSVAL_IS_OBJECT(aArgv[0])) {
     539               0 :       return NS_ERROR_UNEXPECTED; // We're not interested
     540                 :     }
     541                 : 
     542               6 :     JSObject* obj = JSVAL_TO_OBJECT(aArgv[0]);
     543               6 :     NS_ASSERTION(obj, "This is a bit odd");
     544                 : 
     545                 :     // Is it an nsIFile
     546                 :     file = do_QueryInterface(
     547               6 :       nsContentUtils::XPConnect()->
     548               6 :         GetNativeOfWrapper(aCx, obj));
     549               6 :     if (!file)
     550               0 :       return NS_ERROR_UNEXPECTED;
     551                 :   } else {
     552                 :     // It's a string
     553               4 :     JSString* str = JS_ValueToString(aCx, aArgv[0]);
     554               4 :     NS_ENSURE_TRUE(str, NS_ERROR_XPC_BAD_CONVERT_JS);
     555                 : 
     556               8 :     nsDependentJSString xpcomStr;
     557               4 :     if (!xpcomStr.init(aCx, str)) {
     558               0 :       return NS_ERROR_XPC_BAD_CONVERT_JS;
     559                 :     }
     560                 : 
     561               8 :     nsCOMPtr<nsILocalFile> localFile;
     562               4 :     rv = NS_NewLocalFile(xpcomStr, false, getter_AddRefs(localFile));
     563               4 :     NS_ENSURE_SUCCESS(rv, rv);
     564                 : 
     565               3 :     file = do_QueryInterface(localFile);
     566               3 :     NS_ASSERTION(file, "This should never happen");
     567                 :   }
     568                 : 
     569                 :   bool exists;
     570               9 :   rv = file->Exists(&exists);
     571               9 :   NS_ENSURE_SUCCESS(rv, rv);
     572               9 :   NS_ENSURE_TRUE(exists, NS_ERROR_FILE_NOT_FOUND);
     573                 : 
     574                 :   bool isDir;
     575               9 :   rv = file->IsDirectory(&isDir);
     576               9 :   NS_ENSURE_SUCCESS(rv, rv);
     577               9 :   NS_ENSURE_FALSE(isDir, NS_ERROR_FILE_IS_DIRECTORY);
     578                 : 
     579               8 :   mFile = file;
     580               8 :   file->GetLeafName(mName);
     581                 : 
     582               8 :   return NS_OK;
     583                 : }
     584                 : 
     585                 : ////////////////////////////////////////////////////////////////////////////
     586                 : // nsDOMMemoryFile implementation
     587                 : 
     588                 : already_AddRefed<nsIDOMBlob>
     589               0 : nsDOMMemoryFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
     590                 :                              const nsAString& aContentType)
     591                 : {
     592                 :   nsCOMPtr<nsIDOMBlob> t =
     593               0 :     new nsDOMMemoryFile(this, aStart, aLength, aContentType);
     594               0 :   return t.forget();
     595                 : }
     596                 : 
     597                 : NS_IMETHODIMP
     598               0 : nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
     599                 : {
     600               0 :   if (mLength > PR_INT32_MAX)
     601               0 :     return NS_ERROR_FAILURE;
     602                 : 
     603               0 :   return DataOwnerAdapter::Create(mDataOwner, mStart, mLength, aStream);
     604                 : }
     605                 : 
     606                 : ////////////////////////////////////////////////////////////////////////////
     607                 : // nsDOMFileList implementation
     608                 : 
     609                 : DOMCI_DATA(FileList, nsDOMFileList)
     610                 : 
     611            1396 : NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileList)
     612               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMFileList)
     613               0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
     614               0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     615               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMFileList)
     616               0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
     617               0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     618               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMFileList)
     619               0 :   NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
     620               0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     621                 : 
     622               0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMFileList)
     623               0 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     624               0 :   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMFileList)
     625               0 :   NS_INTERFACE_MAP_ENTRY(nsIDOMFileList)
     626               0 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(FileList)
     627               0 : NS_INTERFACE_MAP_END
     628                 : 
     629               0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMFileList)
     630               0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMFileList)
     631                 : 
     632                 : JSObject*
     633               0 : nsDOMFileList::WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,
     634                 :                           bool *triedToWrap)
     635                 : {
     636               0 :   return mozilla::dom::binding::FileList::create(cx, scope, this, triedToWrap);
     637                 : }
     638                 : 
     639                 : nsIDOMFile*
     640               0 : nsDOMFileList::GetItemAt(PRUint32 aIndex)
     641                 : {
     642               0 :   return mFiles.SafeObjectAt(aIndex);
     643                 : }
     644                 : 
     645                 : NS_IMETHODIMP
     646               0 : nsDOMFileList::GetLength(PRUint32* aLength)
     647                 : {
     648               0 :   *aLength = mFiles.Count();
     649                 : 
     650               0 :   return NS_OK;
     651                 : }
     652                 : 
     653                 : NS_IMETHODIMP
     654               0 : nsDOMFileList::Item(PRUint32 aIndex, nsIDOMFile **aFile)
     655                 : {
     656               0 :   NS_IF_ADDREF(*aFile = nsDOMFileList::GetItemAt(aIndex));
     657                 : 
     658               0 :   return NS_OK;
     659                 : }
     660                 : 
     661                 : ////////////////////////////////////////////////////////////////////////////
     662                 : // nsDOMFileInternalUrlHolder implementation
     663                 : 
     664               2 : nsDOMFileInternalUrlHolder::nsDOMFileInternalUrlHolder(nsIDOMBlob* aFile,
     665                 :                                                        nsIPrincipal* aPrincipal
     666               2 :                                                        MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
     667               2 :   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     668               2 :   aFile->GetInternalUrl(aPrincipal, mUrl);
     669               2 : }
     670                 :  
     671               4 : nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() {
     672               2 :   if (!mUrl.IsEmpty()) {
     673               4 :     nsCAutoString narrowUrl;
     674               2 :     CopyUTF16toUTF8(mUrl, narrowUrl);
     675               2 :     nsBlobProtocolHandler::RemoveFileDataEntry(narrowUrl);
     676                 :   }
     677            4190 : }

Generated by: LCOV version 1.7