mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Bug 541594 - extend nsIINIParser to allow writing INI files. p=dolske+benjamin, r=benjamin, r=dolske
This commit is contained in:
parent
264dc95781
commit
3e1253bd35
@ -281,6 +281,28 @@ var XPCOMUtils = {
|
||||
.getService(Ci.nsICategoryManager);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper which iterates over a nsISimpleEnumerator.
|
||||
* @param e The nsISimpleEnumerator to iterate over.
|
||||
* @param i The expected interface for each element.
|
||||
*/
|
||||
IterSimpleEnumerator: function XPCU_IterSimpleEnumerator(e, i)
|
||||
{
|
||||
while (e.hasMoreElements())
|
||||
yield e.getNext().QueryInterface(i);
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper which iterates over a string enumerator.
|
||||
* @param e The string enumerator (nsIUTF8StringEnumerator or
|
||||
* nsIStringEnumerator) over which to iterate.
|
||||
*/
|
||||
IterStringEnumerator: function XPCU_IterStringEnumerator(e)
|
||||
{
|
||||
while (e.hasMore())
|
||||
yield e.getNext();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns an nsIFactory for |component|.
|
||||
*/
|
||||
@ -314,3 +336,4 @@ function makeQI(interfaceNames) {
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -154,6 +154,10 @@ XPIDLSRCS += nsIWindowsRegKey.idl
|
||||
EXPORTS += nsWindowsRegKey.h
|
||||
endif
|
||||
|
||||
EXTRA_COMPONENTS = \
|
||||
nsINIProcessor.js \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
|
@ -59,6 +59,20 @@ interface nsIINIParser : nsISupports
|
||||
AUTF8String getString(in AUTF8String aSection, in AUTF8String aKey);
|
||||
};
|
||||
|
||||
[scriptable, uuid(712dc5da-8d09-45d0-ba2e-de27eb384c4c)]
|
||||
interface nsIINIParserWriter : nsISupports
|
||||
{
|
||||
/**
|
||||
* Set the value of a string for a particular section and key.
|
||||
*/
|
||||
void setString(in AUTF8String aSection, in AUTF8String aKey, in AUTF8String aValue);
|
||||
|
||||
/**
|
||||
* Write to the INI file.
|
||||
*/
|
||||
void writeFile([optional] in nsILocalFile aINIFile);
|
||||
};
|
||||
|
||||
[scriptable, uuid(ccae7ea5-1218-4b51-aecb-c2d8ecd46af9)]
|
||||
interface nsIINIParserFactory : nsISupports
|
||||
{
|
||||
|
209
xpcom/ds/nsINIProcessor.js
Normal file
209
xpcom/ds/nsINIProcessor.js
Normal file
@ -0,0 +1,209 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Justin Dolske <dolske@mozilla.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
function INIProcessorFactory() {
|
||||
}
|
||||
|
||||
INIProcessorFactory.prototype = {
|
||||
classDescription: "INIProcessorFactory",
|
||||
contractID: "@mozilla.org/xpcom/ini-processor-factory;1",
|
||||
classID: Components.ID("{6ec5f479-8e13-4403-b6ca-fe4c2dca14fd}"),
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIINIParserFactory]),
|
||||
|
||||
createINIParser : function (aINIFile) {
|
||||
return new INIProcessor(aINIFile);
|
||||
}
|
||||
|
||||
}; // end of INIProcessorFactory implementation
|
||||
|
||||
const MODE_WRONLY = 0x02;
|
||||
const MODE_CREATE = 0x08;
|
||||
const MODE_TRUNCATE = 0x20;
|
||||
|
||||
// nsIINIParser implementation
|
||||
function INIProcessor(aFile) {
|
||||
this._iniFile = aFile;
|
||||
this._iniData = {};
|
||||
this._readFile();
|
||||
}
|
||||
|
||||
INIProcessor.prototype = {
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIINIParser, Ci.nsIINIParserWriter]),
|
||||
|
||||
__utfConverter : null, // UCS2 <--> UTF8 string conversion
|
||||
get _utfConverter() {
|
||||
if (!this.__utfConverter) {
|
||||
this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||
this.__utfConverter.charset = "UTF-8";
|
||||
}
|
||||
return this.__utfConverter;
|
||||
},
|
||||
|
||||
_utfConverterReset : function() {
|
||||
this.__utfConverter = null;
|
||||
},
|
||||
|
||||
_iniFile : null,
|
||||
_iniData : null,
|
||||
|
||||
/*
|
||||
* Reads the INI file and stores the data internally.
|
||||
*/
|
||||
_readFile : function() {
|
||||
// If file doesn't exist, there's nothing to do.
|
||||
if (!this._iniFile.exists() || 0 == this._iniFile.fileSize)
|
||||
return;
|
||||
|
||||
let iniParser = Cc["@mozilla.org/xpcom/ini-parser-factory;1"]
|
||||
.getService(Ci.nsIINIParserFactory).createINIParser(this._iniFile);
|
||||
for (let section in XPCOMUtils.IterStringEnumerator(iniParser.getSections())) {
|
||||
this._iniData[section] = {};
|
||||
for (let key in XPCOMUtils.IterStringEnumerator(iniParser.getKeys(section))) {
|
||||
this._iniData[section][key] = iniParser.getString(section, key);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// nsIINIParser
|
||||
|
||||
getSections : function() {
|
||||
let sections = [];
|
||||
for (let section in this._iniData)
|
||||
sections.push(section);
|
||||
return new stringEnumerator(sections);
|
||||
},
|
||||
|
||||
getKeys : function(aSection) {
|
||||
let keys = [];
|
||||
if (aSection in this._iniData)
|
||||
for (let key in this._iniData[aSection])
|
||||
keys.push(key);
|
||||
return new stringEnumerator(keys);
|
||||
},
|
||||
|
||||
getString : function(aSection, aKey) {
|
||||
if (!(aSection in this._iniData))
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
if (!(aKey in this._iniData[aSection]))
|
||||
throw Cr.NS_ERROR_FAILURE;
|
||||
return this._iniData[aSection][aKey];
|
||||
},
|
||||
|
||||
|
||||
// nsIINIParserWriter
|
||||
|
||||
setString : function(aSection, aKey, aValue) {
|
||||
const isSectionIllegal = /[\0\r\n\[\]]/;
|
||||
const isKeyValIllegal = /[\0\r\n=]/;
|
||||
|
||||
if (isSectionIllegal.test(aSection))
|
||||
throw Components.Exception("bad character in section name",
|
||||
Cr.ERROR_ILLEGAL_VALUE);
|
||||
if (isKeyValIllegal.test(aKey) || isKeyValIllegal.test(aValue))
|
||||
throw Components.Exception("bad character in key/value",
|
||||
Cr.ERROR_ILLEGAL_VALUE);
|
||||
|
||||
if (!(aSection in this._iniData))
|
||||
this._iniData[aSection] = {};
|
||||
|
||||
this._iniData[aSection][aKey] = aValue;
|
||||
},
|
||||
|
||||
writeFile : function(aFile) {
|
||||
|
||||
let converter = this._utfConverter;
|
||||
function writeLine(data) {
|
||||
data = converter.ConvertFromUnicode(data);
|
||||
data += converter.Finish();
|
||||
data += "\n";
|
||||
outputStream.write(data, data.length);
|
||||
}
|
||||
|
||||
if (!aFile)
|
||||
aFile = this._iniFile;
|
||||
|
||||
let safeStream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
|
||||
createInstance(Ci.nsIFileOutputStream);
|
||||
safeStream.init(aFile, MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE,
|
||||
0600, null);
|
||||
|
||||
var outputStream = Cc["@mozilla.org/network/buffered-output-stream;1"].
|
||||
createInstance(Ci.nsIBufferedOutputStream);
|
||||
outputStream.init(safeStream, 8192);
|
||||
outputStream.QueryInterface(Ci.nsISafeOutputStream); // for .finish()
|
||||
|
||||
for (let section in this._iniData) {
|
||||
writeLine("[" + section + "]");
|
||||
for (let key in this._iniData[section]) {
|
||||
writeLine(key + "=" + this._iniData[section][key]);
|
||||
}
|
||||
}
|
||||
|
||||
outputStream.finish();
|
||||
}
|
||||
};
|
||||
|
||||
function stringEnumerator(stringArray) {
|
||||
this._strings = stringArray;
|
||||
}
|
||||
stringEnumerator.prototype = {
|
||||
QueryInterface : XPCOMUtils.generateQI([Ci.nsIUTF8StringEnumerator]),
|
||||
|
||||
_strings : null,
|
||||
_enumIndex: 0,
|
||||
|
||||
hasMore : function() {
|
||||
return (this._enumIndex < this._strings.length);
|
||||
},
|
||||
|
||||
getNext : function() {
|
||||
return this._strings[this._enumIndex++];
|
||||
}
|
||||
};
|
||||
|
||||
let component = [INIProcessorFactory];
|
||||
function NSGetModule (compMgr, fileSpec) {
|
||||
return XPCOMUtils.generateModule(component);
|
||||
}
|
@ -91,7 +91,7 @@ NS_strtok(const char *delims, char **str)
|
||||
} while (*i);
|
||||
|
||||
*str = NULL;
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
@ -163,7 +163,6 @@ nsINIParser::InitFromFILE(FILE *fd)
|
||||
|
||||
char *buffer = mFileContents;
|
||||
char *currSection = nsnull;
|
||||
INIValue *last = nsnull;
|
||||
|
||||
// outer loop tokenizes into lines
|
||||
while (char *token = NS_strtok(kNL, &buffer)) {
|
||||
@ -177,7 +176,6 @@ nsINIParser::InitFromFILE(FILE *fd)
|
||||
if (token[0] == '[') { // section header!
|
||||
++token;
|
||||
currSection = token;
|
||||
last = nsnull;
|
||||
|
||||
char *rb = NS_strtok(kRBracket, &token);
|
||||
if (!rb || NS_strtok(kWhitespace, &token)) {
|
||||
@ -202,28 +200,32 @@ nsINIParser::InitFromFILE(FILE *fd)
|
||||
if (!e)
|
||||
continue;
|
||||
|
||||
INIValue *val = new INIValue(key, token);
|
||||
if (!val)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
INIValue *v;
|
||||
if (!mSections.Get(currSection, &v)) {
|
||||
v = new INIValue(key, token);
|
||||
if (!v)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
// If we haven't already added something to this section, "last" will
|
||||
// be null.
|
||||
if (!last) {
|
||||
mSections.Get(currSection, &last);
|
||||
while (last && last->next)
|
||||
last = last->next;
|
||||
}
|
||||
|
||||
if (last) {
|
||||
// Add this element on to the tail of the existing list
|
||||
|
||||
last->next = val;
|
||||
last = val;
|
||||
mSections.Put(currSection, v);
|
||||
continue;
|
||||
}
|
||||
|
||||
// We've never encountered this section before, add it to the head
|
||||
mSections.Put(currSection, val);
|
||||
// Check whether this key has already been specified; overwrite
|
||||
// if so, or append if not.
|
||||
while (v) {
|
||||
if (!strcmp(key, v->key)) {
|
||||
v->value = token;
|
||||
break;
|
||||
}
|
||||
if (!v->next) {
|
||||
v->next = new INIValue(key, token);
|
||||
if (!v->next)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
v = v->next;
|
||||
}
|
||||
NS_ASSERTION(v, "v should never be null coming out of this loop");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
0
xpcom/tests/unit/data/iniparser01.ini
Normal file
0
xpcom/tests/unit/data/iniparser01.ini
Normal file
1
xpcom/tests/unit/data/iniparser02.ini
Normal file
1
xpcom/tests/unit/data/iniparser02.ini
Normal file
@ -0,0 +1 @@
|
||||
|
1
xpcom/tests/unit/data/iniparser03.ini
Normal file
1
xpcom/tests/unit/data/iniparser03.ini
Normal file
@ -0,0 +1 @@
|
||||
[]
|
1
xpcom/tests/unit/data/iniparser04.ini
Normal file
1
xpcom/tests/unit/data/iniparser04.ini
Normal file
@ -0,0 +1 @@
|
||||
[section1]
|
1
xpcom/tests/unit/data/iniparser05.ini
Normal file
1
xpcom/tests/unit/data/iniparser05.ini
Normal file
@ -0,0 +1 @@
|
||||
[section1]junk
|
2
xpcom/tests/unit/data/iniparser06.ini
Normal file
2
xpcom/tests/unit/data/iniparser06.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[section1]
|
||||
|
2
xpcom/tests/unit/data/iniparser07.ini
Normal file
2
xpcom/tests/unit/data/iniparser07.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[section1]
|
||||
name1
|
2
xpcom/tests/unit/data/iniparser08.ini
Normal file
2
xpcom/tests/unit/data/iniparser08.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[section1]
|
||||
name1=
|
2
xpcom/tests/unit/data/iniparser09.ini
Normal file
2
xpcom/tests/unit/data/iniparser09.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[section1]
|
||||
name1=value1
|
3
xpcom/tests/unit/data/iniparser10.ini
Normal file
3
xpcom/tests/unit/data/iniparser10.ini
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
[section1]
|
||||
name1=value1
|
3
xpcom/tests/unit/data/iniparser11.ini
Normal file
3
xpcom/tests/unit/data/iniparser11.ini
Normal file
@ -0,0 +1,3 @@
|
||||
# comment
|
||||
[section1]
|
||||
name1=value1
|
3
xpcom/tests/unit/data/iniparser12.ini
Normal file
3
xpcom/tests/unit/data/iniparser12.ini
Normal file
@ -0,0 +1,3 @@
|
||||
[section1]
|
||||
# [sectionBAD]
|
||||
name1=value1
|
3
xpcom/tests/unit/data/iniparser13.ini
Normal file
3
xpcom/tests/unit/data/iniparser13.ini
Normal file
@ -0,0 +1,3 @@
|
||||
[section1]
|
||||
name1=value1
|
||||
# nameBAD=valueBAD
|
6
xpcom/tests/unit/data/iniparser14.ini
Normal file
6
xpcom/tests/unit/data/iniparser14.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[section1]
|
||||
name1=value1
|
||||
name2=value2
|
||||
[section2]
|
||||
name1=value1
|
||||
name2=foopy
|
6
xpcom/tests/unit/data/iniparser15.ini
Normal file
6
xpcom/tests/unit/data/iniparser15.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[section1]
|
||||
name1=value1
|
||||
[section2]
|
||||
name1=foopy
|
||||
[section1]
|
||||
name1=newValue1
|
211
xpcom/tests/unit/test_iniProcessor.js
Normal file
211
xpcom/tests/unit/test_iniProcessor.js
Normal file
@ -0,0 +1,211 @@
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cr = Components.results;
|
||||
|
||||
let testnum = 0;
|
||||
let factory;
|
||||
|
||||
function parserForFile(filename) {
|
||||
let parser = null;
|
||||
try {
|
||||
let file = do_get_file(filename);
|
||||
do_check_true(!!file);
|
||||
parser = factory.createINIParser(file);
|
||||
do_check_true(!!parser);
|
||||
} catch(e) {
|
||||
dump("INFO | caught error: " + e);
|
||||
// checkParserOutput will handle a null parser when it's expected.
|
||||
}
|
||||
return parser;
|
||||
|
||||
}
|
||||
|
||||
function checkParserOutput(parser, expected) {
|
||||
// If the expected output is null, we expect the parser to have
|
||||
// failed (and vice-versa).
|
||||
if (!parser || !expected) {
|
||||
do_check_eq(parser, null);
|
||||
do_check_eq(expected, null);
|
||||
return;
|
||||
}
|
||||
|
||||
let output = getParserOutput(parser);
|
||||
for (let section in expected) {
|
||||
do_check_true(section in output);
|
||||
for (let key in expected[section]) {
|
||||
do_check_true(key in output[section]);
|
||||
do_check_eq(output[section][key], expected[section][key]);
|
||||
delete output[section][key];
|
||||
}
|
||||
for (let key in output[section])
|
||||
do_check_eq(key, "wasn't expecting this key!");
|
||||
delete output[section];
|
||||
}
|
||||
for (let section in output)
|
||||
do_check_eq(section, "wasn't expecting this section!");
|
||||
}
|
||||
|
||||
function getParserOutput(parser) {
|
||||
let output = {};
|
||||
|
||||
let sections = parser.getSections();
|
||||
do_check_true(!!sections);
|
||||
while (sections.hasMore()) {
|
||||
let section = sections.getNext();
|
||||
do_check_false(section in output); // catch dupes
|
||||
output[section] = {};
|
||||
|
||||
let keys = parser.getKeys(section);
|
||||
do_check_true(!!keys);
|
||||
while (keys.hasMore()) {
|
||||
let key = keys.getNext();
|
||||
do_check_false(key in output[section]); // catch dupes
|
||||
let value = parser.getString(section, key);
|
||||
output[section][key] = value;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
try {
|
||||
|
||||
let testdata = [
|
||||
{ filename: "data/iniparser01.ini", reference: {} },
|
||||
{ filename: "data/iniparser02.ini", reference: {} },
|
||||
{ filename: "data/iniparser03.ini", reference: {} },
|
||||
{ filename: "data/iniparser04.ini", reference: {} },
|
||||
{ filename: "data/iniparser05.ini", reference: {} },
|
||||
{ filename: "data/iniparser06.ini", reference: {} },
|
||||
{ filename: "data/iniparser07.ini", reference: {} },
|
||||
{ filename: "data/iniparser08.ini", reference: { section1: { name1: "" }} },
|
||||
{ filename: "data/iniparser09.ini", reference: { section1: { name1: "value1" } } },
|
||||
{ filename: "data/iniparser10.ini", reference: { section1: { name1: "value1" } } },
|
||||
{ filename: "data/iniparser11.ini", reference: { section1: { name1: "value1" } } },
|
||||
{ filename: "data/iniparser12.ini", reference: { section1: { name1: "value1" } } },
|
||||
{ filename: "data/iniparser13.ini", reference: { section1: { name1: "value1" } } },
|
||||
{ filename: "data/iniparser14.ini", reference:
|
||||
{ section1: { name1: "value1", name2: "value2" },
|
||||
section2: { name1: "value1", name2: "foopy" }} },
|
||||
{ filename: "data/iniparser15.ini", reference:
|
||||
{ section1: { name1: "newValue1" },
|
||||
section2: { name1: "foopy" }} },
|
||||
];
|
||||
|
||||
/* ========== 0 ========== */
|
||||
factory = Cc["@mozilla.org/xpcom/ini-processor-factory;1"].
|
||||
getService(Ci.nsIINIParserFactory);
|
||||
do_check_true(!!factory);
|
||||
|
||||
/* ========== 1 - 15 ========== */
|
||||
|
||||
// Test reading from a variety of files. While we're at it, write out each one
|
||||
// and read it back to ensure that nothing changed.
|
||||
for (testnum = 1; testnum <= 15; testnum++) {
|
||||
let filename = testdata[testnum -1].filename;
|
||||
dump("INFO | test #" + testnum + ", filename " + filename + "\n");
|
||||
let parser = parserForFile(filename);
|
||||
checkParserOutput(parser, testdata[testnum - 1].reference);
|
||||
if (!parser)
|
||||
continue;
|
||||
do_check_true(parser instanceof Ci.nsIINIParserWriter);
|
||||
// write contents out to a new file
|
||||
let newfilename = filename + ".new";
|
||||
let newfile = do_get_file(filename);
|
||||
newfile.leafName += ".new";
|
||||
parser.writeFile(newfile);
|
||||
// read new file and make sure the contents are the same.
|
||||
parser = parserForFile(newfilename);
|
||||
checkParserOutput(parser, testdata[testnum - 1].reference);
|
||||
}
|
||||
|
||||
/* ========== 16 ========== */
|
||||
|
||||
// test writing to a new file.
|
||||
let newfile = do_get_file("data/");
|
||||
newfile.append("non-existant-file.ini");
|
||||
if (newfile.exists())
|
||||
newfile.remove(false);
|
||||
do_check_false(newfile.exists());
|
||||
|
||||
let parser = factory.createINIParser(newfile);
|
||||
do_check_true(!!parser);
|
||||
do_check_true(parser instanceof Ci.nsIINIParserWriter);
|
||||
checkParserOutput(parser, {});
|
||||
parser.writeFile();
|
||||
do_check_true(newfile.exists());
|
||||
|
||||
// test adding a new section and new key
|
||||
parser.setString("section", "key", "value");
|
||||
parser.writeFile();
|
||||
do_check_true(newfile.exists());
|
||||
checkParserOutput(parser, {section: {key: "value"} });
|
||||
// read it in again, check for same data.
|
||||
parser = parserForFile("data/non-existant-file.ini");
|
||||
checkParserOutput(parser, {section: {key: "value"} });
|
||||
|
||||
/* ========== 17 ========== */
|
||||
|
||||
// test modifying a existing key's value (in an existing section)
|
||||
parser = parserForFile("data/iniparser09.ini");
|
||||
checkParserOutput(parser, {section1: {name1: "value1"} });
|
||||
|
||||
do_check_true(parser instanceof Ci.nsIINIParserWriter);
|
||||
parser.setString("section1", "name1", "value2");
|
||||
checkParserOutput(parser, {section1: {name1: "value2"} });
|
||||
|
||||
/* ========== 18 ========== */
|
||||
|
||||
// test trying to set illegal characters
|
||||
let caughtError;
|
||||
caughtError = false;
|
||||
checkParserOutput(parser, {section1: {name1: "value2"} });
|
||||
|
||||
// Bad characters in section name
|
||||
try { parser.SetString("bad\0", "ok", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("bad\r", "ok", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("bad\n", "ok", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("bad[", "ok", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("bad]", "ok", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
|
||||
// Bad characters in key name
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "bad\0", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "bad\r", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "bad\n", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "bad=", "ok"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
|
||||
// Bad characters in value
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "ok", "bad\0"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "ok", "bad\r"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "ok", "bad\n"); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
caughtError = false;
|
||||
try { parser.SetString("ok", "ok", "bad="); } catch (e) { caughtError = true; }
|
||||
do_check_true(caughtError);
|
||||
|
||||
} catch(e) {
|
||||
throw "FAILED in test #" + testnum + " -- " + e;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user