Bumping manifests a=b2g-bump
[gecko.git] / xpcom / ds / nsINIProcessor.js
blobebea6224673acd35dce21a9b29a241836e5d40d0
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 const Cc = Components.classes;
7 const Ci = Components.interfaces;
8 const Cr = Components.results;
9 const Cu = Components.utils;
11 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
13 function INIProcessorFactory() {
16 INIProcessorFactory.prototype = {
17     classID: Components.ID("{6ec5f479-8e13-4403-b6ca-fe4c2dca14fd}"),
18     QueryInterface : XPCOMUtils.generateQI([Ci.nsIINIParserFactory]),
20     createINIParser : function (aINIFile) {
21         return new INIProcessor(aINIFile);
22     }
24 }; // end of INIProcessorFactory implementation
26 const MODE_WRONLY = 0x02;
27 const MODE_CREATE = 0x08;
28 const MODE_TRUNCATE = 0x20;
30 // nsIINIParser implementation
31 function INIProcessor(aFile) {
32     this._iniFile = aFile;
33     this._iniData = {};
34     this._readFile();
37 INIProcessor.prototype = {
38     QueryInterface : XPCOMUtils.generateQI([Ci.nsIINIParser, Ci.nsIINIParserWriter]),
40     __utf8Converter : null, // UCS2 <--> UTF8 string conversion
41     get _utf8Converter() {
42         if (!this.__utf8Converter) {
43             this.__utf8Converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
44                                   createInstance(Ci.nsIScriptableUnicodeConverter);
45             this.__utf8Converter.charset = "UTF-8";
46         }
47         return this.__utf8Converter;
48     },
50     __utf16leConverter : null, // UCS2 <--> UTF16LE string conversion
51     get _utf16leConverter() {
52         if (!this.__utf16leConverter) {
53             this.__utf16leConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
54                                   createInstance(Ci.nsIScriptableUnicodeConverter);
55             this.__utf16leConverter.charset = "UTF-16LE";
56         }
57         return this.__utf16leConverter;
58     },
60     _utfConverterReset : function() {
61         this.__utf8Converter = null;
62         this.__utf16leConverter = null;
63     },
65     _iniFile : null,
66     _iniData : null,
68     /*
69      * Reads the INI file and stores the data internally.
70      */
71     _readFile : function() {
72         // If file doesn't exist, there's nothing to do.
73         if (!this._iniFile.exists() || 0 == this._iniFile.fileSize)
74             return;
76         let iniParser = Cc["@mozilla.org/xpcom/ini-parser-factory;1"]
77             .getService(Ci.nsIINIParserFactory).createINIParser(this._iniFile);
78         for (let section in XPCOMUtils.IterStringEnumerator(iniParser.getSections())) {
79             this._iniData[section] = {};
80             for (let key in XPCOMUtils.IterStringEnumerator(iniParser.getKeys(section))) {
81                 this._iniData[section][key] = iniParser.getString(section, key);
82             }
83         }
84     },
86     // nsIINIParser
88     getSections : function() {
89         let sections = [];
90         for (let section in this._iniData)
91             sections.push(section);
92         return new stringEnumerator(sections);
93     },
95     getKeys : function(aSection) {
96         let keys = [];
97         if (aSection in this._iniData)
98             for (let key in this._iniData[aSection])
99                 keys.push(key);
100         return new stringEnumerator(keys);
101     },
103     getString : function(aSection, aKey) {
104         if (!(aSection in this._iniData))
105             throw Cr.NS_ERROR_FAILURE;
106         if (!(aKey in this._iniData[aSection]))
107             throw Cr.NS_ERROR_FAILURE;
108         return this._iniData[aSection][aKey];
109     },
112     // nsIINIParserWriter
114     setString : function(aSection, aKey, aValue) {
115         const isSectionIllegal = /[\0\r\n\[\]]/;
116         const isKeyValIllegal  = /[\0\r\n=]/;
118         if (isSectionIllegal.test(aSection))
119             throw Components.Exception("bad character in section name",
120                                        Cr.ERROR_ILLEGAL_VALUE);
121         if (isKeyValIllegal.test(aKey) || isKeyValIllegal.test(aValue))
122             throw Components.Exception("bad character in key/value",
123                                        Cr.ERROR_ILLEGAL_VALUE);
125         if (!(aSection in this._iniData))
126             this._iniData[aSection] = {};
128         this._iniData[aSection][aKey] = aValue;
129     },
131     writeFile : function(aFile, aFlags) {
133         let converter;
134         function writeLine(data) {
135             data += "\n";
136             data = converter.ConvertFromUnicode(data);
137             data += converter.Finish();
138             outputStream.write(data, data.length);
139         }
141         if (!aFile)
142             aFile = this._iniFile;
144         let safeStream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
145                          createInstance(Ci.nsIFileOutputStream);
146         safeStream.init(aFile, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE,
147                         0600, null);
149         var outputStream = Cc["@mozilla.org/network/buffered-output-stream;1"].
150                            createInstance(Ci.nsIBufferedOutputStream);
151         outputStream.init(safeStream, 8192);
152         outputStream.QueryInterface(Ci.nsISafeOutputStream); // for .finish()
154         if (Ci.nsIINIParserWriter.WRITE_UTF16 == aFlags
155          && 'nsIWindowsRegKey' in Ci) {
156             outputStream.write("\xFF\xFE", 2);
157             converter = this._utf16leConverter;
158         } else {
159             converter = this._utf8Converter;
160         }
162         for (let section in this._iniData) {
163             writeLine("[" + section + "]");
164             for (let key in this._iniData[section]) {
165                 writeLine(key + "=" + this._iniData[section][key]);
166             }
167         }
169         outputStream.finish();
170     }
173 function stringEnumerator(stringArray) {
174     this._strings = stringArray;
176 stringEnumerator.prototype = {
177     QueryInterface : XPCOMUtils.generateQI([Ci.nsIUTF8StringEnumerator]),
179     _strings : null,
180     _enumIndex: 0,
182     hasMore : function() {
183         return (this._enumIndex < this._strings.length);
184     },
186     getNext : function() {
187         return this._strings[this._enumIndex++];
188     }
191 let component = [INIProcessorFactory];
192 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(component);