tomwalters@268: // Copyright 2006-2010, Willem van Engen
tomwalters@268: //
tomwalters@268: // AIM-C: A C++ implementation of the Auditory Image Model
tomwalters@268: // http://www.acousticscale.org/AIMC
tomwalters@268: //
tomwalters@268: // This program is free software: you can redistribute it and/or modify
tomwalters@268: // it under the terms of the GNU General Public License as published by
tomwalters@268: // the Free Software Foundation, either version 3 of the License, or
tomwalters@268: // (at your option) any later version.
tomwalters@268: //
tomwalters@268: // This program is distributed in the hope that it will be useful,
tomwalters@268: // but WITHOUT ANY WARRANTY; without even the implied warranty of
tomwalters@268: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
tomwalters@268: // GNU General Public License for more details.
tomwalters@268: //
tomwalters@268: // You should have received a copy of the GNU General Public License
tomwalters@268: // along with this program. If not, see .
tomwalters@268:
tomwalters@280: /*!
tomwalters@280: * \file
tomwalters@280: * \brief Main parameters store
tomwalters@280: *
tomwalters@280: * \author Willem van Engen
tomwalters@280: * \date created 2006/09/21
tomwalters@280: * \version \$Id: Parameters.cc 4 2010-02-03 18:44:58Z tcw $
tomwalters@280: */
tomwalters@268:
tomwalters@268: #include
tomwalters@268: #include
tomwalters@268: #include
tomwalters@268:
tomwalters@268: #include "Support/Common.h"
tomwalters@268: #include "Support/Parameters.h"
tomwalters@268:
tomwalters@268: namespace aimc {
tomwalters@268: const char *Parameters::m_SDefaultIniSection = "";
tomwalters@268:
tomwalters@268: Parameters::Parameters() {
tomwalters@268: m_iNestCount = 0;
tomwalters@268: m_pIni = new CSimpleIniCase(false, false, true);
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: }
tomwalters@268:
tomwalters@268: Parameters::~Parameters() {
tomwalters@268: DELETE_IF_NONNULL(m_pIni);
tomwalters@268: }
tomwalters@268:
tomwalters@268: const char * Parameters::DefaultString(const char* sName, const char* val) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: if (!IsSet(sName)) {
tomwalters@273: SetString(sName, val);
tomwalters@268: }
tomwalters@273: return GetString(sName);
tomwalters@268: }
tomwalters@268:
tomwalters@268: int Parameters::DefaultInt(const char* sName, int val) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: if (!IsSet(sName)) {
tomwalters@273: SetInt(sName, val);
tomwalters@268: }
tomwalters@273: return GetInt(sName);
tomwalters@268: }
tomwalters@268:
tomwalters@268: unsigned int Parameters::DefaultUInt(const char* sName, unsigned int val) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: if (!IsSet(sName)) {
tomwalters@273: SetUInt(sName, val);
tomwalters@268: }
tomwalters@273: return GetUInt(sName);
tomwalters@268: }
tomwalters@268:
tomwalters@268: float Parameters::DefaultFloat(const char* sName, float val) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: if (!IsSet(sName)) {
tomwalters@273: SetFloat(sName, val);
tomwalters@268: }
tomwalters@273: return GetFloat(sName);
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::DefaultBool(const char* sName, bool val) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: if (!IsSet(sName)) {
tomwalters@273: SetBool(sName, val);
tomwalters@268: }
tomwalters@273: return GetBool(sName);
tomwalters@268: }
tomwalters@268:
tomwalters@268: void Parameters::SetString(const char *sName, const char *val) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: m_pIni->SetValue(m_SDefaultIniSection, sName, val);
tomwalters@268: }
tomwalters@268:
tomwalters@268: void Parameters::SetInt(const char *sName, int val) {
tomwalters@268: char sVal[20];
tomwalters@268: snprintf(sVal, sizeof(sVal)/sizeof(sVal[0]), "%d", val);
tomwalters@268: SetString(sName, sVal);
tomwalters@268: }
tomwalters@268:
tomwalters@268: void Parameters::SetUInt(const char *sName, unsigned int val) {
tomwalters@268: char sVal[20];
tomwalters@268: snprintf(sVal, sizeof(sVal)/sizeof(sVal[0]), "%ud", val);
tomwalters@268: SetString(sName, sVal);
tomwalters@268: }
tomwalters@268:
tomwalters@268: void Parameters::SetBool(const char *sName, bool val) {
tomwalters@268: SetString(sName, val ? "true" : "false");
tomwalters@268: }
tomwalters@268:
tomwalters@268: void Parameters::SetFloat(const char *sName, float val) {
tomwalters@268: char sVal[20];
tomwalters@268: snprintf(sVal, sizeof(sVal)/sizeof(sVal[0]), "%f", val);
tomwalters@268: SetString(sName, sVal);
tomwalters@268: }
tomwalters@268:
tomwalters@268: const char *Parameters::GetString(const char *sName) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: const char *sVal = m_pIni->GetValue(m_SDefaultIniSection, sName, NULL);
tomwalters@268: if (!sVal) {
tomwalters@268: LOG_ERROR(_T("Parameter not found '%s'"), sName);
tomwalters@268: return "";
tomwalters@268: }
tomwalters@268: return sVal;
tomwalters@268: }
tomwalters@268:
tomwalters@268: int Parameters::GetInt(const char *sName) {
tomwalters@268: return atoi(GetString(sName));
tomwalters@268: }
tomwalters@268:
tomwalters@268: unsigned int Parameters::GetUInt(const char *sName) {
tomwalters@268: return atoi(GetString(sName));
tomwalters@268: }
tomwalters@268:
tomwalters@268: float Parameters::GetFloat(const char *sName) {
tomwalters@280: return atof(GetString(sName));
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::GetBool(const char *sName) {
tomwalters@268: const char *sVal = GetString(sName);
tomwalters@280: if (strcmp(sVal, "true") == 0 || strcmp(sVal, "on") == 0 ||
tomwalters@280: strcmp(sVal, "yes") == 0 || strcmp(sVal, "1") == 0 ||
tomwalters@280: strcmp(sVal, "y") == 0 || strcmp(sVal, "t") == 0)
tomwalters@268: return true;
tomwalters@268: else
tomwalters@268: return false;
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::IsSet(const char *sName) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@280: return m_pIni->GetValue(m_SDefaultIniSection, sName, NULL) != NULL;
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::Parse(const char *sCmd) {
tomwalters@280: /*! \todo There is some code duplication here from Parameters::Merge()
tomwalters@280: */
tomwalters@268:
tomwalters@268: CSimpleIniCase *pIni2 = new CSimpleIniCase(false, false, true);
tomwalters@268: AIM_ASSERT(pIni2);
tomwalters@268: if (pIni2->Load(sCmd, strlen(sCmd)) < 0) {
tomwalters@268: LOG_ERROR(_T("Could not parse option '%s'"), sCmd);
tomwalters@268: delete pIni2;
tomwalters@268: return false;
tomwalters@268: }
tomwalters@268:
tomwalters@268: // if there are keys and values...
tomwalters@268: const CSimpleIniCase::TKeyVal *pSectionData =
tomwalters@268: pIni2->GetSection(m_SDefaultIniSection);
tomwalters@268: if (pSectionData) {
tomwalters@268: // iterate over all keys and set them in the current parameter file
tomwalters@268: CSimpleIniCase::TKeyVal::const_iterator iKeyVal = pSectionData->begin();
tomwalters@268: for ( ;iKeyVal != pSectionData->end(); ++iKeyVal) {
tomwalters@268: m_pIni->SetValue(m_SDefaultIniSection,
tomwalters@268: iKeyVal->first.pItem,
tomwalters@268: iKeyVal->second);
tomwalters@268: }
tomwalters@268: }
tomwalters@268: delete pIni2;
tomwalters@268: return true;
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::Delete(const char *sName) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: return(m_pIni->Delete(m_SDefaultIniSection, sName));
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::LoadFile(const char *sParamFilename) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: SI_Error siErr;
tomwalters@268: bool bRet = true;
tomwalters@268:
tomwalters@268: // Avoid inclusion loops
tomwalters@268: if (m_iNestCount >= m_iNestCountMaximum) {
tomwalters@268: LOG_ERROR(_T("Possible inclusion loop in file '%s' (%d times)"),
tomwalters@268: sParamFilename, m_iNestCount);
tomwalters@268: return false;
tomwalters@268: }
tomwalters@268: m_iNestCount++;
tomwalters@268:
tomwalters@280: if ((siErr=m_pIni->LoadFile(sParamFilename)) < 0) {
tomwalters@268: // Don't complain if file not found, but do return error
tomwalters@280: if (siErr != SI_FILE)
tomwalters@268: LOG_ERROR(_T("Couldn't parse parameters from '%s'"), sParamFilename);
tomwalters@268: m_iNestCount--;
tomwalters@268: return false;
tomwalters@268: }
tomwalters@268:
tomwalters@268: m_iNestCount--;
tomwalters@268: return bRet;
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::MergeFile(const char *sParamFilename) {
tomwalters@268: Parameters *pParam2 = new Parameters();
tomwalters@268: AIM_ASSERT(pParam2);
tomwalters@268: if (!pParam2->LoadFile(sParamFilename)) {
tomwalters@268: LOG_ERROR(_T("Could not load parameter file '%s' for merging"),
tomwalters@268: sParamFilename);
tomwalters@268: delete pParam2;
tomwalters@268: return false;
tomwalters@268: }
tomwalters@268:
tomwalters@268: // if there are keys and values...
tomwalters@268: const CSimpleIniCase::TKeyVal *pSectionData =
tomwalters@268: pParam2->m_pIni->GetSection(m_SDefaultIniSection);
tomwalters@268: if (pSectionData) {
tomwalters@268: // iterate over all keys and set them in the current parameter file
tomwalters@268: CSimpleIniCase::TKeyVal::const_iterator iKeyVal = pSectionData->begin();
tomwalters@268: for ( ;iKeyVal != pSectionData->end(); ++iKeyVal) {
tomwalters@268: m_pIni->SetValue(m_SDefaultIniSection,
tomwalters@268: iKeyVal->first.pItem,
tomwalters@268: iKeyVal->second);
tomwalters@268: }
tomwalters@268: }
tomwalters@268:
tomwalters@268: delete pParam2;
tomwalters@268: return true;
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::Merge(const char *sParamFilename) {
tomwalters@268: return MergeFile(sParamFilename);
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::Load(const char *sParamFilename) {
tomwalters@268: bool bRet = true;
tomwalters@268: // Load parameter file
tomwalters@268: bRet &= Merge(sParamFilename);
tomwalters@268: return bRet;
tomwalters@268: }
tomwalters@268:
tomwalters@268: bool Parameters::Save(const char *sParamFilename) {
tomwalters@268: AIM_ASSERT(m_pIni);
tomwalters@268: SI_Error siErr;
tomwalters@268: FILE *pSaveFile;
tomwalters@268:
tomwalters@268: pSaveFile = fopen(sParamFilename, "wb");
tomwalters@268: if (pSaveFile == NULL) {
tomwalters@268: LOG_ERROR(_T("Couldn't create parameters file '%s' to save to"),
tomwalters@268: sParamFilename);
tomwalters@268: return false;
tomwalters@268: }
tomwalters@268:
tomwalters@280: if ((siErr = m_pIni->SaveFile(pSaveFile)) < 0) {
tomwalters@268: LOG_ERROR(_T("Couldn't save parameters in file '%s'"), sParamFilename);
tomwalters@268: return false;
tomwalters@268: }
tomwalters@268:
tomwalters@268: fclose(pSaveFile);
tomwalters@268:
tomwalters@268: return true;
tomwalters@268: }
tomwalters@273:
tomwalters@273: std::string Parameters::WriteString() {
tomwalters@273: AIM_ASSERT(m_pIni);
tomwalters@273: SI_Error siErr;
tomwalters@273: std::string output_string;
tomwalters@273:
tomwalters@280: if ((siErr = m_pIni->Save(output_string)) < 0) {
tomwalters@273: LOG_ERROR(_T("Couldn't write parameters to string"));
tomwalters@273: return false;
tomwalters@273: }
tomwalters@273: return output_string;
tomwalters@273: }
tomwalters@273:
tomwalters@268: } // namespace aimc