1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/ds/nsINIProcessor.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,192 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 + 1.9 +const Cc = Components.classes; 1.10 +const Ci = Components.interfaces; 1.11 +const Cr = Components.results; 1.12 +const Cu = Components.utils; 1.13 + 1.14 +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); 1.15 + 1.16 +function INIProcessorFactory() { 1.17 +} 1.18 + 1.19 +INIProcessorFactory.prototype = { 1.20 + classID: Components.ID("{6ec5f479-8e13-4403-b6ca-fe4c2dca14fd}"), 1.21 + QueryInterface : XPCOMUtils.generateQI([Ci.nsIINIParserFactory]), 1.22 + 1.23 + createINIParser : function (aINIFile) { 1.24 + return new INIProcessor(aINIFile); 1.25 + } 1.26 + 1.27 +}; // end of INIProcessorFactory implementation 1.28 + 1.29 +const MODE_WRONLY = 0x02; 1.30 +const MODE_CREATE = 0x08; 1.31 +const MODE_TRUNCATE = 0x20; 1.32 + 1.33 +// nsIINIParser implementation 1.34 +function INIProcessor(aFile) { 1.35 + this._iniFile = aFile; 1.36 + this._iniData = {}; 1.37 + this._readFile(); 1.38 +} 1.39 + 1.40 +INIProcessor.prototype = { 1.41 + QueryInterface : XPCOMUtils.generateQI([Ci.nsIINIParser, Ci.nsIINIParserWriter]), 1.42 + 1.43 + __utf8Converter : null, // UCS2 <--> UTF8 string conversion 1.44 + get _utf8Converter() { 1.45 + if (!this.__utf8Converter) { 1.46 + this.__utf8Converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. 1.47 + createInstance(Ci.nsIScriptableUnicodeConverter); 1.48 + this.__utf8Converter.charset = "UTF-8"; 1.49 + } 1.50 + return this.__utf8Converter; 1.51 + }, 1.52 + 1.53 + __utf16leConverter : null, // UCS2 <--> UTF16LE string conversion 1.54 + get _utf16leConverter() { 1.55 + if (!this.__utf16leConverter) { 1.56 + this.__utf16leConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]. 1.57 + createInstance(Ci.nsIScriptableUnicodeConverter); 1.58 + this.__utf16leConverter.charset = "UTF-16LE"; 1.59 + } 1.60 + return this.__utf16leConverter; 1.61 + }, 1.62 + 1.63 + _utfConverterReset : function() { 1.64 + this.__utf8Converter = null; 1.65 + this.__utf16leConverter = null; 1.66 + }, 1.67 + 1.68 + _iniFile : null, 1.69 + _iniData : null, 1.70 + 1.71 + /* 1.72 + * Reads the INI file and stores the data internally. 1.73 + */ 1.74 + _readFile : function() { 1.75 + // If file doesn't exist, there's nothing to do. 1.76 + if (!this._iniFile.exists() || 0 == this._iniFile.fileSize) 1.77 + return; 1.78 + 1.79 + let iniParser = Cc["@mozilla.org/xpcom/ini-parser-factory;1"] 1.80 + .getService(Ci.nsIINIParserFactory).createINIParser(this._iniFile); 1.81 + for (let section in XPCOMUtils.IterStringEnumerator(iniParser.getSections())) { 1.82 + this._iniData[section] = {}; 1.83 + for (let key in XPCOMUtils.IterStringEnumerator(iniParser.getKeys(section))) { 1.84 + this._iniData[section][key] = iniParser.getString(section, key); 1.85 + } 1.86 + } 1.87 + }, 1.88 + 1.89 + // nsIINIParser 1.90 + 1.91 + getSections : function() { 1.92 + let sections = []; 1.93 + for (let section in this._iniData) 1.94 + sections.push(section); 1.95 + return new stringEnumerator(sections); 1.96 + }, 1.97 + 1.98 + getKeys : function(aSection) { 1.99 + let keys = []; 1.100 + if (aSection in this._iniData) 1.101 + for (let key in this._iniData[aSection]) 1.102 + keys.push(key); 1.103 + return new stringEnumerator(keys); 1.104 + }, 1.105 + 1.106 + getString : function(aSection, aKey) { 1.107 + if (!(aSection in this._iniData)) 1.108 + throw Cr.NS_ERROR_FAILURE; 1.109 + if (!(aKey in this._iniData[aSection])) 1.110 + throw Cr.NS_ERROR_FAILURE; 1.111 + return this._iniData[aSection][aKey]; 1.112 + }, 1.113 + 1.114 + 1.115 + // nsIINIParserWriter 1.116 + 1.117 + setString : function(aSection, aKey, aValue) { 1.118 + const isSectionIllegal = /[\0\r\n\[\]]/; 1.119 + const isKeyValIllegal = /[\0\r\n=]/; 1.120 + 1.121 + if (isSectionIllegal.test(aSection)) 1.122 + throw Components.Exception("bad character in section name", 1.123 + Cr.ERROR_ILLEGAL_VALUE); 1.124 + if (isKeyValIllegal.test(aKey) || isKeyValIllegal.test(aValue)) 1.125 + throw Components.Exception("bad character in key/value", 1.126 + Cr.ERROR_ILLEGAL_VALUE); 1.127 + 1.128 + if (!(aSection in this._iniData)) 1.129 + this._iniData[aSection] = {}; 1.130 + 1.131 + this._iniData[aSection][aKey] = aValue; 1.132 + }, 1.133 + 1.134 + writeFile : function(aFile, aFlags) { 1.135 + 1.136 + let converter; 1.137 + function writeLine(data) { 1.138 + data += "\n"; 1.139 + data = converter.ConvertFromUnicode(data); 1.140 + data += converter.Finish(); 1.141 + outputStream.write(data, data.length); 1.142 + } 1.143 + 1.144 + if (!aFile) 1.145 + aFile = this._iniFile; 1.146 + 1.147 + let safeStream = Cc["@mozilla.org/network/safe-file-output-stream;1"]. 1.148 + createInstance(Ci.nsIFileOutputStream); 1.149 + safeStream.init(aFile, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE, 1.150 + 0600, null); 1.151 + 1.152 + var outputStream = Cc["@mozilla.org/network/buffered-output-stream;1"]. 1.153 + createInstance(Ci.nsIBufferedOutputStream); 1.154 + outputStream.init(safeStream, 8192); 1.155 + outputStream.QueryInterface(Ci.nsISafeOutputStream); // for .finish() 1.156 + 1.157 + if (Ci.nsIINIParserWriter.WRITE_UTF16 == aFlags 1.158 + && 'nsIWindowsRegKey' in Ci) { 1.159 + outputStream.write("\xFF\xFE", 2); 1.160 + converter = this._utf16leConverter; 1.161 + } else { 1.162 + converter = this._utf8Converter; 1.163 + } 1.164 + 1.165 + for (let section in this._iniData) { 1.166 + writeLine("[" + section + "]"); 1.167 + for (let key in this._iniData[section]) { 1.168 + writeLine(key + "=" + this._iniData[section][key]); 1.169 + } 1.170 + } 1.171 + 1.172 + outputStream.finish(); 1.173 + } 1.174 +}; 1.175 + 1.176 +function stringEnumerator(stringArray) { 1.177 + this._strings = stringArray; 1.178 +} 1.179 +stringEnumerator.prototype = { 1.180 + QueryInterface : XPCOMUtils.generateQI([Ci.nsIUTF8StringEnumerator]), 1.181 + 1.182 + _strings : null, 1.183 + _enumIndex: 0, 1.184 + 1.185 + hasMore : function() { 1.186 + return (this._enumIndex < this._strings.length); 1.187 + }, 1.188 + 1.189 + getNext : function() { 1.190 + return this._strings[this._enumIndex++]; 1.191 + } 1.192 +}; 1.193 + 1.194 +let component = [INIProcessorFactory]; 1.195 +this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);