Bug 782231 - Share code between implementations of DirectoryIterator. r=froydnj
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Fri, 21 Sep 2012 23:36:15 -0400
changeset 107792 c6aadfcb3ccf553d3d303a4c9e3d7683d798d3c2
parent 107791 6731957980f9e11a211944bcb448ba3b85aac478
child 107793 3c29b24fd648208ada710a23cf807c3eed564f8c
push id23509
push userryanvm@gmail.com
push dateSat, 22 Sep 2012 12:28:38 +0000
treeherdermozilla-central@b461a7cd250e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs782231
milestone18.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 782231 - Share code between implementations of DirectoryIterator. r=froydnj
toolkit/components/osfile/osfile_shared_front.jsm
toolkit/components/osfile/osfile_unix_front.jsm
toolkit/components/osfile/osfile_win_front.jsm
--- a/toolkit/components/osfile/osfile_shared_front.jsm
+++ b/toolkit/components/osfile/osfile_shared_front.jsm
@@ -186,16 +186,30 @@ AbstractFile.normalizeToPointer = functi
   }
   if (offset != 0) {
     ptr = exports.OS.Shared.offsetBy(ptr, offset);
   }
   return {ptr: ptr, bytes: bytes};
 };
 
 /**
+ * Code shared by iterators.
+ */
+AbstractFile.AbstractIterator = function AbstractIterator() {
+};
+AbstractFile.AbstractIterator.prototype = {
+  /**
+   * Allow iterating with |for|
+   */
+  __iterator__: function __iterator__() {
+    return this;
+  }
+};
+
+/**
  * Utility function shared by implementations of |OS.File.open|:
  * extract read/write/trunc/create/existing flags from a |mode|
  * object.
  *
  * @param {*=} mode An object that may contain fields |read|,
  * |write|, |truncate|, |create|, |existing|. These fields
  * are interpreted only if true-ish.
  * @return {{read:bool, write:bool, trunc:bool, create:bool,
--- a/toolkit/components/osfile/osfile_unix_front.jsm
+++ b/toolkit/components/osfile/osfile_unix_front.jsm
@@ -578,63 +578,61 @@
       * @param {string} path The directory upon which to iterate.
       * @param {*=} options Ignored in this implementation.
       *
       * @throws {File.Error} If |path| does not represent a directory or
       * if the directory cannot be iterated.
       * @constructor
       */
      File.DirectoryIterator = function DirectoryIterator(path, options) {
+       exports.OS.Shared.AbstractFile.AbstractIterator.call(this);
        let dir = throw_on_null("DirectoryIterator", UnixFile.opendir(path));
        this._dir = dir;
        this._path = path;
      };
-     File.DirectoryIterator.prototype = {
-       __iterator__: function __iterator__() {
-         return this;
-       },
-       /**
-        * Return the next entry in the directory, if any such entry is
-        * available.
-        *
-        * Skip special directories "." and "..".
-        *
-        * @return {File.Entry} The next entry in the directory.
-        * @throws {StopIteration} Once all files in the directory have been
-        * encountered.
-        */
-       next: function next() {
-         if (!this._dir) {
-           throw StopIteration;
+     File.DirectoryIterator.prototype = Object.create(exports.OS.Shared.AbstractFile.AbstractIterator.prototype);
+
+     /**
+      * Return the next entry in the directory, if any such entry is
+      * available.
+      *
+      * Skip special directories "." and "..".
+      *
+      * @return {File.Entry} The next entry in the directory.
+      * @throws {StopIteration} Once all files in the directory have been
+      * encountered.
+      */
+     File.DirectoryIterator.prototype.next = function next() {
+       if (!this._dir) {
+         throw StopIteration;
+       }
+       for (let entry = UnixFile.readdir(this._dir);
+            entry != null && !entry.isNull();
+            entry = UnixFile.readdir(this._dir)) {
+         let contents = entry.contents;
+         if (contents.d_type == OS.Constants.libc.DT_DIR) {
+           let name = contents.d_name.readString();
+           if (name == "." || name == "..") {
+             continue;
+           }
          }
-         for (let entry = UnixFile.readdir(this._dir);
-              entry != null && !entry.isNull();
-              entry = UnixFile.readdir(this._dir)) {
-           let contents = entry.contents;
-           if (contents.d_type == OS.Constants.libc.DT_DIR) {
-             let name = contents.d_name.readString();
-             if (name == "." || name == "..") {
-               continue;
-             }
-           }
-           return new File.DirectoryIterator.Entry(contents, this._path);
-         }
-         this.close();
-         throw StopIteration;
-       },
+         return new File.DirectoryIterator.Entry(contents, this._path);
+       }
+       this.close();
+       throw StopIteration;
+     };
 
-       /**
-        * Close the iterator and recover all resources.
-        * You should call this once you have finished iterating on a directory.
-        */
-       close: function close() {
-         if (!this._dir) return;
-         UnixFile.closedir(this._dir);
-         this._dir = null;
-       }
+     /**
+      * Close the iterator and recover all resources.
+      * You should call this once you have finished iterating on a directory.
+      */
+     File.DirectoryIterator.prototype.close = function close() {
+       if (!this._dir) return;
+       UnixFile.closedir(this._dir);
+       this._dir = null;
      };
 
      /**
       * An entry in a directory.
       */
      File.DirectoryIterator.Entry = function Entry(unix_entry, parent) {
        // Copy the relevant part of |unix_entry| to ensure that
        // our data is not overwritten prematurely.
--- a/toolkit/components/osfile/osfile_win_front.jsm
+++ b/toolkit/components/osfile/osfile_win_front.jsm
@@ -475,36 +475,34 @@
       * @param {string} path The directory upon which to iterate.
       * @param {*=} options Ignored in this implementation.
       *
       * @throws {File.Error} If |path| does not represent a directory or
       * if the directory cannot be iterated.
       * @constructor
       */
      File.DirectoryIterator = function DirectoryIterator(path, options) {
+       exports.OS.Shared.AbstractFile.AbstractIterator.call(this);
        if (options && options.winPattern) {
          this._pattern = path + "\\" + options.winPattern;
        } else {
          this._pattern = path + "\\*";
        }
        this._handle = null;
        this._path = path;
        this._started = false;
      };
-     File.DirectoryIterator.prototype = {
-       __iterator__: function __iterator__() {
-         return this;
-       },
+     File.DirectoryIterator.prototype = Object.create(exports.OS.Shared.AbstractFile.AbstractIterator.prototype);
 
        /**
         * Fetch the next entry in the directory.
         *
         * @return null If we have reached the end of the directory.
         */
-       _next: function _next() {
+     File.DirectoryIterator.prototype._next = function _next() {
          // Iterator is not fully initialized yet. Finish
          // initialization.
          if (!this._started) {
             this._started = true;
             this._handle = WinFile.FindFirstFile(this._pattern, gFindDataPtr);
             if (this._handle == null) {
               let error = ctypes.winLastError;
               if (error == Const.ERROR_FILE_NOT_FOUND) {
@@ -539,37 +537,36 @@
         * available.
         *
         * Skip special directories "." and "..".
         *
         * @return {File.Entry} The next entry in the directory.
         * @throws {StopIteration} Once all files in the directory have been
         * encountered.
         */
-       next: function next() {
+     File.DirectoryIterator.prototype.next = function next() {
          // FIXME: If we start supporting "\\?\"-prefixed paths, do not forget
          // that "." and ".." are absolutely normal file names if _path starts
          // with such prefix
          for (let entry = this._next(); entry != null; entry = this._next()) {
            let name = entry.cFileName.readString();
            if (name == "." || name == "..") {
              continue;
            }
            return new File.DirectoryIterator.Entry(entry, this._path);
          }
          throw StopIteration;
-       },
-       close: function close() {
-         if (!this._handle) {
-           return;
-         }
-         throw_on_zero("FindClose",
-           WinFile.FindClose(this._handle));
-         this._handle = null;
+     };
+     File.DirectoryIterator.prototype.close = function close() {
+       if (!this._handle) {
+         return;
        }
+       throw_on_zero("FindClose",
+         WinFile.FindClose(this._handle));
+       this._handle = null;
      };
      File.DirectoryIterator.Entry = function Entry(win_entry, parent) {
        // Copy the relevant part of |win_entry| to ensure that
        // our data is not overwritten prematurely.
        if (!win_entry.dwFileAttributes) {
          throw new TypeError();
        }
        this._dwFileAttributes = win_entry.dwFileAttributes;