Bug 781425 - Part 2: getFiles(). r=khuey, r=mounir
authorAndrea Marchesini <amarchesini@mozilla.com>
Tue, 06 Nov 2012 18:23:13 -0500
changeset 112486 36a99706bcbec2f42833abd09c01c944ce734769
parent 112485 5bc6448929cbf262a088aaba89c268c71b94e8d9
child 112487 098958fa76f3be74c293989a67ccc16b631e308b
push id23825
push useremorley@mozilla.com
push dateWed, 07 Nov 2012 12:53:10 +0000
treeherdermozilla-central@8671bfc8e9a8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhuey, mounir
bugs781425
milestone19.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 781425 - Part 2: getFiles(). r=khuey, r=mounir
dom/file/ArchiveReader.cpp
dom/file/ArchiveReader.h
dom/file/ArchiveRequest.cpp
dom/file/ArchiveRequest.h
dom/file/nsIDOMArchiveReader.idl
dom/file/test/test_archivereader.html
--- a/dom/file/ArchiveReader.cpp
+++ b/dom/file/ArchiveReader.cpp
@@ -187,16 +187,27 @@ ArchiveReader::GetFile(const nsAString& 
 {
   nsRefPtr<ArchiveRequest> request = GenerateArchiveRequest();
   request->OpGetFile(filename);
 
   request.forget(_retval);
   return NS_OK;
 }
 
+/* nsIDOMArchiveRequest getFiles (); */
+NS_IMETHODIMP
+ArchiveReader::GetFiles(nsIDOMArchiveRequest** _retval)
+{
+  nsRefPtr<ArchiveRequest> request = GenerateArchiveRequest();
+  request->OpGetFiles();
+
+  request.forget(_retval);
+  return NS_OK;
+}
+
 already_AddRefed<ArchiveRequest>
 ArchiveReader::GenerateArchiveRequest()
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
   return ArchiveRequest::Create(mWindow, this);
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(ArchiveReader)
--- a/dom/file/ArchiveReader.h
+++ b/dom/file/ArchiveReader.h
@@ -38,17 +38,17 @@ public:
 
   ArchiveReader();
 
   // nsIJSNativeInitializer
   NS_IMETHOD Initialize(nsISupports* aOwner,
                         JSContext* aCx,
                         JSObject* aObj,
                         uint32_t aArgc,
-                        jsval* aArgv);
+                        JS::Value* aArgv);
 
   nsresult GetInputStream(nsIInputStream** aInputStream);
   nsresult GetSize(uint64_t* aSize);
 
 public: // for the ArchiveRequest:
   nsresult RegisterRequest(ArchiveRequest* aRequest);
 
 public: // For events:
--- a/dom/file/ArchiveRequest.cpp
+++ b/dom/file/ArchiveRequest.cpp
@@ -103,26 +103,32 @@ ArchiveRequest::OpGetFilenames()
 
 void
 ArchiveRequest::OpGetFile(const nsAString& aFilename)
 {
   mOperation = GetFile;
   mFilename = aFilename;
 }
 
+void
+ArchiveRequest::OpGetFiles()
+{
+  mOperation = GetFiles;
+}
+
 nsresult
 ArchiveRequest::ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
                             nsresult aStatus)
 {
   if (NS_FAILED(aStatus)) {
     FireError(aStatus);
     return NS_OK;
   }
 
-  jsval result;
+  JS::Value result;
   nsresult rv;
 
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   NS_ENSURE_STATE(sc);
 
   JSContext* cx = sc->GetNativeContext();
   NS_ASSERTION(cx, "Failed to get a context!");
 
@@ -135,16 +141,20 @@ ArchiveRequest::ReaderReady(nsTArray<nsC
   switch (mOperation) {
     case GetFilenames:
       rv = GetFilenamesResult(cx, &result, aFileList);
       break;
 
     case GetFile:
       rv = GetFileResult(cx, &result, aFileList);
       break;
+
+      case GetFiles:
+        rv = GetFilesResult(cx, &result, aFileList);
+        break;
   }
 
   if (NS_FAILED(rv)) {
     NS_WARNING("Get*Result failed!");
   }
 
   if (NS_SUCCEEDED(rv)) {
     FireSuccess(result);
@@ -153,17 +163,17 @@ ArchiveRequest::ReaderReady(nsTArray<nsC
     FireError(rv);
   }
 
   return NS_OK;
 }
 
 nsresult
 ArchiveRequest::GetFilenamesResult(JSContext* aCx,
-                                   jsval* aValue,
+                                   JS::Value* aValue,
                                    nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
 {
   JSObject* array = JS_NewArrayObject(aCx, aFileList.Length(), nullptr);
   nsresult rv;
 
   if (!array) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
@@ -173,34 +183,34 @@ ArchiveRequest::GetFilenamesResult(JSCon
 
     nsString filename;
     rv = file->GetName(filename);
     NS_ENSURE_SUCCESS(rv, rv);
 
     JSString* str = JS_NewUCStringCopyZ(aCx, filename.get());
     NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
 
-    jsval item = STRING_TO_JSVAL(str);
+    JS::Value item = STRING_TO_JSVAL(str);
 
     if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, &item)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   if (!JS_FreezeObject(aCx, array)) {
     return NS_ERROR_FAILURE;
   }
 
   *aValue = OBJECT_TO_JSVAL(array);
   return NS_OK;
 }
 
 nsresult
 ArchiveRequest::GetFileResult(JSContext* aCx,
-                              jsval* aValue,
+                              JS::Value* aValue,
                               nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
 {
   for (uint32_t i = 0; i < aFileList.Length(); ++i) {
     nsCOMPtr<nsIDOMFile> file = aFileList[i];
 
     nsString filename;
     nsresult rv = file->GetName(filename);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -211,16 +221,41 @@ ArchiveRequest::GetFileResult(JSContext*
                       file, &NS_GET_IID(nsIDOMFile), aValue);
       return rv;
     }
   }
 
   return NS_ERROR_FAILURE;
 }
 
+nsresult
+ArchiveRequest::GetFilesResult(JSContext* aCx,
+                               JS::Value* aValue,
+                               nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
+{
+  JSObject* array = JS_NewArrayObject(aCx, aFileList.Length(), nullptr);
+  if (!array) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  for (PRUint32 i = 0; i < aFileList.Length(); ++i) {
+    nsCOMPtr<nsIDOMFile> file = aFileList[i];
+
+    JS::Value value;
+    nsresult rv = nsContentUtils::WrapNative(aCx, JS_GetGlobalForScopeChain(aCx),
+                                             file, &NS_GET_IID(nsIDOMFile), &value);
+    if (NS_FAILED(rv) || !JS_SetElement(aCx, array, i, &value)) {
+      return NS_ERROR_FAILURE;
+    }
+  }
+
+  aValue->setObject(*array);
+  return NS_OK;
+}
+
 // static
 already_AddRefed<ArchiveRequest>
 ArchiveRequest::Create(nsIDOMWindow* aOwner,
                        ArchiveReader* aReader)
 {
   NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
 
   nsRefPtr<ArchiveRequest> request = new ArchiveRequest(aOwner, aReader);
--- a/dom/file/ArchiveRequest.h
+++ b/dom/file/ArchiveRequest.h
@@ -39,42 +39,47 @@ public:
 
 public:
   // This is called by the DOMArchiveRequestEvent
   void Run();
 
   // Set the types for this request
   void OpGetFilenames();
   void OpGetFile(const nsAString& aFilename);
+  void OpGetFiles();
 
   nsresult ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
                        nsresult aStatus);
 
 public: // static
   static already_AddRefed<ArchiveRequest> Create(nsIDOMWindow* aOwner,
                                                  ArchiveReader* aReader);
 
 private:
   ~ArchiveRequest();
 
   nsresult GetFilenamesResult(JSContext* aCx,
-                              jsval* aValue,
+                              JS::Value* aValue,
                               nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList);
   nsresult GetFileResult(JSContext* aCx,
-                         jsval* aValue,
+                         JS::Value* aValue,
                          nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList);
+  nsresult GetFilesResult(JSContext* aCx,
+                          JS::Value* aValue,
+                          nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList);
 
 protected:
   // The reader:
   nsRefPtr<ArchiveReader> mArchiveReader;
 
   // The operation:
   enum {
     GetFilenames,
-    GetFile
+    GetFile,
+    GetFiles
   } mOperation;
 
   // The filename (needed by GetFile):
   nsString mFilename;
 };
 
 END_FILE_NAMESPACE
 
--- a/dom/file/nsIDOMArchiveReader.idl
+++ b/dom/file/nsIDOMArchiveReader.idl
@@ -7,16 +7,17 @@
 
 interface nsIDOMArchiveRequest;
 
 [scriptable, builtinclass, uuid(a616ab85-fc3a-4028-9f10-f8620ee1b8e1)]
 interface nsIDOMArchiveReader : nsISupports
 {
   nsIDOMArchiveRequest getFilenames();
   nsIDOMArchiveRequest getFile(in DOMString filename);
+  nsIDOMArchiveRequest getFiles();
 };
 
 /* This dictionary is the optional argument for the
  * ArchiveReader constructor:
  * var a = new ArchiveReader(blob, { encoding: "iso-8859-1" }); */
 dictionary ArchiveReaderOptions
 {
   DOMString encoding = "windows-1252"; // Default fallback encoding
--- a/dom/file/test/test_archivereader.html
+++ b/dom/file/test/test_archivereader.html
@@ -57,17 +57,17 @@
   handleFinished = 0;
   function markTestDone() {
     ++handleFinished;
     if (isFinished()) {
       SimpleTest.finish();
     }
   }
   function isFinished() {
-    return handleFinished == 5;
+    return handleFinished == 6;
   }
 
   function testSteps()
   {
     var binaryString = '504B03040A00000000002E6BF14000000000000000000000000005001C00746573742F555409000337CA055039CA055075780B' +
                        '000104E803000004E8030000504B03041400000008002D6BF1401780E15015000000580200000A001C00746573742F612E7478' +
                        '74555409000336CA05503ACA055075780B000104E803000004E8030000CB48CDC9C95728CF2FCA49E1CA18658FB2A9C4060050' +
                        '4B03040A00000000002F88EC40662E847010000000100000000A001C00746573742F622E74787455540900035A65FF4F42C505' +
@@ -227,16 +227,35 @@
           is(p[i], "hello world", "ArchiveReader + FileReader are working with a compress data");
         markTestDone();
       }
     }
     handle4.onerror = function() {
       ok(false, "ArchiveReader.getFile('test/a.txt') should not return an 'error'");
       markTestDone();
     }
+
+    var handle5 = r.getFiles();
+    isnot(handle5, null, "ArchiveReader.getFiles() cannot be null");
+    handle5.onsuccess = function() {
+      ok(true, "ArchiveReader.getFiles() should return a 'success'");
+      ok(this.reader, r, "ArchiveRequest.reader should be == ArchiveReader");
+
+      is(this.result.length, 2, "ArchiveReader.getFilenames(): the array contains 2 items");
+      is(this.result[0].name, "test/a.txt", "ArchiveReader.getFilenames(): first file is 'test/a.txt'");
+      is(this.result[1].name, "test/b.txt", "ArchiveReader.getFilenames(): second file is 'test/b.txt'");
+      is(this.result[0].type, "text/plain", "ArchiveReader.getFile('test/a.txt') the type MUST be 'text/plain'");
+      is(this.result[1].type, "text/plain", "ArchiveReader.getFile('test/a.txt') the type MUST be 'text/plain'");
+
+      markTestDone();
+    }
+    handle5.onerror = function() {
+      ok(false, "ArchiveReader.getFiles() should not return an 'error'");
+      markTestDone();
+    }
   }
 
   SimpleTest.waitForExplicitFinish();
   testSteps();
   </script>
 </body>
 
 </html>