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@45: // Licensed under the Apache License, Version 2.0 (the "License"); tomwalters@45: // you may not use this file except in compliance with the License. tomwalters@45: // You may obtain a copy of the License at tomwalters@0: // tomwalters@45: // http://www.apache.org/licenses/LICENSE-2.0 tomwalters@0: // tomwalters@45: // Unless required by applicable law or agreed to in writing, software tomwalters@45: // distributed under the License is distributed on an "AS IS" BASIS, tomwalters@45: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. tomwalters@45: // See the License for the specific language governing permissions and tomwalters@45: // limitations under the License. tomwalters@0: tomwalters@8: /*! tomwalters@8: * \file tomwalters@8: * \brief Main parameters store tomwalters@8: * tomwalters@8: * \author Willem van Engen tomwalters@8: * \date created 2006/09/21 tomwalters@23: * \version \$Id$ tomwalters@8: */ 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@163: #ifdef _MSC_VER tomwalters@163: #define snprintf _snprintf tomwalters@163: #endif tomwalters@163: 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@1: SetString(sName, val); tomwalters@0: } tomwalters@1: return 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@1: SetInt(sName, val); tomwalters@0: } tomwalters@1: return 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@1: SetUInt(sName, val); tomwalters@0: } tomwalters@1: return 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@1: SetFloat(sName, val); tomwalters@0: } tomwalters@1: return 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@1: SetBool(sName, val); tomwalters@0: } tomwalters@1: return 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@8: return atof(GetString(sName)); tomwalters@0: } tomwalters@0: tomwalters@0: bool Parameters::GetBool(const char *sName) { tomwalters@0: const char *sVal = GetString(sName); tomwalters@8: if (strcmp(sVal, "true") == 0 || strcmp(sVal, "on") == 0 || tomwalters@8: strcmp(sVal, "yes") == 0 || strcmp(sVal, "1") == 0 || tomwalters@8: 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@8: return m_pIni->GetValue(m_SDefaultIniSection, sName, NULL) != NULL; tomwalters@0: } tomwalters@0: tomwalters@0: bool Parameters::Parse(const char *sCmd) { tomwalters@8: /*! \todo There is some code duplication here from Parameters::Merge() tomwalters@8: */ 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@8: if ((siErr=m_pIni->LoadFile(sParamFilename)) < 0) { tomwalters@0: // Don't complain if file not found, but do return error tomwalters@8: 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@8: 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@1: tomwalters@1: std::string Parameters::WriteString() { tomwalters@1: AIM_ASSERT(m_pIni); tomwalters@1: SI_Error siErr; tomwalters@1: std::string output_string; tomwalters@1: tomwalters@8: if ((siErr = m_pIni->Save(output_string)) < 0) { tomwalters@1: LOG_ERROR(_T("Couldn't write parameters to string")); tomwalters@1: return false; tomwalters@1: } tomwalters@1: return output_string; tomwalters@1: } tomwalters@1: tomwalters@0: } // namespace aimc