| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- #include "CmPreferences.h"
- #include "CmException.h"
- #include "CmDebug.h"
- #include "CmFileSystem.h"
- #include "CmDataStream.h"
- namespace CamelotEditor
- {
- void Preferences::setValue(const String& key, const String& value, UINT32 arrayIdx)
- {
- if(!isKeyValid(key))
- CM_EXCEPT(InvalidParametersException, "Invalid key name. Please don't use any special character in the key name: " + key);
- auto findIter = mKeys.find(key);
- if(findIter == mKeys.end() || findIter->second.mapType != VMT_String)
- {
- KeyMapIndex kmi;
- kmi.mapType = VMT_String;
- kmi.entryIdx = (UINT32)mStringEntries.size();
- mStringEntries.push_back(PrefStringEntries());
- mKeys[key] = kmi;
- findIter = mKeys.find(key);
- }
- PrefStringEntries& strEntry = mStringEntries[findIter->second.entryIdx];
- if(strEntry.entries.size() <= arrayIdx)
- strEntry.entries.resize(arrayIdx + 1);
- strEntry.entries[arrayIdx] = value;
- }
- void Preferences::addValue(const String& key, const String& value)
- {
- UINT32 arrayIdx = getNumValues(key);
- setValue(key, value, arrayIdx);
- }
- const String& Preferences::getValue(const String& key, const String& defaultValue, UINT32 arrayIdx)
- {
- auto findIter = mKeys.find(key);
- if(findIter == mKeys.end() || findIter->second.mapType != VMT_String)
- return defaultValue;
- PrefStringEntries& entry = mStringEntries[findIter->second.entryIdx];
- if(arrayIdx < entry.entries.size())
- return entry.entries[arrayIdx];
- return defaultValue;
- }
- void Preferences::setValue(const String& key, const int value, UINT32 arrayIdx)
- {
- if(!isKeyValid(key))
- CM_EXCEPT(InvalidParametersException, "Invalid key name. Please don't use any special character in the key name: " + key);
- auto findIter = mKeys.find(key);
- if(findIter == mKeys.end() || findIter->second.mapType != VMT_Int)
- {
- KeyMapIndex kmi;
- kmi.mapType = VMT_Int;
- kmi.entryIdx = (UINT32)mIntEntries.size();
- mIntEntries.push_back(PrefIntEntries());
- mKeys[key] = kmi;
- findIter = mKeys.find(key);
- }
- PrefIntEntries& intEntry = mIntEntries[findIter->second.entryIdx];
- if(intEntry.entries.size() <= arrayIdx)
- intEntry.entries.resize(arrayIdx + 1);
- intEntry.entries[arrayIdx] = value;
- }
- void Preferences::addValue(const String& key, const int value)
- {
- UINT32 arrayIdx = getNumValues(key);
- setValue(key, value, arrayIdx);
- }
- int Preferences::getValue(const String& key, int defaultValue, UINT32 arrayIdx)
- {
- auto findIter = mKeys.find(key);
- if(findIter == mKeys.end() || findIter->second.mapType != VMT_Int)
- return defaultValue;
- PrefIntEntries& entry = mIntEntries[findIter->second.entryIdx];
- if(arrayIdx < entry.entries.size())
- return entry.entries[arrayIdx];
- return defaultValue;
- }
- void Preferences::setValue(const String& key, float value, UINT32 arrayIdx)
- {
- if(!isKeyValid(key))
- CM_EXCEPT(InvalidParametersException, "Invalid key name. Please don't use any special character in the key name: " + key);
- auto findIter = mKeys.find(key);
- if(findIter == mKeys.end() || findIter->second.mapType != VMT_Float)
- {
- KeyMapIndex kmi;
- kmi.mapType = VMT_Float;
- kmi.entryIdx = (UINT32)mFloatEntries.size();
- mFloatEntries.push_back(PrefFloatEntries());
- mKeys[key] = kmi;
- findIter = mKeys.find(key);
- }
- PrefFloatEntries& floatEntry = mFloatEntries[findIter->second.entryIdx];
- if(floatEntry.entries.size() <= arrayIdx)
- floatEntry.entries.resize(arrayIdx + 1);
- floatEntry.entries[arrayIdx] = value;
- }
- void Preferences::addValue(const String& key, float value)
- {
- UINT32 arrayIdx = getNumValues(key);
- setValue(key, value, arrayIdx);
- }
- float Preferences::getValue(const String& key, float defaultValue, UINT32 arrayIdx)
- {
- auto findIter = mKeys.find(key);
- if(findIter == mKeys.end() || findIter->second.mapType != VMT_Float)
- return defaultValue;
- PrefFloatEntries& entry = mFloatEntries[findIter->second.entryIdx];
- if(arrayIdx < entry.entries.size())
- return entry.entries[arrayIdx];
-
- return defaultValue;
- }
- UINT32 Preferences::getNumValues(const String& key)
- {
- auto findIter = mKeys.find(key);
- if(findIter == mKeys.end())
- return 0;
- switch(findIter->second.mapType)
- {
- case VMT_String:
- return (UINT32)mStringEntries[findIter->second.entryIdx].entries.size();
- case VMT_Float:
- return (UINT32)mFloatEntries[findIter->second.entryIdx].entries.size();
- case VMT_Int:
- return (UINT32)mIntEntries[findIter->second.entryIdx].entries.size();
- }
- return 0;
- }
- bool Preferences::isKeyValid(const String& key) const
- {
- String::size_type foundComma = key.find(",");
- return foundComma == String::npos;
- }
- void Preferences::save(const String& path, bool overwrite) const
- {
- if(FileSystem::fileExists(path))
- {
- if(!overwrite)
- {
- CM_EXCEPT(FileNotFoundException, "File already exists at this location.");
- }
- else
- FileSystem::remove(path);
- }
- map<String, vector<EntryToSave>::type>::type groups;
- for(auto iter = mKeys.begin(); iter != mKeys.end(); ++iter)
- {
- vector<String>::type splitStr = StringUtil::split(iter->first, ".", 1);
- String groupName;
- String paramName;
- if(splitStr.size() > 1)
- {
- groupName = splitStr[0];
- paramName = splitStr[1];
- }
- else
- {
- groupName = "Global";
- paramName = splitStr[0];
- }
- switch(iter->second.mapType)
- {
- case VMT_String:
- {
- const PrefStringEntries& entry = mStringEntries[iter->second.entryIdx];
- if(entry.entries.size() > 1)
- {
- for(size_t i = 0; i < entry.entries.size(); i++)
- {
- EntryToSave newEntry;
- newEntry.name = paramName + "," + toString(i);
- newEntry.value = "\"" + entry.entries[i] + "\"";
- groups[groupName].push_back(newEntry);
- }
- }
- else
- {
- EntryToSave newEntry;
- newEntry.name = paramName;
- newEntry.value = "\"" + entry.entries[0] + "\"";
- groups[groupName].push_back(newEntry);
- }
- }
- break;
- case VMT_Float:
- {
- const PrefFloatEntries& entry = mFloatEntries[iter->second.entryIdx];
- if(entry.entries.size() > 1)
- {
- for(size_t i = 0; i < entry.entries.size(); i++)
- {
- EntryToSave newEntry;
- newEntry.name = paramName + "," + toString(i);
- newEntry.value = toString(entry.entries[i], 12) + "f";
- groups[groupName].push_back(newEntry);
- }
- }
- else
- {
- EntryToSave newEntry;
- newEntry.name = paramName;
- newEntry.value = toString(entry.entries[0], 12) + "f";
- groups[groupName].push_back(newEntry);
- }
- }
- break;
- case VMT_Int:
- {
- const PrefIntEntries& entry = mIntEntries[iter->second.entryIdx];
- if(entry.entries.size() > 1)
- {
- for(size_t i = 0; i < entry.entries.size(); i++)
- {
- EntryToSave newEntry;
- newEntry.name = paramName + "," + toString(i);
- newEntry.value = toString(entry.entries[i]);
- groups[groupName].push_back(newEntry);
- }
- }
- else
- {
- EntryToSave newEntry;
- newEntry.name = paramName;
- newEntry.value = toString(entry.entries[0]);
- groups[groupName].push_back(newEntry);
- }
- }
- break;
- }
- }
- stringstream strStream;
- for(auto iter = groups.begin(); iter != groups.end(); ++iter)
- {
- strStream<<"["<<iter->first<<"]\r\n";
- for(auto iter2 = iter->second.begin(); iter2 != iter->second.end(); ++iter2)
- {
- strStream<<iter2->name<<" = "<<iter2->value<<"\r\n";
- }
- strStream<<"\r\n";
- }
- String outputString = strStream.str();
- DataStreamPtr stream = FileSystem::create(path);
- stream->write(outputString.data(), outputString.size());
- stream->close();
- }
- void Preferences::load(const String& path)
- {
- if(!FileSystem::fileExists(path))
- CM_EXCEPT(FileNotFoundException, "Specified file: " + path + " does not exist.");
- DataStreamPtr stream = FileSystem::open(path);
- char buffer[4096];
- String currentGroupName = "Global";
- bool groupIsDefault = true;
- int foundGroups = 0;
- while(!stream->eof())
- {
- stream->readLine(buffer, sizeof(buffer));
- String line(buffer);
- String::size_type bracketsStart = line.find("[");
- String::size_type bracketsEnd = line.find("]");
- if (bracketsStart != String::npos && bracketsEnd != String::npos)
- {
- currentGroupName = line.substr(bracketsStart + 1, bracketsEnd - (bracketsStart + 1));
- groupIsDefault = foundGroups == 0;
- foundGroups++;
- continue;
- }
- vector<String>::type paramSplit = StringUtil::split(line, "=");
- if(paramSplit.size() < 2)
- {
- LOGWRN("Cannot parse line in file " + path + ". Invalid number of elements: " + line);
- continue;
- }
- String paramName = paramSplit[0];
- StringUtil::trim(paramName);
- vector<String>::type arrayElemSplit = StringUtil::split(paramName, ",");
- UINT32 arrayIdx = 0;
- if(arrayElemSplit.size() > 1)
- {
- String arrayElemStr = arrayElemSplit[1];
- StringUtil::trim(arrayElemStr);
- arrayIdx = parseInt(arrayElemStr);
- paramName = arrayElemSplit[0];
- StringUtil::trim(paramName);
- }
- if(!groupIsDefault)
- paramName = currentGroupName + "." + paramName;
- String paramValue = paramSplit[1];
- StringUtil::trim(paramValue);
- // Float
- if(StringUtil::endsWith(paramValue, "f"))
- {
- paramValue.erase(paramValue.begin() + paramValue.size() - 1);
- float fltValue = parseFloat(paramValue);
- setValue(paramName, fltValue, arrayIdx);
- }
- else if(StringUtil::endsWith(paramValue, "\"")) // String
- {
- paramValue.erase(paramValue.begin());
- paramValue.erase(paramValue.begin() + paramValue.size() - 1);
- setValue(paramName, paramValue, arrayIdx);
- }
- else // Assuming int
- {
- int intValue = parseInt(paramValue);
- setValue(paramName, intValue, arrayIdx);
- }
- }
- stream->close();
- }
- }
|