home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 December / PCWorld_2007-12_cd.bin / audio-video / songbird / Songbird_0.3_windows-i686.exe / xulrunner / components / nsScriptableIO.js < prev    next >
Text File  |  2007-07-25  |  13KB  |  378 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Scriptable IO.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla Corporation.
  17.  * Portions created by the Initial Developer are Copyright (C) 2007
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Neil Deakin <enndeakin@sympatico.ca> (Original Author)
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  25.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26.  * in which case the provisions of the GPL or the LGPL are applicable instead
  27.  * of those above. If you wish to allow use of your version of this file only
  28.  * under the terms of either the GPL or the LGPL, and not to allow others to
  29.  * use your version of this file under the terms of the MPL, indicate your
  30.  * decision by deleting the provisions above and replace them with the notice
  31.  * and other provisions required by the GPL or the LGPL. If you do not delete
  32.  * the provisions above, a recipient may use your version of this file under
  33.  * the terms of any one of the MPL, the GPL or the LGPL.
  34.  *
  35.  * ***** END LICENSE BLOCK ***** */
  36.  
  37. const SCRIPTABLEIO_CLASS_ID = Components.ID("1EDB3B94-0E2E-419A-8C2B-D9E232D41086");
  38. const SCRIPTABLEIO_CLASS_NAME = "Scriptable IO";
  39. const SCRIPTABLEIO_CONTRACT_ID = "@mozilla.org/io/scriptable-io;1";
  40.  
  41. const DEFAULT_BUFFER_SIZE = 1024;
  42. const DEFAULT_PERMISSIONS = 0644;
  43.  
  44. const Cc = Components.classes;
  45. const Ci = Components.interfaces;
  46.  
  47. var gScriptableIO = null;
  48.  
  49. // when using the directory service, map some extra keys that are
  50. // easier to understand for common directories
  51. var mappedDirKeys = {
  52.   Application: "resource:app",
  53.   Working: "CurWorkD",
  54.   Profile: "ProfD",
  55.   Desktop: "Desk",
  56.   Components: "ComsD",
  57.   Temp: "TmpD"
  58. };
  59.   
  60. function ScriptableIO() {
  61. }
  62.  
  63. ScriptableIO.prototype =
  64. {
  65.   _wrapBaseWithInputStream : function ScriptableIO_wrapBaseWithInputStream
  66.                                       (base, modes, permissions)
  67.   {
  68.     var stream;
  69.     if (base instanceof Ci.nsIFile) {
  70.       var behaviour = 0;
  71.       if (modes["deleteonclose"])
  72.         behaviour |= Ci.nsIFileInputStream.DELETE_ON_CLOSE;
  73.       if (modes["closeoneof"])
  74.         behaviour |= Ci.nsIFileInputStream.CLOSE_ON_EOF;
  75.       if (modes["reopenonrewind"])
  76.         behaviour |= Ci.nsIFileInputStream.REOPEN_ON_REWIND;
  77.  
  78.       stream = Cc["@mozilla.org/network/file-input-stream;1"].
  79.                  createInstance(Ci.nsIFileInputStream);
  80.       stream.init(base, 1, permissions, behaviour);
  81.     }
  82.     else if (base instanceof Ci.nsITransport) {
  83.       var flags = modes["block"] ? Ci.nsITransport.OPEN_BLOCKING : 0;
  84.       stream = base.openInputStream(flags, buffersize, 0);
  85.     }
  86.     else if (base instanceof Ci.nsIInputStream) {
  87.       stream = base;
  88.     }
  89.     else if (typeof base == "string") {
  90.       stream = Cc["@mozilla.org/io/string-input-stream;1"].
  91.                  createInstance(Ci.nsIStringInputStream);
  92.       stream.setData(base, base.length);
  93.     }
  94.     if (!stream)
  95.       throw "Cannot create input stream from base";
  96.  
  97.     return stream;
  98.   },
  99.  
  100.   _wrapBaseWithOutputStream : function ScriptableIO_wrapBaseWithOutputStream
  101.                               (base, modes, permissions)
  102.   {
  103.     var stream;
  104.     if (base instanceof Ci.nsIFile) {
  105.       stream = Cc["@mozilla.org/network/file-output-stream;1"].
  106.                  createInstance(Ci.nsIFileOutputStream);
  107.  
  108.       // default for writing is 'write create truncate'
  109.       var modeFlags = 42;
  110.       if (modes["nocreate"])
  111.         modeFlags ^= 8;
  112.       if (modes["append"])
  113.         modeFlags |= 16;
  114.       if (modes["notruncate"])
  115.         modeFlags ^= 32;
  116.       if (modes["syncsave"])
  117.         modeFlags |= 64;
  118.  
  119.       stream.init(base, modeFlags, permissions, 0);
  120.     }
  121.     else if (base instanceof Ci.nsITransport) {
  122.       var flags = modes["block"] ? Ci.nsITransport.OPEN_BLOCKING : 0;
  123.       stream = base.openOutputStream(flags, buffersize, 0);
  124.     }
  125.     else if (base instanceof Ci.nsIInputStream) {
  126.       stream = base;
  127.     }
  128.     if (!stream)
  129.       throw "Cannot create output stream from base";
  130.  
  131.     return stream;
  132.   },
  133.  
  134.   _openForReading : function ScriptableIO_openForReading
  135.                              (base, modes, buffersize, charset, replchar)
  136.   {
  137.     var stream = base;
  138.     var charstream = null;
  139.     if (modes["text"]) {
  140.       if (!charset)
  141.         charset = "UTF-8";
  142.       if (!replchar)
  143.         replchar = Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
  144.  
  145.       charstream = Cc["@mozilla.org/intl/converter-input-stream;1"].
  146.                      createInstance(Ci.nsIConverterInputStream);
  147.       charstream.init(base, charset, buffersize, replchar);
  148.     }
  149.     else if (modes["buffered"]) {
  150.       stream = Cc["@mozilla.org/network/buffered-input-stream;1"].
  151.                  createInstance(Ci.nsIBufferedInputStream);
  152.       stream.init(base, buffersize);
  153.     }
  154.     else if (modes["multi"]) {
  155.       stream = Cc["@mozilla.org/io/multiplex-input-stream;1"].
  156.                  createInstance(Ci.nsIMultiplexInputStream);
  157.       stream.appendStream(base);
  158.     }
  159.  
  160.     // wrap the stream in a scriptable stream
  161.     var sstream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance();
  162.     sstream.initWithStreams(stream, charstream);
  163.     return sstream;
  164.   },
  165.  
  166.   _openForWriting : function ScriptableIO_openForWriting
  167.                              (base, modes, buffersize, charset, replchar)
  168.   {
  169.     var stream = base;
  170.     var charstream = null;
  171.     if (modes["text"]) {
  172.       if (!charset)
  173.         charset = "UTF-8";
  174.       if (!replchar)
  175.         replchar = Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER;
  176.  
  177.       charstream = Cc["@mozilla.org/intl/converter-output-stream;1"].
  178.                      createInstance(Ci.nsIConverterOutputStream);
  179.       charstream.init(base, charset, buffersize, replchar);
  180.     }
  181.     else if (modes["buffered"]) {
  182.       stream = Cc["@mozilla.org/network/buffered-output-stream;1"].
  183.                  createInstance(Ci.nsIBufferedOutputStream);
  184.       stream.init(base, buffersize);
  185.     }
  186.  
  187.     // wrap the stream in a scriptable stream
  188.     var sstream = Cc["@mozilla.org/scriptableoutputstream;1"].createInstance();
  189.     sstream.initWithStreams(stream, charstream);
  190.     return sstream;
  191.   },
  192.  
  193.   getFile : function ScriptableIO_getFile(location, file)
  194.   {
  195.     if (!location)
  196.       throw Components.results.NS_ERROR_INVALID_ARG;
  197.  
  198.     if (location in mappedDirKeys)
  199.       location = mappedDirKeys[location];
  200.  
  201.     var ds = Cc["@mozilla.org/file/directory_service;1"].
  202.                getService(Ci.nsIProperties);
  203.     var fl = ds.get(location, Ci.nsILocalFile);
  204.     if (file)
  205.       fl.append(file);
  206.     return fl;
  207.   },
  208.  
  209.   getFileWithPath : function ScriptableIO_getFileWithPath(filepath)
  210.   {
  211.     if (!filepath)
  212.       throw Components.results.NS_ERROR_INVALID_ARG;
  213.  
  214.     // XXXndeakin not sure if setting persistentDescriptor is best here, but
  215.     // it's more useful than initWithPath, for instance, for preferences
  216.     var fl = Cc["@mozilla.org/file/local;1"].createInstance();
  217.     fl.persistentDescriptor = filepath;
  218.     return fl;
  219.   },
  220.  
  221.   newURI : function ScriptableIO_newURI(uri)
  222.   {
  223.     if (!uri)
  224.       throw Components.results.NS_ERROR_INVALID_ARG;
  225.  
  226.     var ios = Cc["@mozilla.org/network/io-service;1"].
  227.                 getService(Ci.nsIIOService);
  228.     if (uri instanceof Ci.nsIFile)
  229.       return ios.newFileURI(uri);
  230.     return ios.newURI(uri, "", null);
  231.   },
  232.  
  233.   newInputStream : function ScriptableIO_newInputStream
  234.                             (base, mode, charset, replchar, buffersize)
  235.   {
  236.     return this._newStream(base, mode, charset, replchar, buffersize,
  237.                            DEFAULT_PERMISSIONS, false);
  238.   },
  239.  
  240.   newOutputStream : function ScriptableIO_newOutputStream
  241.                              (base, mode, charset, replchar, buffersize, permissions)
  242.   {
  243.     return this._newStream(base, mode, charset, replchar, buffersize,
  244.                            permissions, true);
  245.   },
  246.  
  247.   _newStream : function ScriptableIO_newStream
  248.                         (base, mode, charset, replchar, buffersize, permissions, iswrite)
  249.   {
  250.     if (!base)
  251.       throw Components.results.NS_ERROR_INVALID_ARG;
  252.  
  253.     var modes = {};
  254.     var modeArr = mode.split(/\s+/);
  255.     for (var m = 0; m < modeArr.length; m++) {
  256.       modes[modeArr[m]] = true;
  257.     }
  258.  
  259.     if (!buffersize)
  260.       buffersize = DEFAULT_BUFFER_SIZE;
  261.  
  262.     var stream;
  263.     if (iswrite) {
  264.       base = this._wrapBaseWithOutputStream(base, modes, permissions);
  265.       stream = this._openForWriting(base, modes, buffersize, charset, replchar);
  266.     }
  267.     else {
  268.       base = this._wrapBaseWithInputStream(base, modes, permissions);
  269.       stream = this._openForReading(base, modes, buffersize, charset, replchar);
  270.     }
  271.  
  272.     if (!stream)
  273.       throw "Cannot create stream from base";
  274.  
  275.     return stream;
  276.   },
  277.  
  278.   // nsIClassInfo
  279.   classDescription : "IO",
  280.   classID : SCRIPTABLEIO_CLASS_ID,
  281.   contractID : SCRIPTABLEIO_CONTRACT_ID,
  282.   flags : Ci.nsIClassInfo.SINGLETON,
  283.   implementationLanguage : Ci.nsIProgrammingLanguage.JAVASCRIPT,
  284.  
  285.   getInterfaces : function ScriptableIO_getInterfaces(aCount) {
  286.     var interfaces = [Ci.nsIScriptableIO, Ci.nsIClassInfo];
  287.     aCount.value = interfaces.length;
  288.     return interfaces;
  289.   },
  290.  
  291.   getHelperForLanguage : function ScriptableIO_getHelperForLanguage(aCount) {
  292.     return null;
  293.   },
  294.   
  295.   QueryInterface: function ScriptableIO_QueryInterface(aIID) {
  296.     if (aIID.equals(Ci.nsIScriptableIO) ||
  297.         aIID.equals(Ci.nsIClassInfo) ||
  298.         aIID.equals(Ci.nsISupports))
  299.       return this;
  300.     throw Components.results.NS_ERROR_NO_INTERFACE;
  301.   }
  302. }
  303.  
  304. var ScriptableIOFactory = {
  305.   QueryInterface: function ScriptableIOFactory_QueryInterface(iid)
  306.   {
  307.     if (iid.equals(Ci.nsIFactory) ||
  308.         iid.equals(Ci.nsISupports))
  309.       return this;
  310.     throw Cr.NS_ERROR_NO_INTERFACE;
  311.   },
  312.    
  313.   createInstance: function ScriptableIOFactory_createInstance(aOuter, aIID)
  314.   {
  315.     if (aOuter != null)
  316.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  317.  
  318.     if (gScriptableIO == null)
  319.       gScriptableIO = new ScriptableIO();
  320.  
  321.     return gScriptableIO.QueryInterface(aIID);
  322.   }
  323. };
  324.  
  325. var ScriptableIOModule = {
  326.   QueryInterface: function ScriptableIOModule_QueryInterface(iid) {
  327.     if (iid.equals(Ci.nsIModule) ||
  328.         iid.equals(Ci.nsISupports))
  329.       return this;
  330.     throw Cr.NS_ERROR_NO_INTERFACE;
  331.   },
  332.  
  333.   registerSelf: function ScriptableIOModule_registerSelf(aCompMgr, aFileSpec, aLocation, aType)
  334.   {
  335.     aCompMgr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
  336.     aCompMgr.registerFactoryLocation(SCRIPTABLEIO_CLASS_ID,
  337.                                      SCRIPTABLEIO_CLASS_NAME,
  338.                                      SCRIPTABLEIO_CONTRACT_ID,
  339.                                      aFileSpec, aLocation, aType);
  340.  
  341.     var categoryManager = Cc["@mozilla.org/categorymanager;1"].
  342.                             getService(Ci.nsICategoryManager);
  343.  
  344.     categoryManager.addCategoryEntry("JavaScript global privileged property", "IO",
  345.                                      SCRIPTABLEIO_CONTRACT_ID, true, true);
  346.   },
  347.  
  348.   unregisterSelf: function ScriptableIOModule_unregisterSelf(aCompMgr, aLocation, aType)
  349.   {
  350.     aCompMgr = aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
  351.     aCompMgr.unregisterFactoryLocation(SCRIPTABLEIO_CLASS_ID, aLocation);        
  352.  
  353.     var categoryManager = Cc["@mozilla.org/categorymanager;1"].
  354.                             getService(Ci.nsICategoryManager);
  355.     categoryManager.deleteCategoryEntry("JavaScript global privileged property",
  356.                                         SCRIPTABLEIO_CONTRACT_ID, true);
  357.   },
  358.  
  359.   getClassObject: function ScriptableIOModule_getClassObject(aCompMgr, aCID, aIID)
  360.   {
  361.     if (!aIID.equals(Ci.nsIFactory))
  362.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  363.  
  364.     if (aCID.equals(SCRIPTABLEIO_CLASS_ID))
  365.       return ScriptableIOFactory;
  366.  
  367.     throw Components.results.NS_ERROR_NO_INTERFACE;
  368.   },
  369.  
  370.   canUnload: function ScriptableIOModule_canUnload(aCompMgr)
  371.   {
  372.     gScriptableIO = null;
  373.     return true;
  374.   }
  375. };
  376.  
  377. function NSGetModule(aCompMgr, aFileSpec) { return ScriptableIOModule; }
  378.