Index: ext/libicpf/src/libicpf/cfg.cpp =================================================================== diff -u -N -r21847bff9bc6958b98f3fe8bac319590b790fc0f -r86310fdf8a767b700985ebd1b255004d9eb85fb7 --- ext/libicpf/src/libicpf/cfg.cpp (.../cfg.cpp) (revision 21847bff9bc6958b98f3fe8bac319590b790fc0f) +++ ext/libicpf/src/libicpf/cfg.cpp (.../cfg.cpp) (revision 86310fdf8a767b700985ebd1b255004d9eb85fb7) @@ -27,6 +27,9 @@ #include "exception.h" #include #include +#include "err_codes.h" +#include "cfg_xml.h" +#include "cfg_ini.h" BEGIN_ICPF_NAMESPACE @@ -48,7 +51,6 @@ property_tracker::property_tracker(const property_tracker& rSrc) : m_hProperties((ptr_t)new std::set(*(std::set*)rSrc.m_hProperties)) { - } /** Destructs the property tracker object. @@ -98,7 +100,7 @@ for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) { puiProps[tIndex++]=(*it); - if (tIndex >= stMaxCount) + if(tIndex >= stMaxCount) break; } @@ -115,7 +117,7 @@ { for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) { - if (!(*pfn)((*it), pParam)) + if(!(*pfn)((*it), pParam)) break; } } @@ -129,18 +131,31 @@ * \param[in] pCfgBase - pointer to a base handler of the configuration strings * cound be pointer to xml handler, ini handler or any other */ -config::config(config_base* pCfgBase) : +config::config(config_base_types eCfgType) : m_lock(), m_hProps((ptr_t)new std::vector), - m_pCfgBase(pCfgBase) + m_pszCurrentPath(NULL) { + switch(eCfgType) + { + case eXml: + m_pCfgBase = new xml_cfg; + break; + case eIni: + m_pCfgBase = new ini_cfg; + break; + default: + THROW(_t("Undefined config base type"), 0, 0, 0); + } } /** Destructs the config class. */ config::~config() { delete m_pvProps; + delete [] m_pszCurrentPath; + delete m_pCfgBase; } /** Function opens the specified file using the underlying config base @@ -152,6 +167,20 @@ void config::read(const tchar_t* pszPath) { assert(pszPath); + if(!pszPath) + THROW(_T("Path to the file not provided."), FERR_OPEN, 0, 0); + + // remembering path before operation and not freeing it on fail is done on purpose here + // (to support future write() to this file in case file does not exist yet) + size_t stLen = _tcslen(pszPath); + if(stLen) + { + delete [] m_pszCurrentPath; + m_pszCurrentPath = new tchar_t[stLen + 1]; + _tcscpy(m_pszCurrentPath, pszPath); + m_pszCurrentPath[stLen] = _t('\0'); + } + m_lock.lock(); try { @@ -176,15 +205,29 @@ */ void config::write(const tchar_t* pszPath) { + if(!m_pszCurrentPath && !pszPath) + THROW(_T("No path specified"), FERR_OPEN, 0, 0); m_lock.lock(); try { // store current properties to the underlying object store_registered(); + if(pszPath) + { + size_t stLen = _tcslen(pszPath); + if(stLen) + { + delete [] m_pszCurrentPath; + m_pszCurrentPath = new tchar_t[stLen + 1]; + _tcscpy(m_pszCurrentPath, pszPath); + m_pszCurrentPath[stLen] = _t('\0'); + } + } + // and save - m_pCfgBase->save(pszPath); + m_pCfgBase->save(m_pszCurrentPath); } catch(...) { @@ -277,7 +320,7 @@ // get the value for the property name ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + if( (hFind=m_pCfgBase->find(pszName)) != NULL ) { const tchar_t* psz=NULL; while( (psz=m_pCfgBase->find_next(hFind)) != NULL) @@ -287,7 +330,7 @@ m_pCfgBase->find_close(hFind); } - else if (!(uiFlags & property::flag_array)) + else if(!(uiFlags & property::flag_array)) prop.set_signed_num(llDef); // add to the vector @@ -321,7 +364,7 @@ // get the value for the property name ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + if( (hFind=m_pCfgBase->find(pszName)) != NULL ) { const tchar_t* psz=NULL; while( (psz=m_pCfgBase->find_next(hFind)) != NULL) @@ -331,7 +374,7 @@ m_pCfgBase->find_close(hFind); } - else if (!(uiFlags & property::flag_array)) + else if(!(uiFlags & property::flag_array)) prop.set_unsigned_num(ullDef); // add to the vector @@ -362,7 +405,7 @@ // get the value for the property name ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + if( (hFind=m_pCfgBase->find(pszName)) != NULL ) { const tchar_t* psz=NULL; while( (psz=m_pCfgBase->find_next(hFind)) != NULL) @@ -372,7 +415,7 @@ m_pCfgBase->find_close(hFind); } - else if (!(uiFlags & property::flag_array)) + else if(!(uiFlags & property::flag_array)) prop.set_bool(bDef); // add to the vector @@ -403,7 +446,7 @@ // get the value for the property name ptr_t hFind=NULL; - if ( (hFind=m_pCfgBase->find(pszName)) != NULL ) + if( (hFind=m_pCfgBase->find(pszName)) != NULL ) { const tchar_t* psz=NULL; while( (psz=m_pCfgBase->find_next(hFind)) != NULL) @@ -413,7 +456,7 @@ m_pCfgBase->find_close(hFind); } - else if (!(uiFlags & property::flag_array)) + else if(!(uiFlags & property::flag_array)) prop.set_string(pszDef); // add to the vector @@ -507,6 +550,30 @@ return psz; } +/** Function retrieves the string value. +* +* \param[in] uiProp - property to retrieve the value of +* \param[in] stIndex - index of the value to retrieve (meaningful only for +* array-based properties) +* \return Property value. +*/ +const tchar_t* config::get_string(uint_t uiProp, tchar_t* pszBuffer, size_t stBufferSize, size_t stIndex) +{ + if(!pszBuffer || stBufferSize < 1) + return NULL; + + m_lock.lock(); + const tchar_t* psz=m_pvProps->at(uiProp).get_string(stIndex); + size_t stLen = _tcslen(psz); + if(stLen >= stBufferSize) + stLen = stBufferSize - 1; + + _tcsncpy(pszBuffer, psz, stLen); + pszBuffer[stLen] = _t('\0'); + m_lock.unlock(); + return pszBuffer; +} + /** Function sets the property value from string. * * \param[in] uiProp - property id to set the value for @@ -519,9 +586,10 @@ { m_lock.lock(); m_pvProps->at(uiProp).set_value(pszVal, a, tIndex); - if (pTracker) + if(pTracker) pTracker->add(uiProp); m_lock.unlock(); + property_changed_notify(uiProp); } /** Function sets the signed number property value. @@ -536,9 +604,10 @@ { m_lock.lock(); m_pvProps->at(uiProp).set_signed_num(llVal, a, tIndex); - if (pTracker) + if(pTracker) pTracker->add(uiProp); m_lock.unlock(); + property_changed_notify(uiProp); } /** Function sets the unsigned number property value. @@ -553,9 +622,10 @@ { m_lock.lock(); m_pvProps->at(uiProp).set_unsigned_num(ullVal, a, tIndex); - if (pTracker) + if(pTracker) pTracker->add(uiProp); m_lock.unlock(); + property_changed_notify(uiProp); } /** Function sets the bool property value. @@ -570,9 +640,10 @@ { m_lock.lock(); m_pvProps->at(uiProp).set_bool(bVal, a, tIndex); - if (pTracker) + if(pTracker) pTracker->add(uiProp); m_lock.unlock(); + property_changed_notify(uiProp); } /** Function sets the string property value. @@ -587,11 +658,22 @@ { m_lock.lock(); m_pvProps->at(uiProp).set_string(pszVal, a, tIndex); - if (pTracker) + if(pTracker) pTracker->add(uiProp); m_lock.unlock(); + property_changed_notify(uiProp); } +/** Function sets the callback function to be called on property change. + * \param[in] pfnCallback - pointer to the function + * \param[in] pParam - user defined parameter to pass to the callback + */ +void config::set_callback(PFNPROPERTYCHANGED pfnCallback, ptr_t pParam) +{ + m_pfnNotifyCallback = pfnCallback; + m_pCallbackParam = pParam; +} + /** Function reads the values for the registered properties from the underlying * base config object. */ @@ -604,11 +686,11 @@ for (std::vector::iterator it=m_pvProps->begin();it != m_pvProps->end();it++) { // is this an array property ? - if ((*it).is_array()) + if((*it).is_array()) (*it).clear_array(); // and fill with value(s) - if ( (hFind=m_pCfgBase->find((*it).get_name())) != NULL) + if( (hFind=m_pCfgBase->find((*it).get_name())) != NULL) { while( (psz=m_pCfgBase->find_next(hFind)) != NULL) { @@ -646,4 +728,13 @@ m_lock.unlock(); } +/** Function executes the callback to notify about property value change. + * \param[in] uiPropID - property ID that changed + */ +void config::property_changed_notify(uint_t uiPropID) +{ + if(m_pfnNotifyCallback) + (*m_pfnNotifyCallback)(uiPropID, m_pCallbackParam); +} + END_ICPF_NAMESPACE