Here's my code for working with ini files. I use this all the time and it works well for me. Enjoy!
Code: Select all//
// IniFile.jsx
//
// $Id: IniFile.jsx,v 1.1 2006/11/21 21:15:09 anonymous Exp $
// Contact: xbytor@gmail.com
//
//
// IniFile is a set of functions for reading and writing ini files
// in a consistent fashion across a broad number of scripts.
//
function IniFile(fptr) {
};
//
// Return fptr if its a File or Folder, if not, make it one
//
IniFile.convertFptr = function(fptr) {
var f;
if (fptr.constructor == String) {
f = File(fptr);
} else if (fptr instanceof File || fptr instanceof Folder) {
f = fptr;
} else {
throw IOError("Bad file \"" + fptr + "\" specified.");
}
return f;
};
//
// Return an ini string to an object. Use 'ini' as the object if it's specified
//
IniFile.iniFromString = function(str, ini) {
var lines = str.split(/\r|\n/);
var rexp = new RegExp(/([^:]+):(.*)$/);
if (!ini) {
ini = {};
}
for (var i = 0; i < lines.length; i++) {
var line = IniFile.trim(lines);
if (!line || line.charAt(0) == '#') {
continue;
}
var ar = rexp.exec(line);
if (!ar) {
alert("Bad line in config: \"" + line + "\"");
return undefined;
}
ini[IniFile.trim(ar[1])] = IniFile.trim(ar[2]);
}
return ini;
};
//
// Return an ini file to an object. Use 'ini' as the object if it's specified
//
IniFile.read = function(iniFile, ini) {
if (!ini) {
ini = {};
}
if (!iniFile) {
return ini;
}
var file = IniFile.convertFptr(iniFile);
if (!file) {
throw "Bad ini file specified: \"" + iniFile + "\".";
}
if (!file.exists) {
}
if (file.exists && file.open("r")) {
var str = file.read();
ini = IniFile.iniFromString(str, ini);
file.close();
}
return ini;
};
//
// Return an ini string coverted from an object
//
IniFile.iniToString = function(ini) {
var str = '';
for (var idx in ini) {
if (idx.charAt(0) == '_') { // private stuff
continue;
}
if (idx == 'typename') {
continue;
}
var val = ini[idx];
if (val.constructor == String ||
val.constructor == Number ||
val.constructor == Boolean ||
typeof(val) == "object") {
str += (idx + ": " + val.toString() + "\n");
}
}
return str;
};
//
// Write an object to an ini file overwriting whatever was there before
//
IniFile.overwrite = function(iniFile, ini) {
if (!ini || !iniFile) {
return;
}
var file = IniFile.convertFptr.iniFileToFile(iniFile);
if (!file) {
throw "Bad ini file specified: \"" + iniFile + "\".";
}
if (!file.open("w")) {
throw "Unable to open ini file " + file + ": " + file.error;
}
var str = IniString.iniToString(ini);
file.write(str);
file.close();
return ini;
};
IniFile.trim = function(value) {
return value.replace(/^[\s]+|[\s]+$/g, '');
};
//
// Updating the ini file retains the ini file layout including any externally
// add comments, blank lines, and the property sequence
//
IniFile.update = function(iniFile, ini) {
if (!ini || !iniFile) {
return;
}
var file = IniFile.convertFptr(iniFile);
// we can only update the file if it exists
var update = file.exists;
var str = '';
if (update) {
file.open("r");
str = file.read();
file.close();
for (var idx in ini) {
if (idx.charAt(0) == '_') { // private stuff
continue;
}
if (idx == "typename") {
continue;
}
var val = ini[idx];
if (val == undefined) {
val = '';
}
if (typeof val == "string" ||
typeof val == "number" ||
typeof val == "boolean" ||
typeof val == "object") {
idx += ':';
var re = RegExp('^' + idx, 'm');
if (re.test(str)) {
re = RegExp('^' + idx + '[^\n]+', 'm');
str = str.replace(re, idx + ' ' + val);
} else {
str += '\n' + idx + ' ' + val;
}
}
}
} else {
str = IniFile.iniToString(ini);
}
if (str) {
if (!file.open("w")) {
throw "Unable to open ini file " + file + ": " + file.error;
}
file.write(str);
file.close();
}
return ini;
};
// By default, I update ini files instead of overwriting them.
IniFile.write = IniFile.update;
// convert an object into an easy-to-read string
listProps = function(obj) {
var s = '';
for (var x in obj) {
s += x + ":\t";
try {
var o = obj[x];
s += (typeof o == "function") ? "[function]" : o;
} catch (e) {
}
s += "\r\n";
}
return s;
};
// a simple demo of the INI functions
IniFile.demo1 = function() {
var obj = {
name: "bob",
age: 24
};
alert(listProps(obj));
IniFile.write("~/testfile.ini", obj);
var z = IniFile.read("~/testfile.ini", obj);
alert(listProps(z));
};
// a simple demo of the INI functions
IniFile.demo2 = function() {
var f = new File("~/testfile.ini");
var obj = {};
obj.city = "singapore";
IniFile.read(f, obj);
var z = IniFile.write(f, obj);
alert(listProps(z));
};
// IniFile.demo1();
// IniFile.demo2();
"IniFile.jsx";
// EOF
IniFile
IniFile
When I tried to use the Overwrite instead of Update option, I came up with errors on line 115 and 125, missing a couple of functions.
It seems to be fixed by the following, but I haven't studied it in great detail yet - is this right?
It's changed
var file = IniFile.convertFptr.iniFileToFile(iniFile);
to
var file = IniFile.convertFptr(iniFile);
as it didn't recognise iniFileToFile
and
var str = IniString.iniToString(ini);
to
var str = IniFile.iniToString(ini);
as it was missing IniString.
I've just borrowed bits from IniFile.Update, and it works on CS ok - or have I missed the point completely?
Code: Select all//
// Write an object to an ini file overwriting whatever was there before
//
IniFile.overwrite = function(iniFile, ini) {
if (!ini || !iniFile) {
return;
}
var file = IniFile.convertFptr(iniFile);
if (!file) {
throw "Bad ini file specified: \"" + iniFile + "\".";
}
if (!file.open("w")) {
throw "Unable to open ini file " + file + ": " + file.error;
}
var str = IniFile.iniToString(ini);
file.write(str);
file.close();
return ini;
};
IniFile.trim = function(value) {
return value.replace(/^[\s]+|[\s]+$/g, '');
};
It seems to be fixed by the following, but I haven't studied it in great detail yet - is this right?
It's changed
var file = IniFile.convertFptr.iniFileToFile(iniFile);
to
var file = IniFile.convertFptr(iniFile);
as it didn't recognise iniFileToFile
and
var str = IniString.iniToString(ini);
to
var str = IniFile.iniToString(ini);
as it was missing IniString.
I've just borrowed bits from IniFile.Update, and it works on CS ok - or have I missed the point completely?
Code: Select all//
// Write an object to an ini file overwriting whatever was there before
//
IniFile.overwrite = function(iniFile, ini) {
if (!ini || !iniFile) {
return;
}
var file = IniFile.convertFptr(iniFile);
if (!file) {
throw "Bad ini file specified: \"" + iniFile + "\".";
}
if (!file.open("w")) {
throw "Unable to open ini file " + file + ": " + file.error;
}
var str = IniFile.iniToString(ini);
file.write(str);
file.close();
return ini;
};
IniFile.trim = function(value) {
return value.replace(/^[\s]+|[\s]+$/g, '');
};
IniFile
You have to remember that all values are strings. If you need to use them as booleans or numbers, you have to convert them. These are the two functions that I use for this purpose:
Code: Select allfunction toBoolean(s) {
if (s == undefined) return false;
if (s.constructor == Boolean) return s.valueOf();
if (s.constructor == String) return s.toLowerCase() == "true";
return Boolean(s);
};
function toNumber(s) {
if (s == undefined) return NaN;
if (s.constructor == Number) return s.valueOf();
return Number(s.toString());
};
If you are trying to set a checkbox value like this:
Code: Select allchk.value = ini.chk;
it will be true if you have "true" or "false" in the ini file. You have to convert it like this:
Code: Select allchk.value = toBoolean(ini.chk);
In scripts where I have a lot of ini settings, I typically have a function called 'rationalize'. This function takes the ini object that I've just read in from the ini file and does all of the conversions to numbers, booleans, Files, Colors, Fonts, or whatever. If I don't do it like this, I'll eventually forget to do the conversion in my code somewhere and I'll wonder when the checkbox is always true.
If you want to take a look at a script that uses these techniques to the extreme, take a look at CSX. Much of what's in IniFile was built in response to the needs of that script.
-X
Code: Select allfunction toBoolean(s) {
if (s == undefined) return false;
if (s.constructor == Boolean) return s.valueOf();
if (s.constructor == String) return s.toLowerCase() == "true";
return Boolean(s);
};
function toNumber(s) {
if (s == undefined) return NaN;
if (s.constructor == Number) return s.valueOf();
return Number(s.toString());
};
If you are trying to set a checkbox value like this:
Code: Select allchk.value = ini.chk;
it will be true if you have "true" or "false" in the ini file. You have to convert it like this:
Code: Select allchk.value = toBoolean(ini.chk);
In scripts where I have a lot of ini settings, I typically have a function called 'rationalize'. This function takes the ini object that I've just read in from the ini file and does all of the conversions to numbers, booleans, Files, Colors, Fonts, or whatever. If I don't do it like this, I'll eventually forget to do the conversion in my code somewhere and I'll wonder when the checkbox is always true.
If you want to take a look at a script that uses these techniques to the extreme, take a look at CSX. Much of what's in IniFile was built in response to the needs of that script.
-X