stringList
};
+// note: missing application data location support on windows
+enum SettingsLocationType { none, specified, portable, home, winUserProfile, winHomeDrive, winSystemPath, winAllUsers, nixEtc };
+
public enum SettingsIOResult { error, success, fileNotFound, fileNotCompatibleWithDriver };
public class GlobalSettingsDriver
set { allUsers = value; }
get { return allUsers; }
};
+ property bool portable
+ {
+ set { portable = value; }
+ get { return portable; }
+ };
property const String driver
{
GlobalSettingsData data;
GlobalSettingsData * dataOwner;
subclass(GlobalSettingsData) dataClass;
- bool portable;
private:
char * settingsName;
char * settingsFilePath;
bool allowDefaultLocations;
bool allUsers;
+ bool portable;
bool globalPath;
char * settingsDirectory;
+ SettingsLocationType readType;
+ SettingsLocationType writeType;
FileMonitor settingsMonitor
{
delete settingsDirectory;
}
- char * PrepareSpecifiedLocationPath(const char * extension, bool create)
- {
- char * path = null;
- char location[MAX_LOCATION] = "";
- if(settingsLocation)
- strcpy(location, settingsLocation);
- path = GetFilePath(location, extension, create, false, false);
- return path;
- }
-
- char * PreparePortablePath(const char * extension, bool create)
+ char * PreparePath(SettingsLocationType type, const char * extension, bool create, bool unixStyle)
{
- //
char * path = null;
- char location[MAX_LOCATION];
- LocateModule(null, location);
- StripLastDirectory(location, location);
- path = GetFilePath(location, extension, create, false, false);
- return path;
- }
-
- char * PrepareHomePath(const char * extension, bool create, bool unixStyle)
- {
- // ~/.apprc
- char * path = null;
- char * home = getenv("HOME");
- if(home && home[0])
+ char * buffer = new char[MAX_LOCATION];
+ switch(type)
{
- char location[MAX_LOCATION];
- strcpy(location, home);
- path = GetFilePath(location, extension, create, true, unixStyle);
- }
- return path;
- }
-
+ case specified:
+ if(settingsLocation)
+ {
+ buffer[0] = '\0';
+ strcpy(buffer, settingsLocation);
+ path = GetFilePath(buffer, extension, create, false, false);
+ }
+ break;
+ case portable:
+ buffer[0] = '\0';
+ LocateModule(null, buffer);
+ StripLastDirectory(buffer, buffer);
+ path = GetFilePath(buffer, extension, create, false, false);
+ break;
+ case home:
+ {
+ // ~/.apprc
+ char * home = getenv("HOME");
+ if(home && home[0])
+ {
+ strcpy(buffer, home);
+ path = GetFilePath(buffer, extension, create, true, unixStyle);
+ }
+ break;
+ }
#if defined(__WIN32__)
- char * PrepareUserProfilePath(const char * extension, bool create)
- {
- // Windows attempts: $USERPROFILE/app.ini
- char * path = null;
- char * profile = getenv("USERPROFILE");
- if(profile && profile[0])
- {
- char location[MAX_LOCATION];
- strcpy(location, profile);
- path = GetFilePath(location, extension, create, false, false);
- }
- return path;
- }
-
- char * PrepareHomeDrivePath(const char * extension, bool create)
- {
- char * path = null;
- const char * homedrive = getenv("HOMEDRIVE");
- const char * homepath = getenv("HOMEPATH");
- if(homedrive && homedrive[0] && homepath && homepath[0])
- {
- char location[MAX_LOCATION];
- strcpy(location, homedrive);
- PathCatSlash(location, homepath);
- path = GetFilePath(location, extension, create, false, false);
- }
- return path;
- }
-
- char * PrepareSystemPath(const char * extension, bool create)
- {
- char * path = null;
- uint16 _wfilePath[MAX_LOCATION];
- char location[MAX_LOCATION];
- GetSystemDirectory(_wfilePath, MAX_LOCATION);
- UTF16toUTF8Buffer(_wfilePath, location, MAX_LOCATION);
- path = GetFilePath(location, extension, create, false, false);
- return path;
- }
-
- char * PrepareAllUsersPath(const char * extension, bool create)
- {
- char * path = null;
- char * allUsers = getenv("ALLUSERSPROFILE");
- if(allUsers && allUsers[0])
- {
- char location[MAX_LOCATION];
- strcpy(location, allUsers);
- path = GetFilePath(location, extension, create, false, false);
- }
- return path;
- }
+ case winUserProfile:
+ {
+ // Windows attempts: $USERPROFILE/app.ini
+ char * profile = getenv("USERPROFILE");
+ if(profile && profile[0])
+ {
+ strcpy(buffer, profile);
+ path = GetFilePath(buffer, extension, create, false, false);
+ }
+ break;
+ }
+ case winHomeDrive:
+ {
+ const char * homedrive = getenv("HOMEDRIVE");
+ const char * homepath = getenv("HOMEPATH");
+ if(homedrive && homedrive[0] && homepath && homepath[0])
+ {
+ strcpy(buffer, homedrive);
+ PathCatSlash(buffer, homepath);
+ path = GetFilePath(buffer, extension, create, false, false);
+ }
+ break;
+ }
+ case winSystemPath:
+ {
+ uint16 _wfilePath[MAX_LOCATION];
+ buffer[0] = '\0';
+ GetSystemDirectory(_wfilePath, MAX_LOCATION);
+ UTF16toUTF8Buffer(_wfilePath, buffer, MAX_LOCATION);
+ path = GetFilePath(buffer, extension, create, false, false);
+ break;
+ }
+ case winAllUsers:
+ {
+ char * allUsers = getenv("ALLUSERSPROFILE");
+ if(allUsers && allUsers[0])
+ {
+ strcpy(buffer, allUsers);
+ path = GetFilePath(buffer, extension, create, false, false);
+ }
+ break;
+ }
#else
- char * PrepareEtcPath(const char * extension, bool create)
- {
- char * path = null;
- char location[MAX_LOCATION] = "/etc/";
- path = GetFilePath(location, extension, create, false, false);
+ case nixEtc:
+ {
+ strcpy(buffer, "/etc/");
+ path = GetFilePath(buffer, extension, create, false, false);
+ delete buffer;
+ break;
+ }
+#endif
+ }
+ if(!path) delete buffer;
return path;
}
-#endif
char * GetFilePath(char * location, const char * extension, bool create, bool dotPrefix, bool runCommandsStyle)
{
FileAttribs attribs;
if(location[0])
MakeSlashPath(location);
- if(location[0] && (attribs = FileExists(location)).isDirectory)
+ if(location[0] && (attribs = FileExists(location)) && (attribs.isDirectory || attribs.isDrive))
{
if(settingsDirectory)
{
MakeDir(location);
attribs = FileExists(location);
}
- if(attribs.isDirectory)
+ if(attribs.isDirectory || attribs.isDrive)
{
char * name = new char[strlen(settingsName) + strlen(extension) + 2];
if(dotPrefix && !settingsDirectory)
strcat(name, ".");
strcat(name, extension);
}
- path = new char[strlen(location) + strlen(name) + 16];
- strcpy(path, location);
- PathCatSlash(path, name);
+ PathCatSlash(location, name);
+ path = location;
delete name;
}
}
return extension;
}
- void FileOpenTryRead()
+ void FileOpenTryRead(SettingsLocationType type)
{
f = FileOpen(settingsFilePath, read);
- //PrintLn("GlobalSettings::FileOpenTryRead -- ", settingsFilePath, " -- ", f != null);
- if(!f) // This delete will cover both trying the next possible config location and
+ //PrintLn("GlobalSettings::FileOpenTryRead(", type, ") (", settingsFilePath, ") -- ", f ? "SUCCESS" : "FAIL");
+ if(f)
+ readType = type;
+ else
+ {
+ // This delete will cover both trying the next possible config location and
delete settingsFilePath; // the case when we're doing a load when the config file is no longer available
- } // and we want to re-try all possible config locations.
+ } // and we want to re-try all possible config locations.
+ }
- bool FileOpenTryWrite(bool shouldDelete, bool * locked)
+ bool FileOpenTryWrite(SettingsLocationType type, bool shouldDelete, bool * locked)
{
*locked = false;
f = FileOpen(settingsFilePath, readWrite);
f = FileOpen(settingsFilePath, readWrite);
}
}
+ //PrintLn("GlobalSettings::FileOpenTryWrite(", type, ") (", settingsFilePath, ") -- ", f ? "SUCCESS" : "FAIL");
if(f)
{
+ writeType = type;
// Don't wait for a lock, first one to lock gets to write, other will likely loose changes on a reload.
if(f.Lock(exclusive, 0, 0, false))
{
}
}
}
- else if(shouldDelete) // This delete will cover both trying the next possible config location and
- delete settingsFilePath; // allow trying to save to a location where user has permission.
- //PrintLn("GlobalSettings::FileOpenTryWrite -- ", settingsFilePath, " -- ", f != null);
+ else if(shouldDelete)
+ {
+ delete settingsFilePath; // This delete will cover both trying the next possible config location and
+ } // allow trying to save to a location where user has permission.
return f != null;
}
bool OpenAndLock(FileSize * fileSize)
{
+ SettingsLocationType type = readType;
if(!f)
{
settingsMonitor.StopMonitoring();
if(settingsFilePath)
- FileOpenTryRead();
+ FileOpenTryRead(type);
if(!settingsFilePath && settingsName && settingsName[0])
{
const char * extension = GetExtension();
- if(!f && (settingsFilePath = PrepareSpecifiedLocationPath(extension, false)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = specified), extension, false, false)))
+ FileOpenTryRead(type);
if(!f && (!settingsLocation || allowDefaultLocations))
{
globalPath = false;
- if(!f && (settingsFilePath = PreparePortablePath(extension, false)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = portable), extension, false, false)))
+ FileOpenTryRead(type);
if(f)
portable = true;
if(!allUsers)
{
#if defined(__WIN32__)
- if(!f && (settingsFilePath = PrepareHomePath(extension, false, false)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = home), extension, false, false)))
+ FileOpenTryRead(type);
#endif
- if(!f && (settingsFilePath = PrepareHomePath(extension, false, true)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = home), extension, false, true)))
+ FileOpenTryRead(type);
}
#if defined(__WIN32__)
if(!allUsers)
{
- if(!f && (settingsFilePath = PrepareUserProfilePath(extension, false)))
- FileOpenTryRead();
- if(!f && (settingsFilePath = PrepareHomeDrivePath(extension, false)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = winUserProfile), extension, false, false)))
+ FileOpenTryRead(type);
+ if(!f && (settingsFilePath = PreparePath((type = winHomeDrive), extension, false, false)))
+ FileOpenTryRead(type);
}
if(!f)
globalPath = true;
- if(!f && (settingsFilePath = PrepareAllUsersPath(extension, false)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = winAllUsers), extension, false, false)))
+ FileOpenTryRead(type);
- if(!f && (settingsFilePath = PrepareSystemPath(extension, false)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = winSystemPath), extension, false, false)))
+ FileOpenTryRead(type);
#else
if(!f)
globalPath = true;
- if(!f && (settingsFilePath = PrepareEtcPath(extension, false)))
- FileOpenTryRead();
+ if(!f && (settingsFilePath = PreparePath((type = nixEtc), extension, false, false)))
+ FileOpenTryRead(type);
#endif
}
}
virtual SettingsIOResult Save()
{
SettingsIOResult result = error;
+ SettingsLocationType type = writeType;
if(!f)
{
locked = false;
if(settingsFilePath)
// Don't auto delete settingsFilePath because only want to try another path if we were using a global path
- FileOpenTryWrite(false, &locked);
+ FileOpenTryWrite(type, false, &locked);
if((!settingsFilePath || (!f && globalPath)) && settingsName && settingsName[0])
{
const char * extension = GetExtension();
delete settingsFilePath;
- if(!f && (settingsFilePath = PrepareSpecifiedLocationPath(extension, true)))
- FileOpenTryWrite(true, &locked);
+ if(!f && (settingsFilePath = PreparePath((type = specified), extension, true, false)))
+ FileOpenTryWrite(type, true, &locked);
if(!f && (!settingsLocation || allowDefaultLocations))
{
globalPath = true;
- // never try to write a new portable configuration file?
- // -- Probably always want to write back to the same file, the first FileOpenTryWrite(true) should succeed
- //if(!f && (settingsFilePath = PreparePortablePath(extension, true)))
- // FileOpenTryWrite(true);
+ if(!f && portable && (settingsFilePath = PreparePath((type = portable), extension, true, false)))
+ FileOpenTryWrite(type, true, &locked);
#if defined(__WIN32__)
- if(!f && allUSers && (settingsFilePath = PrepareAllUsersPath()))
- FileOpenTryWrite(true, &locked);
+ if(!f && allUsers && (settingsFilePath = PreparePath((type = winAllUsers), extension, true, false)))
+ FileOpenTryWrite(type, true, &locked);
#else
- if(!f && allUSers && (settingsFilePath = PrepareEtcPath()))
- FileOpenTryWrite(true, &locked);
+ if(!f && allUsers && (settingsFilePath = PreparePath((type = nixEtc), extension, true, false)))
+ FileOpenTryWrite(type, true, &locked);
#endif
if(!f && !allUsers)
{
globalPath = false;
- if(!f && (settingsFilePath = PrepareHomePath(extension, true,
+ if(!f && (settingsFilePath = PreparePath((type = home), extension, true,
#if defined(__WIN32__)
false
#else
true
#endif
)))
- FileOpenTryWrite(true, &locked);
+ FileOpenTryWrite(type, true, &locked);
}
#if defined(__WIN32__)
if(!f && !allUsers)
{
globalPath = false;
- if(!f && (settingsFilePath = PrepareUserProfilePath(extension, true)))
- FileOpenTryWrite(true, &locked);
- if(!f && (settingsFilePath = PrepareHomeDrivePath(extension, true)))
- FileOpenTryWrite(true, &locked);
+ if(!f && (settingsFilePath = PreparePath((type = winUserProfile), extension, true, false)))
+ FileOpenTryWrite(type, true, &locked);
+ if(!f && (settingsFilePath = PreparePath((type = winHomeDrive), extension, true, false)))
+ FileOpenTryWrite(type, true, &locked);
}
- if(!f && (settingsFilePath = PrepareSystemPath(extension, true)))
+ if(!f && (settingsFilePath = PreparePath((type = winSystemPath), extension, true, false)))
{
globalPath = true;
- FileOpenTryWrite(true, &locked);
+ FileOpenTryWrite(type, true, &locked);
}
#endif
}