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