📄 config.cxx
字号:
PXConfigSection * currentSection = new PXConfigSection("Options");
Append(currentSection);
while (*envp != NULL && **envp != '\0') {
PString line(*envp);
PINDEX equals = line.Find('=');
if (equals > 0) {
PXConfigValue * value = new PXConfigValue(line.Left(equals), line.Right(line.GetLength() - equals - 1));
currentSection->GetList().Append(value);
}
envp++;
}
// can't save environment configs
canSave = FALSE;
}
PINDEX PXConfig::GetSectionsIndex(const PString & theSection) const
{
PINDEX len = theSection.GetLength()-1;
if (theSection[len] != '\\')
return GetValuesIndex(theSection);
else
return GetValuesIndex(theSection.Left(len));
}
static BOOL LocateFile(const PString & baseName,
PFilePath & readFilename,
PFilePath & filename)
{
// check the user's home directory first
filename = readFilename = PProcess::Current().GetConfigurationFile();
if (PFile::Exists(filename))
return TRUE;
// otherwise check the system directory for a file to read,
// and then create
readFilename = SYS_CONFIG_DIR + baseName + EXTENSION;
return PFile::Exists(readFilename);
}
///////////////////////////////////////////////////////////////////////////////
PString PProcess::GetConfigurationFile()
{
if (configurationPaths.IsEmpty()) {
configurationPaths.AppendString(PXGetHomeDir() + APP_CONFIG_DIR);
configurationPaths.AppendString(SYS_CONFIG_DIR);
}
// See if explicit filename
if (configurationPaths.GetSize() == 1 && !PDirectory::Exists(configurationPaths[0]))
return configurationPaths[0];
PString iniFilename = executableFile.GetTitle() + ".ini";
for (PINDEX i = 0; i < configurationPaths.GetSize(); i++) {
PFilePath cfgFile = PDirectory(configurationPaths[i]) + iniFilename;
if (PFile::Exists(cfgFile))
return cfgFile;
}
return PDirectory(configurationPaths[0]) + iniFilename;
}
////////////////////////////////////////////////////////////
//
// PXConfigDictionary
//
PXConfigDictionary::PXConfigDictionary(int)
{
environmentInstance = NULL;
writeThread = NULL;
configDict = this;
}
PXConfigDictionary::~PXConfigDictionary()
{
if (writeThread != NULL) {
stopConfigWriteThread.Signal();
writeThread->WaitForTermination();
delete writeThread;
}
delete environmentInstance;
}
PXConfig * PXConfigDictionary::GetEnvironmentInstance()
{
mutex.Wait();
if (environmentInstance == NULL) {
environmentInstance = new PXConfig(0);
environmentInstance->ReadFromEnvironment(PProcess::Current().PXGetEnvp());
}
mutex.Signal();
return environmentInstance;
}
PXConfig * PXConfigDictionary::GetFileConfigInstance(const PFilePath & key, const PFilePath & readKey)
{
mutex.Wait();
// start write thread, if not already started
if (writeThread == NULL)
writeThread = new PXConfigWriteThread(stopConfigWriteThread);
PXConfig * config = GetAt(key);
if (config != NULL)
config->AddInstance();
else {
config = new PXConfig(0);
config->ReadFromFile(readKey);
config->AddInstance();
SetAt(key, config);
}
mutex.Signal();
return config;
}
void PXConfigDictionary::RemoveInstance(PXConfig * instance)
{
mutex.Wait();
if (instance != environmentInstance) {
PINDEX index = GetObjectsIndex(instance);
PAssert(index != P_MAX_INDEX, "Cannot find PXConfig instance to remove");
// decrement the instance count, but don't remove it yet
PFilePath key = GetKeyAt(index);
instance->RemoveInstance(key);
}
mutex.Signal();
}
void PXConfigDictionary::WriteChangedInstances()
{
mutex.Wait();
PINDEX i;
for (i = 0; i < GetSize(); i++) {
PFilePath key = GetKeyAt(i);
GetAt(key)->Flush(key);
}
mutex.Signal();
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Create a new configuration object
//
////////////////////////////////////////////////////////////
void PConfig::Construct(Source src,
const PString & appname,
const PString & /*manuf*/)
{
// handle cnvironment configs differently
if (src == PConfig::Environment) {
config = configDict->GetEnvironmentInstance();
return;
}
PString name;
PFilePath filename, readFilename;
// look up file name to read, and write
if (src == PConfig::System)
LocateFile(SYS_CONFIG_NAME, readFilename, filename);
else
filename = readFilename = PProcess::Current().GetConfigurationFile();
// get, or create, the configuration
config = configDict->GetFileConfigInstance(filename, readFilename);
}
PConfig::PConfig(int, const PString & name)
: defaultSection("Options")
{
PFilePath readFilename, filename;
LocateFile(name, readFilename, filename);
config = configDict->GetFileConfigInstance(filename, readFilename);
}
void PConfig::Construct(const PFilePath & theFilename)
{
config = configDict->GetFileConfigInstance(theFilename, theFilename);
}
PConfig::~PConfig()
{
configDict->RemoveInstance(config);
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Return a list of all the section names in the file.
//
////////////////////////////////////////////////////////////
PStringList PConfig::GetSections() const
{
PAssert(config != NULL, "config instance not set");
config->Wait();
PStringList list;
for (PINDEX i = 0; i < (*config).GetSize(); i++)
list.AppendString((*config)[i]);
config->Signal();
return list;
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Return a list of all the keys in the section. If the section name is
// not specified then use the default section.
//
////////////////////////////////////////////////////////////
PStringList PConfig::GetKeys(const PString & theSection) const
{
PAssert(config != NULL, "config instance not set");
config->Wait();
PINDEX index;
PStringList list;
if ((index = config->GetSectionsIndex(theSection)) != P_MAX_INDEX) {
PXConfigSectionList & section = (*config)[index].GetList();
for (PINDEX i = 0; i < section.GetSize(); i++)
list.AppendString(section[i]);
}
config->Signal();
return list;
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Delete all variables in the specified section. If the section name is
// not specified then use the default section.
//
////////////////////////////////////////////////////////////
void PConfig::DeleteSection(const PString & theSection)
{
PAssert(config != NULL, "config instance not set");
config->Wait();
PStringList list;
PINDEX index;
if ((index = config->GetSectionsIndex(theSection)) != P_MAX_INDEX) {
config->RemoveAt(index);
config->SetDirty();
}
config->Signal();
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Delete the particular variable in the specified section.
//
////////////////////////////////////////////////////////////
void PConfig::DeleteKey(const PString & theSection, const PString & theKey)
{
PAssert(config != NULL, "config instance not set");
config->Wait();
PINDEX index;
if ((index = config->GetSectionsIndex(theSection)) != P_MAX_INDEX) {
PXConfigSectionList & section = (*config)[index].GetList();
PINDEX index_2;
if ((index_2 = section.GetValuesIndex(theKey)) != P_MAX_INDEX) {
section.RemoveAt(index_2);
config->SetDirty();
}
}
config->Signal();
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Test if there is a value for the key.
//
////////////////////////////////////////////////////////////
BOOL PConfig::HasKey(const PString & theSection, const PString & theKey) const
{
PAssert(config != NULL, "config instance not set");
config->Wait();
BOOL present = FALSE;
PINDEX index;
if ((index = config->GetSectionsIndex(theSection)) != P_MAX_INDEX) {
PXConfigSectionList & section = (*config)[index].GetList();
present = section.GetValuesIndex(theKey) != P_MAX_INDEX;
}
config->Signal();
return present;
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Get a string variable determined by the key in the section.
//
////////////////////////////////////////////////////////////
PString PConfig::GetString(const PString & theSection,
const PString & theKey, const PString & dflt) const
{
PAssert(config != NULL, "config instance not set");
config->Wait();
PString value = dflt;
PINDEX index;
if ((index = config->GetSectionsIndex(theSection)) != P_MAX_INDEX) {
PXConfigSectionList & section = (*config)[index].GetList();
if ((index = section.GetValuesIndex(theKey)) != P_MAX_INDEX)
value = section[index].GetValue();
}
config->Signal();
return value;
}
////////////////////////////////////////////////////////////
//
// PConfig::
//
// Set a string variable determined by the key in the section.
//
////////////////////////////////////////////////////////////
void PConfig::SetString(const PString & theSection,
const PString & theKey,
const PString & theValue)
{
PAssert(config != NULL, "config instance not set");
config->Wait();
PINDEX index;
PXConfigSection * section;
PXConfigValue * value;
if ((index = config->GetSectionsIndex(theSection)) != P_MAX_INDEX)
section = &(*config)[index];
else {
section = new PXConfigSection(theSection);
config->Append(section);
config->SetDirty();
}
if ((index = section->GetList().GetValuesIndex(theKey)) != P_MAX_INDEX)
value = &(section->GetList()[index]);
else {
value = new PXConfigValue(theKey);
section->GetList().Append(value);
config->SetDirty();
}
if (theValue != value->GetValue()) {
value->SetValue(theValue);
config->SetDirty();
}
config->Signal();
}
///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -