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@318: // Licensed under the Apache License, Version 2.0 (the "License"); tomwalters@318: // you may not use this file except in compliance with the License. tomwalters@318: // You may obtain a copy of the License at tomwalters@268: // tomwalters@318: // http://www.apache.org/licenses/LICENSE-2.0 tomwalters@268: // tomwalters@318: // Unless required by applicable law or agreed to in writing, software tomwalters@318: // distributed under the License is distributed on an "AS IS" BASIS, tomwalters@318: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. tomwalters@318: // See the License for the specific language governing permissions and tomwalters@318: // limitations under the License. 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@296: * \version \$Id$ 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@330: #ifdef _MSC_VER tomwalters@330: #define snprintf _snprintf tomwalters@330: #endif tomwalters@330: 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