home *** CD-ROM | disk | FTP | other *** search
/ Freelog 100 / FreelogNo100-NovembreDecembre2010.iso / Multimedia / Songbird / Songbird_1.8.0-1800_windows-i686-msvc8.exe / jsmodules / ArrayConverter.jsm < prev    next >
Text File  |  2010-08-30  |  8KB  |  292 lines

  1. /*
  2.  * NOTE: This was snagged from https://bugzilla.mozilla.org/show_bug.cgi?id=380839
  3.  * This will go away when this lands
  4.  */
  5.  
  6. /* ***** BEGIN LICENSE BLOCK *****
  7.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  8.  *
  9.  * The contents of this file are subject to the Mozilla Public License Version
  10.  * 1.1 (the "License"); you may not use this file except in compliance with
  11.  * the License. You may obtain a copy of the License at
  12.  * http://www.mozilla.org/MPL/
  13.  *
  14.  * Software distributed under the License is distributed on an "AS IS" basis,
  15.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  16.  * for the specific language governing rights and limitations under the
  17.  * License.
  18.  *
  19.  * The Original Code is Code modules: JavaScript array converter.
  20.  *
  21.  * The Initial Developer of the Original Code is
  22.  * Alexander J. Vincent <ajvincent@gmail.com>.
  23.  * Portions created by the Initial Developer are Copyright (C) 2007
  24.  * the Initial Developer. All Rights Reserved.
  25.  *
  26.  * Contributor(s):
  27.  *
  28.  * Alternatively, the contents of this file may be used under the terms of
  29.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  30.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  31.  * in which case the provisions of the GPL or the LGPL are applicable instead
  32.  * of those above. If you wish to allow use of your version of this file only
  33.  * under the terms of either the GPL or the LGPL, and not to allow others to
  34.  * use your version of this file under the terms of the MPL, indicate your
  35.  * decision by deleting the provisions above and replace them with the notice
  36.  * and other provisions required by the GPL or the LGPL. If you do not delete
  37.  * the provisions above, a recipient may use your version of this file under
  38.  * the terms of any one of the MPL, the GPL or the LGPL.
  39.  *
  40.  * ***** END LICENSE BLOCK ***** */
  41.  
  42. /**
  43.  * Utilities for JavaScript components loaded by the JS component
  44.  * loader.
  45.  *
  46.  * Import into a JS component using
  47.  * 'Components.utils.import("rel:ArrayConverter.jsm");'
  48.  *
  49.  */
  50.  
  51. EXPORTED_SYMBOLS = [ "ArrayConverter" ];
  52.  
  53. const Ci = Components.interfaces;
  54. const Cr = Components.results;
  55.  
  56. /**
  57.  * Get a simple enumerator.
  58.  *
  59.  * @param aItemsList JavaScript array to enumerate.
  60.  */
  61. function Enumerator(aItemsList) {
  62.   this._itemsList = aItemsList;
  63.   this._iteratorPosition = 0;
  64. }
  65. Enumerator.prototype = {
  66.   // nsISimpleEnumerator
  67.   hasMoreElements: function hasMoreElements() {
  68.     return (this._iteratorPosition < this._itemsList.length);
  69.   },
  70.  
  71.   // nsISimpleEnumerator
  72.   getNext: function getNext() {
  73.     if (!(this.hasMoreElements())) {
  74.       throw Components.results.NS_ERROR_FAILURE;
  75.     }
  76.     var type = this._itemsList[this._iteratorPosition];
  77.     this._iteratorPosition++;
  78.     return type;
  79.   },
  80.  
  81.   // nsISupports
  82.   QueryInterface: function QueryInterface(aIID)
  83.   {
  84.     if (aIID.equals(Ci.nsISimpleEnumerator) ||
  85.         aIID.equals(Ci.nsISupports))
  86.       return this;
  87.  
  88.     throw Components.results.NS_ERROR_NO_INTERFACE;
  89.   }
  90. }
  91.  
  92. /**
  93.  * Get a string enumerator.
  94.  *
  95.  * @param aItemsList JavaScript array to enumerate.
  96.  */
  97. function StringEnumerator(aItemsList) {
  98.   this._itemsList = aItemsList;
  99.   this._iteratorPosition = 0;
  100. }
  101. StringEnumerator.prototype = {
  102.   // nsIStringEnumerator
  103.   hasMore: function hasMore() {
  104.     return (this._iteratorPosition < this._itemsList.length);
  105.   },
  106.  
  107.   // nsIStringEnumerator
  108.   getNext: function getNext() {
  109.     if (!(this.hasMore())) {
  110.       throw Components.results.NS_ERROR_FAILURE;
  111.     }
  112.     var type = this._itemsList[this._iteratorPosition];
  113.     this._iteratorPosition++;
  114.     return type;
  115.   },
  116.  
  117.   // nsISupports
  118.   QueryInterface: function QueryInterface(aIID)
  119.   {
  120.     if (aIID.equals(Ci.nsIStringEnumerator) ||
  121.         aIID.equals(Ci.nsISupports))
  122.       return this;
  123.  
  124.     throw Components.results.NS_ERROR_NO_INTERFACE;
  125.   }
  126. }
  127.  
  128. function NSArray(aItemsList) {
  129.   this._itemsList = aItemsList;
  130. }
  131. NSArray.prototype = {
  132.   // nsIArray
  133.   get length() {
  134.     return this._itemsList.length;
  135.   },
  136.  
  137.   // nsIArray
  138.   queryElementAt: function queryElementAt(aIndex, aIID) {
  139.     if (aIndex > this.length - 1) {
  140.       throw Components.results.NS_ERROR_ILLEGAL_VALUE;
  141.     }
  142.  
  143.     return this._itemsList[aIndex].QueryInterface(aIID);
  144.   },
  145.  
  146.   // nsIArray
  147.   indexOf: function indexOf(aIndex, aElement) {
  148.     for (var i = aIndex; i < this._itemsList.length; i++) {
  149.       if (this._itemsList[i] == aElement) {
  150.         return i;
  151.       }
  152.     }
  153.     throw Components.results.NS_ERROR_NOT_FOUND;
  154.   },
  155.  
  156.   // nsIArray
  157.   enumerate: function enumerate() {
  158.     return new Enumerator(this._itemsList);
  159.   },
  160.  
  161.   // nsISupports
  162.   QueryInterface: function QueryInterface(aIID)
  163.   {
  164.     if (aIID.equals(Ci.nsIArray) ||
  165.         aIID.equals(Ci.nsISupports))
  166.       return this;
  167.  
  168.     throw Components.results.NS_ERROR_NO_INTERFACE;
  169.   }
  170. }
  171.  
  172. var ArrayConverter = {
  173.   /**
  174.    * Get a JavaScript array for a nsIArray or nsISimpleEnumerator.
  175.    *
  176.    * @param aObject nsIArray or nsISimpleEnumerator to convert.
  177.    *
  178.    * @throws NS_ERROR_INVALID_ARG.
  179.    */
  180.   JSArray: function getJSArray(aObject) {
  181.     if (aObject instanceof Ci.nsIArray) {
  182.       aObject = aObject.enumerate();
  183.     }
  184.     
  185.     var hasMore;
  186.     
  187.     if (aObject instanceof Ci.nsISimpleEnumerator) {
  188.         hasMore = "hasMoreElements";
  189.     } else if (aObject instanceof Ci.nsIStringEnumerator ||
  190.                aObject instanceof Ci.nsIUTF8StringEnumerator)
  191.     {
  192.         hasMore = "hasMore";
  193.     } else {
  194.         throw new Components.Exception("invalid object",
  195.                                        Cr.NS_ERROR_INVALID_ARG);
  196.     }
  197.  
  198.     var array = [];
  199.     while (aObject[hasMore]()) {
  200.         array.push(aObject.getNext());
  201.     }
  202.     return array;
  203.   },
  204.  
  205.   /**
  206.    * Get a JavaScript iterator for a nsIArray, nsISimpleEnumerator,
  207.    * or nsIStringEnumerator.
  208.    *
  209.    * @param aObject nsIArray or nsISimpleEnumerator to convert.
  210.    *
  211.    * @throws NS_ERROR_INVALID_ARG.
  212.    */
  213.   JSEnum: function JSEnum(enumIn) {
  214.     if (enumIn instanceof Ci.nsIArray) {
  215.       enumIn = enumIn.enumerate();
  216.     }
  217.     
  218.     if (enumIn instanceof Ci.nsISimpleEnumerator) {
  219.       return {
  220.         __iterator__: function() {
  221.           while(enumIn.hasMoreElements())
  222.             yield(enumIn.getNext());
  223.         }
  224.       }
  225.     }
  226.     else if (enumIn instanceof Ci.nsIStringEnumerator) {
  227.       return {
  228.         __iterator__: function() {
  229.           while(enumIn.hasMore())
  230.             yield(enumIn.getNext());
  231.         }
  232.       }
  233.     }
  234.     return null;
  235.   },
  236.  
  237.   /**
  238.    * Return a nsIArray for a JavaScript array.
  239.    *
  240.    * @param aArray JavaScript array to convert.
  241.    */
  242.   nsIArray: function get_nsIArray(aArray) {
  243.     return new NSArray(aArray);
  244.   },
  245.  
  246.   /**
  247.    * Return a nsISimpleEnumerator for a JavaScript array or nsIArray.
  248.    *
  249.    * @param aArray JavaScript array to convert.
  250.    */
  251.   enumerator: function get_enumerator(/* in JSArray */ aArray) {
  252.     if (aArray instanceof Ci.nsIArray) {
  253.       return aArray.nsIArray.enumerate();
  254.     }
  255.     return new Enumerator(aArray);
  256.   },
  257.  
  258.   /**
  259.    * Return a nsIStringEnumerator for a JavaScript array.
  260.    *
  261.    * @param aArray JavaScript array to convert.
  262.    */
  263.   stringEnumerator: function get_stringEnumerator(/* in JSArray */ aArray) {
  264.     return new StringEnumerator(aArray);
  265.   },
  266.  
  267.   /**
  268.    * Return a method to convert a JavaScript array into a XPCOM array.
  269.    *
  270.    * @param aArrayName Name of JavaScript array property in "this" to convert.
  271.    */
  272.   xpcomArrayMethod: function getXPCOMMethod(aArrayName) {
  273.     /**
  274.      * Return a XPCOM array and count.
  275.      *
  276.      * @param (out) aCount The length of the array returned.
  277.      *
  278.      * @return The XPCOM array.
  279.      */
  280.     return function xpcomArray(aCount) {
  281.       var array = this[aArrayName];
  282.       aCount.value = array.length;
  283.       var rv = [];
  284.       for (var i = 0; i < array.length; i++) {
  285.         rv[i] = array[i];
  286.       }
  287.       return rv;
  288.     }
  289.   }  
  290. };
  291.  
  292.