Index: ext/libicpf/libicpf.vc71.vcproj =================================================================== diff -u -N -r3e7ccb6efc5089399a7801082d923aeb41f53d2e -r771dac1fbb7608aa92942c6cab7c5c8b0cccb791 --- ext/libicpf/libicpf.vc71.vcproj (.../libicpf.vc71.vcproj) (revision 3e7ccb6efc5089399a7801082d923aeb41f53d2e) +++ ext/libicpf/libicpf.vc71.vcproj (.../libicpf.vc71.vcproj) (revision 771dac1fbb7608aa92942c6cab7c5c8b0cccb791) @@ -32,6 +32,7 @@ Name="VCCustomBuildTool"/> + + + + -#include "str.h" -#include -#include "str_help.h" -#ifdef USE_ENCRYPTION - #include "crypt.h" -#endif +#include "exception.h" #include +#include -/// Specifies maximum line length of the .conf file -#define MAX_LINE 1024 - -#ifdef _WIN32 - /// A small helper for win32 systems - #define snprintf _snprintf -#endif - BEGIN_ICPF_NAMESPACE -/// A global instance of a config class -config *__g_cfg=NULL; - -// to make access faster -#define m_pvProperties ((std::vector*)m_pProperties) - ////////////////////////////////////////////////////////////////////////////////// -// prop_group class +// property_tracker class +#define m_psProperties ((std::set*)m_hProperties) -/** Standard constructor +/** Constructs the property_tracker object. */ -prop_group::prop_group(ulong_t ulID) : - m_pProperties(NULL), - m_ulGroupID(ulID) +property_tracker::property_tracker() : + m_hProperties((ptr_t)new std::set) { - m_pProperties=(void*)new std::vector; } -/** Standard destructor +/** Constructs the property_tracker by copying data from source object. + * + * \param[in] rSrc - source property tracker */ -prop_group::~prop_group() +property_tracker::property_tracker(const property_tracker& rSrc) : + m_hProperties((ptr_t)new std::set(*(std::set*)rSrc.m_hProperties)) { - try - { - delete m_pvProperties; - } - catch(...) - { - } + } +/** Destructs the property tracker object. + */ +property_tracker::~property_tracker() +{ + delete m_psProperties; +} + /** Function adds a new property id to the group. - * \param[in] ulProp - id of a property to add + * + * \param[in] uiProp - id of a property to add */ -void prop_group::add(ulong_t ulProp) +void property_tracker::add(uint_t uiProp) { - m_pvProperties->push_back(ulProp); + m_psProperties->insert(uiProp); } /** Function searches for a specific property id inside the list. + * + * \param[in] uiProp - property id to check for * \return True if the property has been found, false if not. */ -bool prop_group::is_set(ulong_t ulProp) +bool property_tracker::is_set(uint_t uiProp) { - for (std::vector::iterator it=m_pvProperties->begin();it != m_pvProperties->end();it++) - { - if ((*it) == ulProp) - return true; - } - - return false; + return m_psProperties->find(uiProp) != m_psProperties->end(); } /** Function returns a count of properties contained in the list. - * \return A count of properties. + * + * \return A count of id's. */ -ulong_t prop_group::count() const +size_t property_tracker::count() const { - return (ulong_t)m_pvProperties->size(); + return m_psProperties->size(); } -/** Function returns a property ID at a specified index. - * \param[in] ulIndex - an index - * \return A property id. +/** Function retrieves the id's contained in this tracker by copying + * them to the given array. + * + * \param[out] puiProps - pointer to the array of uint's to receive id's + * \param[in] stMaxCount - size of the array (max count of elements to retrieve) */ -ulong_t prop_group::get_at(ulong_t ulIndex) +size_t property_tracker::get_ids(uint_t* puiProps, size_t stMaxCount) { - return m_pvProperties->at(ulIndex); + size_t tIndex=0; + for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) + { + puiProps[tIndex++]=(*it); + if (tIndex >= stMaxCount) + break; + } + + return tIndex; } -/** Function returns the group id. - * \return A group ID. +/** Function enumerates id's contained in this property_tracker using + * a callback function. + * + * \param[in] pfn - function to be called + * \param[in] pParam - parameter to pass to the callback */ -ulong_t prop_group::get_groupid() const +void property_tracker::enum_ids(bool(*pfn)(uint_t uiProp, ptr_t pParam), ptr_t pParam) { - return m_ulGroupID; + for (std::set::iterator it=m_psProperties->begin();it != m_psProperties->end();it++) + { + if (!(*pfn)((*it), pParam)) + break; + } } ///////////////////////////////////////////////////////////////////////////////////// // config class -#define m_pvProps ((std::vector<_PROP>*)m_pProps) -#define m_pvUnreg ((std::vector<_PROP>*)m_pUnreg) +#define m_pvProps ((std::vector*)m_hProps) -/** Retrieves a pointer to a global instance of a config class - * \return Pointer to the config class - */ -config* config::get_config() -{ - return __g_cfg; -} - /** Constructs a config object. * \param[in] bGlobal - specifies if this class should be globally accessible by the get_config() friend * function. */ -config::config(bool bGlobal) : +config::config(config_base* pCfgBase) : m_lock(), - m_pProps(NULL), - m_pUnreg(NULL), - m_bModified(false), -#ifdef USE_ENCRYPTION - m_strPassword(), -#endif - m_clbPropertyChanged() + m_hProps((ptr_t)new std::vector), + m_pCfgBase(pCfgBase) { - m_pProps=(void*)new std::vector<_PROP>; - m_pUnreg=(void*)new std::vector<_PROP>; - - if (bGlobal) - __g_cfg=this; } /** Destructs the config class. */ -config::~config() +/*config::~config() { try { @@ -175,7 +156,7 @@ * \return -1 on error or 0 if operation finished succesfully * \note The properties does not have to be registered prior to use this function. */ -int_t config::read(const char_t* pszFile) +/*int_t config::read(const char_t* pszFile) { // NOTE: this function should reset the m_bModified flag // open the file @@ -232,7 +213,7 @@ * \param[in] pszFile - path to a .conf file to which the properties shoud be written * \return -1 on error, 0 on success. */ -int_t config::write(const char_t* pszFile) +/*int_t config::write(const char_t* pszFile) { // if the config was not modified - why bother writing if (!m_bModified) @@ -329,7 +310,7 @@ * \param[in] ulProp - property id to get info about. * \return The property type. */ -int_t config::get_proptype(ulong_t ulProp) +/*int_t config::get_proptype(ulong_t ulProp) { m_lock.lock(); @@ -349,7 +330,7 @@ * \param[in] iFlags - additional flags that should be associated with property * \return Property ID of the newly registered property. */ -ulong_t config::register_int(const char_t* pszName, int_t iDef, int_t iLo, int_t iHi, int_t iFlags) +/*ulong_t config::register_int(const char_t* pszName, int_t iDef, int_t iLo, int_t iHi, int_t iFlags) { // check if there is already registered value with the given name m_lock.lock(); @@ -361,36 +342,36 @@ } else { - _PROP prop; + _PROP property; // check if the property is in the unreg container if ( (ulRes = is_unreg(pszName)) == (ulong_t)-1 ) { // property not found in the unreg - means that this is quite new stuff - prop.bModified=true; - prop.pszName=new char_t[strlen(pszName)+1]; - strcpy(prop.pszName, pszName); - prop.val.i.iVal=iDef; // will be overwritten when reading file + property.bModified=true; + property.pszName=new char_t[strlen(pszName)+1]; + strcpy(property.pszName, pszName); + property.val.i.iVal=iDef; // will be overwritten when reading file } else { // get the entry - prop=m_pvUnreg->at(ulRes); + property=m_pvUnreg->at(ulRes); m_pvUnreg->erase(m_pvUnreg->begin()+ulRes); // set the value from a string - int_t iVal=atol(prop.val.pszVal); - delete [] prop.val.pszVal; - prop.val.i.iVal=iVal; + int_t iVal=atol(property.val.pszVal); + delete [] property.val.pszVal; + property.val.i.iVal=iVal; } // common part - prop.iType=PT_INT | iFlags; - prop.val.i.iLo=iLo; - prop.val.i.iHi=iHi; + property.iType=PT_INT | iFlags; + property.val.i.iLo=iLo; + property.val.i.iHi=iHi; // add to the list - m_pvProps->push_back(prop); + m_pvProps->push_back(property); m_bModified=true; ulRes=(ulong_t)(m_pvProps->size()-1); m_lock.unlock(); @@ -409,7 +390,7 @@ * \param[in] iFlags - additional flags that should be associated with property * \return Property ID of the newly registered property. */ -ulong_t config::register_uint(const char_t* pszName, uint_t uiDef, uint_t uiLo, uint_t uiHi, int_t iFlags) +/*ulong_t config::register_uint(const char_t* pszName, uint_t uiDef, uint_t uiLo, uint_t uiHi, int_t iFlags) { // check if there is already registered value with the given name m_lock.lock(); @@ -421,33 +402,33 @@ } else { - _PROP prop; + _PROP property; if ( (ulRes = is_unreg(pszName)) == (ulong_t)-1 ) { - prop.pszName=new char_t[strlen(pszName)+1]; - strcpy(prop.pszName, pszName); - prop.val.ui.uiVal=uiDef; // will be overwritten when reading file - prop.bModified=true; + property.pszName=new char_t[strlen(pszName)+1]; + strcpy(property.pszName, pszName); + property.val.ui.uiVal=uiDef; // will be overwritten when reading file + property.bModified=true; } else { // get the entry - prop=m_pvUnreg->at(ulRes); + property=m_pvUnreg->at(ulRes); m_pvUnreg->erase(m_pvUnreg->begin()+ulRes); - uint_t uiVal=strtoul(prop.val.pszVal, NULL, 10); - delete [] prop.val.pszVal; - prop.val.ui.uiVal=uiVal; + uint_t uiVal=strtoul(property.val.pszVal, NULL, 10); + delete [] property.val.pszVal; + property.val.ui.uiVal=uiVal; } // common part - prop.iType=PT_UINT | iFlags; - prop.val.ui.uiLo=uiLo; - prop.val.ui.uiHi=uiHi; + property.iType=PT_UINT | iFlags; + property.val.ui.uiLo=uiLo; + property.val.ui.uiHi=uiHi; // add to the list - m_pvProps->push_back(prop); + m_pvProps->push_back(property); m_bModified=true; ulRes=(ulong_t)(m_pvProps->size()-1); m_lock.unlock(); @@ -466,7 +447,7 @@ * \param[in] iFlags - additional flags that should be associated with property * \return Property ID of the newly registered property. */ -ulong_t config::register_longlong(const char_t* pszName, longlong_t llDef, longlong_t llLo, longlong_t llHi, int_t iFlags) +/*ulong_t config::register_longlong(const char_t* pszName, longlong_t llDef, longlong_t llLo, longlong_t llHi, int_t iFlags) { // check if there is already registered value with the given name m_lock.lock(); @@ -478,38 +459,38 @@ } else { - _PROP prop; + _PROP property; if ( (ulRes = is_unreg(pszName)) == (ulong_t)-1 ) { - prop.pszName=new char_t[strlen(pszName)+1]; - strcpy(prop.pszName, pszName); - prop.val.ll.llVal=llDef; // will be overwritten when reading file - prop.bModified=true; + property.pszName=new char_t[strlen(pszName)+1]; + strcpy(property.pszName, pszName); + property.val.ll.llVal=llDef; // will be overwritten when reading file + property.bModified=true; } else { // get the entry - prop=m_pvUnreg->at(ulRes); + property=m_pvUnreg->at(ulRes); m_pvUnreg->erase(m_pvUnreg->begin()+ulRes); ll_t llVal; #ifdef _WIN32 - llVal=_atoi64(prop.val.pszVal); + llVal=_atoi64(property.val.pszVal); #else - llVal=atoll(prop.val.pszVal); + llVal=atoll(property.val.pszVal); #endif - delete [] prop.val.pszVal; - prop.val.ll.llVal=llVal; + delete [] property.val.pszVal; + property.val.ll.llVal=llVal; } // common - prop.iType=PT_LONGLONG | iFlags; - prop.val.ll.llLo=llLo; - prop.val.ll.llHi=llHi; + property.iType=PT_LONGLONG | iFlags; + property.val.ll.llLo=llLo; + property.val.ll.llHi=llHi; // add to the list - m_pvProps->push_back(prop); + m_pvProps->push_back(property); m_bModified=true; ulRes=(ulong_t)(m_pvProps->size()-1); m_lock.unlock(); @@ -528,7 +509,7 @@ * \param[in] iFlags - additional flags that should be associated with property * \return Property ID of the newly registered property. */ -ulong_t config::register_ulonglong(const char_t* pszName, ulonglong_t ullDef, ulonglong_t ullLo, ulonglong_t ullHi, int_t iFlags) +/*ulong_t config::register_ulonglong(const char_t* pszName, ulonglong_t ullDef, ulonglong_t ullLo, ulonglong_t ullHi, int_t iFlags) { // check if there is already registered value with the given name m_lock.lock(); @@ -540,37 +521,37 @@ } else { - _PROP prop; + _PROP property; if ( (ulRes = is_unreg(pszName)) == (ulong_t)-1 ) { - prop.pszName=new char_t[strlen(pszName)+1]; - strcpy(prop.pszName, pszName); - prop.val.ull.ullVal=ullDef; // will be overwritten when reading file - prop.bModified=true; + property.pszName=new char_t[strlen(pszName)+1]; + strcpy(property.pszName, pszName); + property.val.ull.ullVal=ullDef; // will be overwritten when reading file + property.bModified=true; } else { - prop=m_pvUnreg->at(ulRes); + property=m_pvUnreg->at(ulRes); m_pvUnreg->erase(m_pvUnreg->begin()+ulRes); ull_t ullVal; #ifdef _WIN32 - ullVal=(ulonglong_t)_atoi64(prop.val.pszVal); + ullVal=(ulonglong_t)_atoi64(property.val.pszVal); #else - ullVal=(ulonglong_t)atoll(prop.val.pszVal); + ullVal=(ulonglong_t)atoll(property.val.pszVal); #endif - delete [] prop.val.pszVal; - prop.val.ull.ullVal=ullVal; + delete [] property.val.pszVal; + property.val.ull.ullVal=ullVal; } // common - prop.iType=PT_ULONGLONG | iFlags; - prop.val.ull.ullLo=ullLo; - prop.val.ull.ullHi=ullHi; + property.iType=PT_ULONGLONG | iFlags; + property.val.ull.ullLo=ullLo; + property.val.ull.ullHi=ullHi; // add to the list - m_pvProps->push_back(prop); + m_pvProps->push_back(property); m_bModified=true; ulRes=(ulong_t)(m_pvProps->size()-1); m_lock.unlock(); @@ -587,7 +568,7 @@ * \param[in] iFlags - additional flags that should be associated with property * \return Property ID of the newly registered property. */ -ulong_t config::register_bool(const char_t* pszName, bool bDef, int_t iFlags) +/*ulong_t config::register_bool(const char_t* pszName, bool bDef, int_t iFlags) { // check if there is already registered value with the given name m_lock.lock(); @@ -599,37 +580,37 @@ } else { - _PROP prop; + _PROP property; if ( (ulRes = is_unreg(pszName)) == (ulong_t)-1 ) { - prop.pszName=new char_t[strlen(pszName)+1]; - strcpy(prop.pszName, pszName); - prop.val.bVal=bDef; // current - prop.bModified=true; + property.pszName=new char_t[strlen(pszName)+1]; + strcpy(property.pszName, pszName); + property.val.bVal=bDef; // current + property.bModified=true; } else { - prop=m_pvUnreg->at(ulRes); + property=m_pvUnreg->at(ulRes); m_pvUnreg->erase(m_pvUnreg->begin()+ulRes); bool bVal; - if (strcmp(prop.val.pszVal, "yes") == 0) + if (strcmp(property.val.pszVal, "yes") == 0) bVal=true; - else if (strcmp(prop.val.pszVal, "no") == 0) + else if (strcmp(property.val.pszVal, "no") == 0) bVal=false; else - bVal=atoi(prop.val.pszVal) != 0; + bVal=atoi(property.val.pszVal) != 0; - delete [] prop.val.pszVal; - prop.val.bVal=bVal; + delete [] property.val.pszVal; + property.val.bVal=bVal; } // common - prop.iType=PT_BOOL | iFlags; + property.iType=PT_BOOL | iFlags; // add to the list - m_pvProps->push_back(prop); + m_pvProps->push_back(property); m_bModified=true; ulRes=(ulong_t)(m_pvProps->size()-1); m_lock.unlock(); @@ -648,7 +629,7 @@ * \param[in] iFlags - additional flags that should be associated with property * \return Property ID of the newly registered property. */ -ulong_t config::register_string(const char_t* pszName, const char_t* pszDef, int_t iFlags) +/*ulong_t config::register_string(const char_t* pszName, const char_t* pszDef, int_t iFlags) { // check if there is already registered value with the given name m_lock.lock(); @@ -660,31 +641,31 @@ } else { - _PROP prop; + _PROP property; if ( (ulRes = is_unreg(pszName)) == (ulong_t)-1 ) { - prop.iType=PT_STRING | iFlags; + property.iType=PT_STRING | iFlags; #ifdef USE_ENCRYPTION if (iFlags & PF_ENCRYPTED) - prop.iType |= PF_DECODED; + property.iType |= PF_DECODED; #endif - prop.pszName=new char_t[strlen(pszName)+1]; - strcpy(prop.pszName, pszName); + property.pszName=new char_t[strlen(pszName)+1]; + strcpy(property.pszName, pszName); - prop.val.pszVal=new char_t[strlen(pszDef)+1]; - strcpy(prop.val.pszVal, pszDef); - prop.bModified=true; + property.val.pszVal=new char_t[strlen(pszDef)+1]; + strcpy(property.val.pszVal, pszDef); + property.bModified=true; } else { - prop=m_pvUnreg->at(ulRes); + property=m_pvUnreg->at(ulRes); m_pvUnreg->erase(m_pvUnreg->begin()+ulRes); - prop.iType = PT_STRING | iFlags; + property.iType = PT_STRING | iFlags; } // add to the list - m_pvProps->push_back(prop); + m_pvProps->push_back(property); m_bModified=true; ulRes=(ulong_t)(m_pvProps->size()-1); m_lock.unlock(); @@ -698,7 +679,7 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \return The property value. */ -int_t config::get_int(ulong_t ulProp) +/*int_t config::get_int(ulong_t ulProp) { m_lock.lock(); @@ -714,7 +695,7 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \return The property value. */ -uint_t config::get_uint(ulong_t ulProp) +/*uint_t config::get_uint(ulong_t ulProp) { m_lock.lock(); @@ -730,7 +711,7 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \return The property value. */ -longlong_t config::get_longlong(ulong_t ulProp) +/*longlong_t config::get_longlong(ulong_t ulProp) { m_lock.lock(); @@ -746,7 +727,7 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \return The property value. */ -ulonglong_t config::get_ulonglong(ulong_t ulProp) +/*ulonglong_t config::get_ulonglong(ulong_t ulProp) { m_lock.lock(); @@ -762,7 +743,7 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \return The property value. */ -bool config::get_bool(ulong_t ulProp) +/*bool config::get_bool(ulong_t ulProp) { m_lock.lock(); @@ -780,19 +761,19 @@ * \param[out] psz - buffer for the string * \param[in] tMaxLen - length of the buffer */ -void config::get_string(ulong_t ulProp, char_t* psz, size_t tMaxLen) +/*void config::get_string(ulong_t ulProp, char_t* psz, size_t tMaxLen) { m_lock.lock(); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_STRING); - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); #ifdef USE_ENCRYPTION // if the property is encrypted and not decoded yet - decode it try { - decrypt_property(&prop); + decrypt_property(&property); } catch(...) { @@ -801,7 +782,7 @@ } #endif - char_t* pszSrc=prop.val.pszVal; + char_t* pszSrc=property.val.pszVal; strncpy(psz, pszSrc, tMaxLen); psz[tMaxLen-1]='\0'; @@ -814,19 +795,19 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \return The pointer to a string contained in the internal structure. */ -char_t* config::get_string(ulong_t ulProp) +/*char_t* config::get_string(ulong_t ulProp) { m_lock.lock(); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_STRING); - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); #ifdef USE_ENCRYPTION // if the property is encrypted and not decoded yet - decode it try { - decrypt_property(&prop); + decrypt_property(&property); } catch(...) { @@ -835,7 +816,7 @@ } #endif - char_t* psz=prop.val.pszVal; + char_t* psz=property.val.pszVal; char_t* pszNew=new char_t[strlen(psz)+1]; strcpy(pszNew, psz); @@ -849,29 +830,29 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \param[in] lVal - the new value of property to set */ -void config::set_int(ulong_t ulProp, int_t iVal, prop_group* pGroup) +/*void config::set_int(ulong_t ulProp, int_t iVal, property_tracker* pGroup) { m_lock.lock(); // get the data - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_INT); - int_t iOldVal=prop.val.i.iVal; + int_t iOldVal=property.val.i.iVal; // check the range - if (iVal < prop.val.i.iLo) - prop.val.i.iVal=prop.val.i.iLo; - else if (iVal > prop.val.i.iHi) - prop.val.i.iVal=prop.val.i.iHi; + if (iVal < property.val.i.iLo) + property.val.i.iVal=property.val.i.iLo; + else if (iVal > property.val.i.iHi) + property.val.i.iVal=property.val.i.iHi; else - prop.val.i.iVal=iVal; + property.val.i.iVal=iVal; - bool bMod=(prop.val.i.iVal != iOldVal); + bool bMod=(property.val.i.iVal != iOldVal); if (bMod) { - prop.bModified=true; + property.bModified=true; m_bModified=true; } m_lock.unlock(); @@ -882,7 +863,7 @@ pGroup->add(ulProp); else { - prop_group* pg=begin_group((ulong_t)-1); + property_tracker* pg=begin_group((ulong_t)-1); pg->add(ulProp); end_group(pg); } @@ -894,30 +875,30 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \param[in] uiVal - the new value of property to set */ -void config::set_uint(ulong_t ulProp, uint_t uiVal, prop_group* pGroup) +/*void config::set_uint(ulong_t ulProp, uint_t uiVal, property_tracker* pGroup) { m_lock.lock(); // get the data - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_UINT); - uint_t uiOldVal=prop.val.ui.uiVal; + uint_t uiOldVal=property.val.ui.uiVal; // check the range - if (uiVal < prop.val.ui.uiLo) - prop.val.ui.uiVal=prop.val.ui.uiLo; - else if (uiVal > prop.val.ui.uiHi) - prop.val.ui.uiVal=prop.val.ui.uiHi; + if (uiVal < property.val.ui.uiLo) + property.val.ui.uiVal=property.val.ui.uiLo; + else if (uiVal > property.val.ui.uiHi) + property.val.ui.uiVal=property.val.ui.uiHi; else - prop.val.ui.uiVal=uiVal; + property.val.ui.uiVal=uiVal; - bool bMod=(prop.val.ui.uiVal != uiOldVal); + bool bMod=(property.val.ui.uiVal != uiOldVal); if (bMod) { - prop.bModified=true; + property.bModified=true; m_bModified=true; } m_lock.unlock(); @@ -928,7 +909,7 @@ pGroup->add(ulProp); else { - prop_group* pg=begin_group((ulong_t)-1); + property_tracker* pg=begin_group((ulong_t)-1); pg->add(ulProp); end_group(pg); } @@ -940,30 +921,30 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \param[in] llVal - the new value of property to set */ -void config::set_longlong(ulong_t ulProp, longlong_t llVal, prop_group* pGroup) +/*void config::set_longlong(ulong_t ulProp, longlong_t llVal, property_tracker* pGroup) { m_lock.lock(); // get the data - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_LONGLONG); - ll_t llOldVal=prop.val.ll.llVal; + ll_t llOldVal=property.val.ll.llVal; // check the range - if (llVal < prop.val.ll.llLo) - prop.val.ll.llVal=prop.val.ll.llLo; - else if (llVal > prop.val.ll.llHi) - prop.val.ll.llVal=prop.val.ll.llHi; + if (llVal < property.val.ll.llLo) + property.val.ll.llVal=property.val.ll.llLo; + else if (llVal > property.val.ll.llHi) + property.val.ll.llVal=property.val.ll.llHi; else - prop.val.ll.llVal=llVal; + property.val.ll.llVal=llVal; - bool bMod=(prop.val.ll.llVal != llOldVal); + bool bMod=(property.val.ll.llVal != llOldVal); if (bMod) { - prop.bModified=true; + property.bModified=true; m_bModified=true; } m_lock.unlock(); @@ -974,7 +955,7 @@ pGroup->add(ulProp); else { - prop_group* pg=begin_group((ulong_t)-1); + property_tracker* pg=begin_group((ulong_t)-1); pg->add(ulProp); end_group(pg); } @@ -986,30 +967,30 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \param[in] ullVal - the new value of property to set */ -void config::set_ulonglong(ulong_t ulProp, ulonglong_t ullVal, prop_group* pGroup) +/*void config::set_ulonglong(ulong_t ulProp, ulonglong_t ullVal, property_tracker* pGroup) { m_lock.lock(); // get the data - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_ULONGLONG); - ull_t ullOldVal=prop.val.ull.ullVal; + ull_t ullOldVal=property.val.ull.ullVal; // check the range - if (ullVal < prop.val.ull.ullLo) - prop.val.ull.ullVal=prop.val.ull.ullLo; - else if (ullVal > prop.val.ull.ullHi) - prop.val.ull.ullVal=prop.val.ull.ullHi; + if (ullVal < property.val.ull.ullLo) + property.val.ull.ullVal=property.val.ull.ullLo; + else if (ullVal > property.val.ull.ullHi) + property.val.ull.ullVal=property.val.ull.ullHi; else - prop.val.ull.ullVal=ullVal; + property.val.ull.ullVal=ullVal; - bool bMod=(prop.val.ull.ullVal != ullOldVal); + bool bMod=(property.val.ull.ullVal != ullOldVal); if (bMod) { - prop.bModified=true; + property.bModified=true; m_bModified=true; } m_lock.unlock(); @@ -1020,7 +1001,7 @@ pGroup->add(ulProp); else { - prop_group* pg=begin_group((ulong_t)-1); + property_tracker* pg=begin_group((ulong_t)-1); pg->add(ulProp); end_group(pg); } @@ -1032,20 +1013,20 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \param[in] bVal - the new value of property to set */ -void config::set_bool(ulong_t ulProp, bool bVal, prop_group* pGroup) +/*void config::set_bool(ulong_t ulProp, bool bVal, property_tracker* pGroup) { m_lock.lock(); // get the data - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_BOOL); - bool bMod=(prop.val.bVal != bVal); + bool bMod=(property.val.bVal != bVal); if (bMod) { - prop.val.bVal=bVal; + property.val.bVal=bVal; - prop.bModified=true; + property.bModified=true; m_bModified=true; } m_lock.unlock(); @@ -1056,7 +1037,7 @@ pGroup->add(ulProp); else { - prop_group* pg=begin_group((ulong_t)-1); + property_tracker* pg=begin_group((ulong_t)-1); pg->add(ulProp); end_group(pg); } @@ -1068,25 +1049,25 @@ * \param[in] ulProp - property identifier returned by one of the register_* functions * \param[in] pszVal - the new value of property to set */ -void config::set_string(ulong_t ulProp, const char_t* pszVal, prop_group* pGroup) +/*void config::set_string(ulong_t ulProp, const char_t* pszVal, property_tracker* pGroup) { m_lock.lock(); - _PROP& prop=m_pvProps->at(ulProp); + _PROP& property=m_pvProps->at(ulProp); assert((m_pvProps->at(ulProp).iType & PTM_TYPE) == PT_STRING); - delete [] prop.val.pszVal; - prop.val.pszVal=new char_t[strlen(pszVal)+1]; - strcpy(prop.val.pszVal, pszVal); + delete [] property.val.pszVal; + property.val.pszVal=new char_t[strlen(pszVal)+1]; + strcpy(property.val.pszVal, pszVal); - prop.bModified=true; + property.bModified=true; m_bModified=true; #ifdef USE_ENCRYPTION // make sure the property is marked decoded - if (prop.iType & PF_ENCRYPTED) - prop.iType |= PF_DECODED; + if (property.iType & PF_ENCRYPTED) + property.iType |= PF_DECODED; #endif m_lock.unlock(); @@ -1095,7 +1076,7 @@ pGroup->add(ulProp); else { - prop_group* pg=begin_group((ulong_t)-1); + property_tracker* pg=begin_group((ulong_t)-1); pg->add(ulProp); end_group(pg); } @@ -1109,16 +1090,16 @@ * \param[in] ulID - group id * \return A pointer to a new property group. Must be released using end_group(). */ -prop_group* config::begin_group(ulong_t ulID) const +/*property_tracker* config::begin_group(ulong_t ulID) const { - return new prop_group(ulID); + return new property_tracker(ulID); } /** Ends a property group started with a begin_group(). Releases the allocated pointer and sends a group property * change information to the callback. * \param[in] pGroup - pointer to the property group allocated with begin_group() */ -void config::end_group(prop_group* pGroup) +/*void config::end_group(property_tracker* pGroup) { assert(pGroup); if (pGroup->count() > 0) @@ -1131,7 +1112,7 @@ * previous password will be decrypted using an old password before setting a new one. * \param[in] pszPass - a new password to be set. */ -void config::set_password(const char_t* pszPass) +/*void config::set_password(const char_t* pszPass) { m_lock.lock(); @@ -1163,58 +1144,58 @@ /** Internal function that encrypts a one specified property structure. Does make a check regarding * the correctness of the property. If it does not met the criteria, then function does nothing. - * \param[in/out] prop - address of the structure describing the property. + * \param[in/out] property - address of the structure describing the property. */ -void config::encrypt_property(_PROP* prop) const +/*void config::encrypt_property(_PROP* property) const { printf("Encrypting...\n"); - if ((prop->iType & (PT_STRING | PF_ENCRYPTED | PF_DECODED)) == (PT_STRING | PF_ENCRYPTED | PF_DECODED)) + if ((property->iType & (PT_STRING | PF_ENCRYPTED | PF_DECODED)) == (PT_STRING | PF_ENCRYPTED | PF_DECODED)) { printf("Real encrypt...\n"); - ulong_t ulLen=(ulong_t)(((strlen(prop->val.pszVal)+1)*sizeof(char_t)+16)*2); + ulong_t ulLen=(ulong_t)(((strlen(property->val.pszVal)+1)*sizeof(char_t)+16)*2); char_t *pszOut=new char_t[ulLen]; try { - strcrypt_aes256(prop->val.pszVal, (const char_t*)m_strPassword, pszOut); + strcrypt_aes256(property->val.pszVal, (const char_t*)m_strPassword, pszOut); } catch(...) { delete [] pszOut; throw; } - delete [] prop->val.pszVal; - prop->val.pszVal=pszOut; + delete [] property->val.pszVal; + property->val.pszVal=pszOut; - prop->iType &= ~PF_DECODED; + property->iType &= ~PF_DECODED; } } /** Internal function that decrypts a one specified property structure. Does make a check regarding * the correctness of the property. If it does not met the criteria, then function does nothing. - * \param[in/out] prop - address of the structure describing the property. + * \param[in/out] property - address of the structure describing the property. */ -void config::decrypt_property(_PROP* prop) const +/*void config::decrypt_property(_PROP* property) const { - if ((prop->iType & (PT_STRING | PF_ENCRYPTED | PF_DECODED)) == (PT_STRING | PF_ENCRYPTED)) + if ((property->iType & (PT_STRING | PF_ENCRYPTED | PF_DECODED)) == (PT_STRING | PF_ENCRYPTED)) { - ulong_t ulLen=(ulong_t)(strlen(prop->val.pszVal)/2); + ulong_t ulLen=(ulong_t)(strlen(property->val.pszVal)/2); char_t *pszOut=new char_t[ulLen]; try { - strdecrypt_aes256(prop->val.pszVal, (const char_t*)m_strPassword, pszOut); + strdecrypt_aes256(property->val.pszVal, (const char_t*)m_strPassword, pszOut); } catch(...) { delete [] pszOut; throw; } - delete [] prop->val.pszVal; - prop->val.pszVal=pszOut; + delete [] property->val.pszVal; + property->val.pszVal=pszOut; - prop->iType |= PF_DECODED; + property->iType |= PF_DECODED; } } @@ -1227,7 +1208,7 @@ * \param[in,out] pszString - string to process * \return Pointer to the first non-whitespace character in a string. */ -char_t* config::trim(char_t* pszString) const +/*char_t* config::trim(char_t* pszString) const { char_t *pszData=pszString; @@ -1253,7 +1234,7 @@ * \param[in] pszValue - value of the property; the string is processed using * the property type found */ -void config::process_line(const char_t* pszName, const char_t* pszValue) +/*void config::process_line(const char_t* pszName, const char_t* pszValue) { // check if the property name is registered for (std::vector<_PROP>::iterator it=m_pvProps->begin();it != m_pvProps->end();it++) @@ -1327,59 +1308,59 @@ } } - // if the property wasn't found - add to the unreg as string prop - _PROP prop; - prop.iType=PT_STRING; - prop.pszName=new char_t[strlen(pszName)+1]; - strcpy(prop.pszName, pszName); - prop.bModified=false; - prop.val.pszVal=new char_t[strlen(pszValue)+1]; - strcpy(prop.val.pszVal, pszValue); + // if the property wasn't found - add to the unreg as string property + _PROP property; + property.iType=PT_STRING; + property.pszName=new char_t[strlen(pszName)+1]; + strcpy(property.pszName, pszName); + property.bModified=false; + property.val.pszVal=new char_t[strlen(pszValue)+1]; + strcpy(property.val.pszVal, pszValue); - m_pvUnreg->push_back(prop); + m_pvUnreg->push_back(property); } /** Prepares the string with the property value to be written to a file. * There is no sane limitation of the string length (but one should be careful * because such a limitation is integrated with read-related functions. - * \param[in] prop - pointer to the internal structure with property description + * \param[in] property - pointer to the internal structure with property description * \param[out] pres - pointer to a string object that will receive the line of text */ -void config::prepare_line(const _PROP* prop, string* pres) const +/*void config::prepare_line(const _PROP* property, string* pres) const { - assert(prop && pres); + assert(property && pres); char_t szLine[MAX_LINE]; - switch(prop->iType & PTM_TYPE) + switch(property->iType & PTM_TYPE) { case PT_INT: { - snprintf(szLine, MAX_LINE, STRFMT " = " LFMT, prop->pszName, prop->val.i.iVal); + snprintf(szLine, MAX_LINE, STRFMT " = " LFMT, property->pszName, property->val.i.iVal); break; } case PT_UINT: { - snprintf(szLine, MAX_LINE, STRFMT " = " ULFMT, prop->pszName, prop->val.ui.uiVal); + snprintf(szLine, MAX_LINE, STRFMT " = " ULFMT, property->pszName, property->val.ui.uiVal); break; } case PT_LONGLONG: { - snprintf(szLine, MAX_LINE, STRFMT " = " LLFMT, prop->pszName, prop->val.ll.llVal); + snprintf(szLine, MAX_LINE, STRFMT " = " LLFMT, property->pszName, property->val.ll.llVal); break; } case PT_ULONGLONG: { - snprintf(szLine, MAX_LINE, STRFMT " = " ULLFMT, prop->pszName, prop->val.ull.ullVal); + snprintf(szLine, MAX_LINE, STRFMT " = " ULLFMT, property->pszName, property->val.ull.ullVal); break; } case PT_BOOL: { - snprintf(szLine, MAX_LINE, STRFMT " = " ULFMT, prop->pszName, (uint_t)prop->val.bVal); + snprintf(szLine, MAX_LINE, STRFMT " = " ULFMT, property->pszName, (uint_t)property->val.bVal); break; } case PT_STRING: { - snprintf(szLine, MAX_LINE, STRFMT " = " STRFMT, prop->pszName, prop->val.pszVal); + snprintf(szLine, MAX_LINE, STRFMT " = " STRFMT, property->pszName, property->val.pszVal); break; } default: @@ -1396,7 +1377,7 @@ * \param[in] pszName - property name to search for * \return The property ID if property has been found, or -1 if not. */ -ulong_t config::is_registered(const char_t* pszName) +/*ulong_t config::is_registered(const char_t* pszName) { // enum through all of the existing nodes for (std::vector<_PROP>::iterator it=m_pvProps->begin();it != m_pvProps->end();it++) @@ -1413,7 +1394,7 @@ * \param[in] pszName - name of the property to search for * \return Property index if found, -1 if not. */ -ulong_t config::is_unreg(const char_t* pszName) +/*ulong_t config::is_unreg(const char_t* pszName) { // enum through all of the existing nodes for (std::vector<_PROP>::iterator it=m_pvUnreg->begin();it != m_pvUnreg->end();it++) @@ -1423,6 +1404,6 @@ } return (ulong_t)-1; // no property found -} +}*/ END_ICPF_NAMESPACE Index: ext/libicpf/src/cfg.h =================================================================== diff -u -N -r2446443341715955423610c01b43fe7841a10e3e -r771dac1fbb7608aa92942c6cab7c5c8b0cccb791 --- ext/libicpf/src/cfg.h (.../cfg.h) (revision 2446443341715955423610c01b43fe7841a10e3e) +++ ext/libicpf/src/cfg.h (.../cfg.h) (revision 771dac1fbb7608aa92942c6cab7c5c8b0cccb791) @@ -26,117 +26,42 @@ #include "mutex.h" #include "libicpf.h" #include "gen_types.h" -#include "callback.h" -#include "str.h" +#include "config_base.h" +#include "config_property.h" BEGIN_ICPF_NAMESPACE -// property types -/// Property type mask -#define PTM_TYPE 0x00ff -/// Signed 32-bit type property -#define PT_INT 0x0001 -/// Unsigned 32-bit type property -#define PT_UINT 0x0002 -/// Signed 64-bit type property -#define PT_LONGLONG 0x0003 -/// Unsigned 64-bit type property -#define PT_ULONGLONG 0x0004 -/// Bool type property -#define PT_BOOL 0x0005 -/// String type property -#define PT_STRING 0x0006 - -// some flags -/// Property flags mask -#define PFM_FLAGS 0xff00 -/// Standard property flag -#define PF_NULL 0x0000 -/// The string specifies a pathname flag -#define PF_PATH 0x1000 -/// Flag that force checking if the property has already been registered (when registering a property) -#define PF_CHECK 0x2000 -/// This flag indicates that the property has been encrypted with a password (only string values) -#define PF_ENCRYPTED 0x4000 -/// The property is currently in decrypted state (but should be encrypted when saving) -#define PF_DECODED 0x8000 - -class config; - -extern config *__g_cfg; - -#ifdef _WIN32 -ICPFTEMPL_EXTERN template class LIBICPF_API callback2; -#endif - -/** \brief Structure contain information about one property. - * - * Struct is used to store information about any property type (name, value, - * default value, allowed range, ...). - */ -struct _PROP -{ - int_t iType; ///< Type of the property (PT_*, PF_*) - char_t *pszName; ///< Property name (as displayed in the .conf file) - bool bModified; ///< States if the property value has been modified - union prop /// Union with different types of properties - { - struct INTP /// Long-type property - { - int_t iVal; ///< Long value - int_t iLo; ///< Minimum allowed value for the int_t property - int_t iHi; ///< Maximum allowed value for the int_t property - } i; - - struct UINTP /// Unsigned int_t-type property - { - uint_t uiVal; ///< Unsigned int_t value - uint_t uiLo; ///< Minimum allowed value for the uint_t property - uint_t uiHi; ///< Maximum allowed value for the uint_t property - } ui; - - struct LLVAL /// Long int_t-type property - { - longlong_t llVal; ///< Long int_t value - longlong_t llLo; ///< Minimum allowed value for the longlong_t property - longlong_t llHi; ///< Maximum allowed value for the longlong_t property - } ll; - - struct ULLVAL /// Unsigned longlong_t-type property - { - ulonglong_t ullVal; ///< Unsigned longlong_t value - ulonglong_t ullLo; ///< Minimum allowed value for the ulonglong_t property - ulonglong_t ullHi; ///< Maximum allowed value for the ulonglong_t property - } ull; - - bool bVal; ///< A bool-type value - - char_t* pszVal; ///< A string-type value - } val; - -}; - /** \brief Property group handling class * * Class is being used to manipulate the property groups (in connection with config::begin_group() and * config::end_group(). */ -class LIBICPF_API prop_group +class LIBICPF_API property_tracker { public: - explicit prop_group(ulong_t ulID); ///< Standard constructor - ~prop_group(); ///< Standard destructor +/** \name Construction/destruction/operators */ +/**@{*/ + property_tracker(); ///< Standard constructor + property_tracker(const property_tracker& rSrc); ///< Copy constructor + ~property_tracker(); ///< Standard destructor - void add(ulong_t ulProp); ///< Adds a new property id to the list - bool is_set(ulong_t ulProp); ///< Checks if a property id is set inside this list - ulong_t count() const; ///< Returns a count of properties in a list - ulong_t get_at(ulong_t ulIndex); ///< Returns a property id at a given index - ulong_t get_groupid() const; ///< Retrieves the group id + property_tracker& operator=(const property_tracker& rSrc); ///< Assignment operator +/**@}*/ +/** \name Operations */ +/**@{*/ + void add(uint_t uiProp); ///< Adds a new property id to the list + bool is_set(uint_t uiProp); ///< Checks if a property id is set inside this list + size_t count() const; ///< Returns a count of properties in a list + + /// Retrieves the list of ID's + size_t get_ids(uint_t* puiProps, size_t stMaxCount); + /// Retrieves the list of ID's using an enumeration function + void enum_ids(bool(*pfn)(uint_t uiProp, ptr_t pParam), ptr_t pParam); +/**@}*/ + protected: - void* m_pProperties; ///< Internal member. Pointer to a storage structure with an int_t. -// std::vector m_vProperties; ///< List of properties in a group - ulong_t m_ulGroupID; ///< The group ID + ptr_t m_hProperties; ///< Internal member. Pointer to a storage structure with an int_t. }; /** \brief Configuration management class. @@ -151,16 +76,16 @@ public: /** \name Construction/destruction */ /**@{*/ - explicit config(bool bGlobal); ///< Standard constructor + config(config_base* pCfgBase); ///< Standard constructor ~config(); ///< Standard destructor /**@}*/ -/** \name Reading and writing to the file */ +/** \name Reading and writing to the external medium */ /**@{*/ - int_t read(const char_t *pszFile); ///< Opens the file with the properties - int_t write(const char_t* pszFile); ///< Saves the registered properties to the file + void read(const tchar_t *pszPath); ///< Reads the file with properties + void write(const tchar_t* pszPath); ///< Saves the properties to the file /**@}*/ - + /** \name Class lock/unlock functions */ /**@{*/ /// Locks the config class for one thread @@ -172,89 +97,57 @@ // property type management /** Property types */ /**@{*/ - int_t get_proptype(ulong_t ulProp); ///< Retrieves the property type + uint_t get_type(uint_t uiProp); ///< Retrieves the property type + size_t get_value_count(uint_t uiProp); ///< Retrieves the count of values for array-based property types + void remove_array_value(uint_t uiProp, size_t stIndex); ///< Removes a value at a specified index in array-based property type + void clear_array_values(uint_t uiProp); ///< Removes all values in array-based property + size_t count(); ///< Retrieves the count of properties contained in this config /**@}*/ // registering the properties /** \name Properties registration functions */ /**@{*/ - /// Registers int_t-type property - ulong_t register_int(const char_t* pszName, int_t iDef, int_t iLo, int_t iHi, int_t iFlags=PF_NULL | PF_CHECK); - /// Registers uint_t-type property - ulong_t register_uint(const char_t* pszName, uint_t uiDef, uint_t uiLo, uint_t uiHi, int_t iFlags=PF_NULL | PF_CHECK); - /// Registers longlong_t-type property - ulong_t register_longlong(const char_t* pszName, longlong_t llDef, longlong_t llLo, longlong_t llHi, int_t iFlags=PF_NULL | PF_CHECK); - /// Registers ulonglong_t-type property - ulong_t register_ulonglong(const char_t* pszName, ulonglong_t ullDef, ulonglong_t ullLo, ulonglong_t ullHi, int_t iFlags=PF_NULL | PF_CHECK); + /// Registers signed number-type property + uint_t register_signed_num(const tchar_t* pszName, ll_t llDef, ll_t llLo, ll_t llHi, uint_t uiFlags=property::flag_none); + /// Registers unsigned number-type property + uint_t register_unsigned_num(const tchar_t* pszName, ull_t ullDef, ull_t ullLo, ull_t ullHi, uint_t uiFlags=property::flag_none); /// Registers bool-type property - ulong_t register_bool(const char_t* pszName, bool bDef, int_t iFlags=PF_NULL | PF_CHECK); + uint_t register_bool(const tchar_t* pszName, bool bDef, uint_t uiFlags=property::flag_none); /// Registers string-type property - ulong_t register_string(const char_t* pszName, const char_t* pszDef, int_t iFlags=PF_NULL | PF_CHECK); + uint_t register_string(const tchar_t* pszName, const tchar_t* pszDef, uint_t uiFlags=property::flag_none); /**@}*/ - // getting property data /** \name Getting and setting values */ /**@{*/ - int_t get_int(ulong_t ulProp); ///< Gets the value of int_t-type property - uint_t get_uint(ulong_t ulProp); ///< Gets the value of uint_t-type property - longlong_t get_longlong(ulong_t ulProp); ///< Gets the value of longlong_t-type property - ulonglong_t get_ulonglong(ulong_t ulProp); ///< Gets the value of ulonglong_t-type property - bool get_bool(ulong_t ulProp); ///< Gets the value of bool-type property - void get_string(ulong_t ulProp, char_t* psz, size_t tMaxLen); ///< Gets the value of string-type property - char_t* get_string(ulong_t ulProp); ///< Gets the value of ulonglong_t-type property (faster and more dangerous) + /// Gets the value of string-type property + const tchar_t* get_value(uint_t uiProp, tchar_t* pszBuffer, size_t stMaxSize, size_t stIndex=0) const; + /// Gets the value of longlong_t-type property + ll_t get_signed_num(uint_t uiProp, size_t stIndex=0) const; + /// Gets the value of ulonglong_t-type property + ull_t get_unsigned_num(uint_t uiProp, size_t stIndex=0) const; + /// Gets the value of bool-type property + bool get_bool(uint_t uiProp, size_t stIndex=0) const; + /// Gets the value of string-type property + const tchar_t* get_string(uint_t uiProp, size_t stIndex=0) const; // setting property data - void set_int(ulong_t ulProp, int_t iVal, prop_group* pGroup=NULL); ///< Sets the value of int_t-type property - void set_uint(ulong_t ulProp, uint_t uiVal, prop_group* pGroup=NULL); ///< Sets the value of uint_t-type property - void set_longlong(ulong_t ulProp, longlong_t llVal, prop_group* pGroup=NULL); ///< Sets the value of longlong_t-type property - void set_ulonglong(ulong_t ulProp, ulonglong_t ullVal, prop_group* pGroup=NULL); ///< Sets the value of ulonglong_t-type property - void set_bool(ulong_t ulProp, bool bVal, prop_group* pGroup=NULL); ///< Sets the value of bool-type property - void set_string(ulong_t ulProp, const char_t* pszVal, prop_group* pGroup=NULL); ///< Sets the value of string-type property + /// Sets the value from the string + void set_value(uint_t uiProp, const tchar_t* pszVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of longlong_t-type property + void set_signed_num(uint_t uiProp, ll_t llVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of ulonglong_t-type property + void set_unsigned_num(uint_t uiProp, ull_t ullVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of bool-type property + void set_bool(uint_t uiProp, bool bVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); + /// Sets the value of string-type property + void set_string(uint_t uiProp, const tchar_t* pszVal, property::actions a=property::action_replace, size_t tIndex=0, property_tracker* pTracker=NULL); /**@}*/ - // group support -/** \name Property group support */ -/**@{*/ - prop_group* begin_group(ulong_t ulID) const; ///< Begins a property group (currently handles multiple property changes when setting property values) - void end_group(prop_group* pGroup); ///< Ends a property group -/**@}*/ - -#ifdef USE_ENCRYPTION -/** \name Encryption related */ -/**@{*/ - void set_password(const char_t* pszPass); ///< Sets a password to encrypt/decrypt the properties -/**@}*/ -#endif - - static config* get_config(); ///< Retrieves the pointer to the global config class - protected: - char_t* trim(char_t* pszString) const; ///< Gets rid of whitespace characters from a string - void process_line(const char_t* pszName, const char_t* pszValue); ///< Sets a property value if registered - void prepare_line(const _PROP* prop, string* pres) const; ///< Prepares a line of text with property key and value to write to a file - ulong_t is_registered(const char_t* pszName); ///< Checks if a property with a given key has been registered - ulong_t is_unreg(const char_t* pszName); ///< Chacks if the path is contained in unreg container - -#ifdef USE_ENCRYPTION - void encrypt_property(_PROP* prop) const; ///< Encrypts a string property - void decrypt_property(_PROP* prop) const; ///< Decrypts a string property -#endif - -protected: - mutex m_lock; ///< Lock for the multi-threaded access to the properties - void* m_pProps; ///< Properties' storage - void* m_pUnreg; ///< Properties read from file, but not registered. - - bool m_bModified; ///< Global modification flag - states if any property is in modified state - -#ifdef USE_ENCRYPTION - string m_strPassword; ///< Password to encrypt/decrypt properties with -#endif - -public: - callback2 m_clbPropertyChanged; ///< Callback (callback2) which is executed when any property has changed - // First param is count of properties changed (-1 if all changed), second one the prop_group* (or NULL if none changed) + mutex m_lock; ///< Lock for the multi-threaded access to the properties + ptr_t m_hProps; ///< Handle to the registered property storage + config_base* m_pCfgBase; ///< Underlying base for this class }; END_ICPF_NAMESPACE Index: ext/libicpf/src/config_base.h =================================================================== diff -u -N -r3e7ccb6efc5089399a7801082d923aeb41f53d2e -r771dac1fbb7608aa92942c6cab7c5c8b0cccb791 --- ext/libicpf/src/config_base.h (.../config_base.h) (revision 3e7ccb6efc5089399a7801082d923aeb41f53d2e) +++ ext/libicpf/src/config_base.h (.../config_base.h) (revision 771dac1fbb7608aa92942c6cab7c5c8b0cccb791) @@ -6,6 +6,10 @@ BEGIN_ICPF_NAMESPACE +/** Base config class. Manages the data that can be directly + * read or written to the storage medium (xml file, ini file, + * registry, ...). + */ class config_base { public: Index: ext/libicpf/src/config_property.cpp =================================================================== diff -u -N --- ext/libicpf/src/config_property.cpp (revision 0) +++ ext/libicpf/src/config_property.cpp (revision 771dac1fbb7608aa92942c6cab7c5c8b0cccb791) @@ -0,0 +1,976 @@ +#include "config_property.h" +#include +#include + +BEGIN_ICPF_NAMESPACE + +////////////////////////////////////////////////////////////////////////////////// +// property class +// fast access to the array property types +#define m_paStrings ((std::vector*)m_val.hArray) +#define m_paSigneds ((std::vector*)m_val.hArray) +#define m_paUnsigneds ((std::vector*)m_val.hArray) +#define m_paBools ((std::vector*)m_val.hArray) + +/** Constructs a property object. + */ +property::property() : + m_uiPropType(prop_type::type_unknown | prop_flags::flag_none), + m_pszName(NULL) +{ + memset(&m_val, 0, sizeof(_VALUE)); + memset(&m_range, 0, sizeof(_RANGE)); +} + +/** Constructs a property object with type initializer. + * + * \param[in] uiType - type and flags to set the property to + */ +property::property(const tchar_t* pszName, uint_t uiType) : + m_uiPropType(uiType), + m_pszName(NULL) +{ + // init + init(pszName, uiType); +} + +/** Constructs a property object based on some other property object. + * + * \param[in] src - a source property object + */ +property::property(const property& src) +{ + operator=(src); +} + +/** Destructs the property object. + */ +property::~property() +{ + clear(); +} + +/** Assigns one property to another. + * + * \param[in] rSrc - a source property to copy + * \return Reference to this object. + */ +property& property::operator=(const property& rSrc) +{ + if (this != &rSrc) + { + // clear values in this class + clear_value(); + + // copy the value(s) + if (rSrc.m_uiPropType & prop_flags::flag_array) + { + // source property is an array + switch(rSrc.m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + case prop_type::type_signed_num: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + case prop_type::type_unsigned_num: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + case prop_type::type_bool: + m_val.hArray=new std::vector(*(std::vector*)rSrc.m_val.hArray); + break; + default: + assert(false); // unknown property type + } + } + else + { + // source property is normal value + switch(rSrc.m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + { + m_val.pszVal=copy_string(rSrc.m_val.pszVal); + break; + } + case prop_type::type_signed_num: + { + m_val.llVal=rSrc.m_val.llVal; + m_range.ll.llHi=rSrc.m_range.ll.llHi; + m_range.ll.llLo=rSrc.m_range.ll.llLo; + break; + } + case prop_type::type_unsigned_num: + { + m_val.ullVal=rSrc.m_val.ullVal; + m_range.ull.ullHi=rSrc.m_range.ull.ullHi; + m_range.ull.ullLo=rSrc.m_range.ull.ullLo; + break; + } + case prop_type::type_bool: + { + m_val.bVal=rSrc.m_val.bVal; + break; + } + default: + assert(false); // property type not implemented? + } + } + + // copy values + m_uiPropType=rSrc.m_uiPropType; + m_pszName=copy_string(rSrc.m_pszName); + } + + return *this; +} + +/** Clears all the internal members. + */ +void property::clear() +{ + // delete the property name + delete [] m_pszName; + m_pszName=NULL; + + clear_value(); + + // reset other members + m_uiPropType=prop_type::type_unknown | prop_flags::flag_none; +} + +/** Initializes the property for storaging of the specific property + * type. Also sets the property name. + * The current property contents are being cleared before setting + * the new type. + * + * \param[in] uiType - the new property type + */ +void property::init(const tchar_t* pszName, uint_t uiType, bool bClear) +{ + // clear the current stuff + if (bClear) + clear(); + + // standard members + m_pszName=copy_string(pszName); + m_uiPropType=uiType; + + // and alloc memory for the array property types + if (uiType & prop_flags::flag_array) + { + switch(uiType & prop_mask::mask_type) + { + case prop_type::type_string: + m_val.hArray=(ptr_t)new std::vector; + break; + case prop_type::type_signed_num: + m_val.hArray=(ptr_t)new std::vector; + m_range.ll.llLo=_I64_MIN; + m_range.ll.llHi=_I64_MAX; + break; + case prop_type::type_unsigned_num: + m_val.hArray=(ptr_t)new std::vector; + m_range.ull.ullLo=0; + m_range.ull.ullHi=_UI64_MAX; + break; + case prop_type::type_bool: + m_val.hArray=(ptr_t)new std::vector; + break; + default: + assert(false); // unhandled property type + } + } + else + { + switch(uiType & prop_mask::mask_type) + { + case prop_type::type_string: + case prop_type::type_bool: + break; + case prop_type::type_signed_num: + m_range.ll.llLo=_I64_MIN; + m_range.ll.llHi=_I64_MAX; + break; + case prop_type::type_unsigned_num: + m_range.ull.ullLo=0; + m_range.ull.ullHi=_UI64_MAX; + break; + default: + assert(false); // unhandled property type + } + } +} + +/** Sets a property value from a given string. If this is the array property + * type, than the operation is defined by a given action - it either replaces + * all the previous values, or adds at the end or replaces value at a specific + * index. + * + * \param[in] pszValue - value to set (stored in a string) + * \param[in] a - action to take when the property is array-based + * \param[in] tIndex - an index at which to place the value (only meaningful + * for array property type). + */ +void property::set_value(const tchar_t* pszValue, actions a, size_t tIndex) +{ + if (m_uiPropType & prop_flags::flag_array) + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + { + switch(a) + { + case actions::action_replace: + { + m_paStrings->clear(); + m_paStrings->push_back(tstring(pszValue)); + break; + } + case actions::action_add: + { + m_paStrings->push_back(tstring(pszValue)); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paStrings->size()); + + tstring& str=m_paStrings->at(tIndex); + str=pszValue; + break; + } + default: + assert(false); // unhandled action type + } + break; + } + case prop_type::type_bool: + { + switch(a) + { + case actions::action_replace: + { + m_paBools->clear(); + m_paBools->push_back(bool_from_string(pszValue)); + break; + } + case actions::action_add: + { + m_paBools->push_back(bool_from_string(pszValue)); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paBools->size()); + + std::vector::iterator it=m_paBools->begin()+tIndex; + (*it)=bool_from_string(pszValue); + break; + } + default: + assert(false); // unhandled action type + } + break; + } + case prop_type::type_signed_num: + { + switch(a) + { + case actions::action_replace: + { + m_paSigneds->clear(); + m_paSigneds->push_back(signed_from_string(pszValue)); + break; + } + case actions::action_add: + { + m_paSigneds->push_back(signed_from_string(pszValue)); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paSigneds->size()); + + ll_t& ll=m_paSigneds->at(tIndex); + ll=signed_from_string(pszValue); + break; + } + default: + assert(false); // unhandled action type + } + break; + } + case prop_type::type_unsigned_num: + { + switch(a) + { + case actions::action_replace: + { + m_paUnsigneds->clear(); + m_paUnsigneds->push_back(unsigned_from_string(pszValue)); + break; + } + case actions::action_add: + { + m_paUnsigneds->push_back(unsigned_from_string(pszValue)); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paUnsigneds->size()); + + ull_t& ull=m_paUnsigneds->at(tIndex); + ull=unsigned_from_string(pszValue); + break; + } + default: + assert(false); // unhandled action type + } + break; + } + } + } + else + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + { + delete [] m_val.pszVal; + m_val.pszVal=copy_string(pszValue); + break; + } + case prop_type::type_signed_num: + { + m_val.llVal=signed_from_string(pszValue); + break; + } + case prop_type::type_unsigned_num: + { + m_val.ullVal=unsigned_from_string(pszValue); + break; + } + case prop_type::type_bool: + { + m_val.bVal=bool_from_string(pszValue); + break; + } + default: + assert(false); // not implemented? + } + } +} + +/** Retrieves the value as a string. + * + * \param[out] pszString - pointer to a string that will receive the value (could + * be NULL when retrieving string value type) + * \param[in] stMaxSize - size of the buffer (could be 0 for string value retrieval) + * \param[in] stIndex - an index at which to get the value (only meaningful + * for array property type). + * \return Pointer to the string with value. + * \note Always use the returned value as a string pointer - it could be different + * than the one provided as a buffer (in case of retrieving string value). + */ +const tchar_t* property::get_value(tchar_t* pszString, size_t stMaxSize, size_t stIndex) +{ + assert(pszString); + + if (m_uiPropType & prop_flags::flag_array) + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + assert(stIndex < m_paStrings->size()); + return m_paStrings->at(stIndex).c_str(); + break; + case prop_type::type_signed_num: + assert(stIndex < m_paSigneds->size()); + _sntprintf(pszString, stMaxSize, LLFMT, m_paSigneds->at(stIndex)); + break; + case prop_type::type_unsigned_num: + assert(stIndex < m_paUnsigneds->size()); + _sntprintf(pszString, stMaxSize, ULLFMT, m_paUnsigneds->at(stIndex)); + break; + case prop_type::type_bool: + assert(stIndex < m_paBools->size()); + _sntprintf(pszString, stMaxSize, USFMT, (ushort_t)m_paBools->at(stIndex)); + break; + default: + assert(false); + } + } + else + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + return m_val.pszVal; + break; + case prop_type::type_signed_num: + _sntprintf(pszString, stMaxSize, LLFMT, m_val.llVal); + break; + case prop_type::type_unsigned_num: + _sntprintf(pszString, stMaxSize, ULLFMT, m_val.ullVal); + break; + case prop_type::type_bool: + _sntprintf(pszString, stMaxSize, USFMT, (ushort_t)m_val.bVal); + break; + default: + assert(false); + } + } + + return pszString; +} + +/** Sets the string value for this property. + * + * \param[in] pszValue - string to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_string(const tchar_t* pszValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_string); + + if (m_uiPropType & prop_flags::flag_array) + { + switch(a) + { + case actions::action_replace: + { + m_paStrings->clear(); + m_paStrings->push_back(tstring(pszValue)); + break; + } + case actions::action_add: + { + m_paStrings->push_back(tstring(pszValue)); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paStrings->size()); + tstring& str=m_paStrings->at(tIndex); + str=pszValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + { + delete [] m_val.pszVal; + m_val.pszVal=copy_string(pszValue); + } +} + +/** Retrieves the string value type. + * + * \param[in] stIndex - index at which to retrieve value (meaningful only + * for array property type) + * \return Pointer to the string. + */ +const tchar_t* property::get_string(size_t stIndex) const +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_string); + + if (m_uiPropType & prop_flags::flag_array) + { + assert(stIndex < m_paStrings->size()); + return m_paStrings->at(stIndex).c_str(); + } + else + return m_val.pszVal; +} + +/** Sets a signed number property value. + * + * \param[in] llValue - signed number value to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_signed_num(ll_t llValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_signed_num); + + if (m_uiPropType & prop_flags::flag_array) + { + switch(a) + { + case actions::action_replace: + { + m_paSigneds->clear(); + m_paSigneds->push_back(llValue); + break; + } + case actions::action_add: + { + m_paSigneds->push_back(llValue); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paSigneds->size()); + ll_t& ll=m_paSigneds->at(tIndex); + ll=llValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + m_val.llVal=llValue; + + check_range(); +} + +/** Sets the range of the signed number property value. + * + * \param[in] llMin - minimum acceptable value of the property + * \param[in] llMax - maximum acceptable value of the property + */ +void property::set_signed_range(ll_t llMin, ll_t llMax) +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_signed_num); + + // set new range + m_range.ll.llLo=llMin; + m_range.ll.llHi=llMax; + + // check range + check_range(); +} + +/** Retrieves the signed number value. + * + * \param[in] stIndex - index at which to retrieve value (array-based + * property types) + * \return Signed number value. + */ +ll_t property::get_signed_num(size_t stIndex) const +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_signed_num); + + if (m_uiPropType & prop_flags::flag_array) + { + assert(stIndex < m_paSigneds->size()); + return m_paSigneds->at(stIndex); + } + else + return m_val.llVal; +} + +/** Sets an unsigned number property value. + * + * \param[in] ullValue - unsigned number value to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_unsigned_num(ull_t ullValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_unsigned_num); + + if (m_uiPropType & prop_flags::flag_array) + { + switch(a) + { + case actions::action_replace: + { + m_paUnsigneds->clear(); + m_paUnsigneds->push_back(ullValue); + break; + } + case actions::action_add: + { + m_paUnsigneds->push_back(ullValue); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paUnsigneds->size()); + ull_t& ull=m_paUnsigneds->at(tIndex); + ull=ullValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + m_val.ullVal=ullValue; + + check_range(); +} + +/** Sets the range of the unsigned number property value. + * + * \param[in] ullMin - minimum acceptable value of the property + * \param[in] ullMax - maximum acceptable value of the property + */ +void property::set_unsigned_range(ull_t ullMin, ull_t ullMax) +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_unsigned_num); + + // set new range + m_range.ull.ullLo=ullMin; + m_range.ull.ullHi=ullMax; + + // check range + check_range(); +} + +/** Retrieves the unsigned number value. + * + * \param[in] stIndex - index at which to retrieve value (array-based + * property types) + * \return Unsigned number value. + */ +ull_t property::get_unsigned_num(size_t stIndex) const +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_unsigned_num); + + if (m_uiPropType & prop_flags::flag_array) + { + assert(stIndex < m_paUnsigneds->size()); + return m_paUnsigneds->at(stIndex); + } + else + return m_val.ullVal; +} + +/** Sets a bool property value. + * + * \param[in] bValue - bool value to set + * \param[in] a - action to take when property is array-based + * \param[in] tIndex - index at which to replace value in case of item + * replace action (for array-based property types) + */ +void property::set_bool(bool bValue, actions a, size_t tIndex) +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_bool); + + if (m_uiPropType & prop_flags::flag_array) + { + switch(a) + { + case actions::action_replace: + { + m_paBools->clear(); + m_paBools->push_back(bValue); + break; + } + case actions::action_add: + { + m_paBools->push_back(bValue); + break; + } + case actions::action_setat: + { + assert(tIndex < m_paBools->size()); + std::vector::iterator it=m_paBools->begin()+tIndex; + (*it)=bValue; + break; + } + default: + assert(false); // unhandled action type + } + } + else + m_val.bVal=bValue; +} + +/** Retrieves the bool value. + * + * \param[in] stIndex - index at which to retrieve value (array-based + * property types) + * \return Bool value. + */ +bool property::get_bool(size_t stIndex) const +{ + assert((m_uiPropType & prop_mask::mask_type) == prop_type::type_bool); + + if (m_uiPropType & prop_flags::flag_array) + { + assert(stIndex < m_paBools->size()); + return m_paBools->at(stIndex); + } + else + return m_val.bVal; +} + +/** Retrieves the property count for this property. + * + * \return Property count. + */ +size_t property::get_count() const +{ + if (m_uiPropType & prop_flags::flag_array) + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + return m_paStrings->size(); + case prop_type::type_signed_num: + return m_paSigneds->size(); + case prop_type::type_unsigned_num: + return m_paUnsigneds->size(); + case prop_type::type_bool: + return m_paBools->size(); + default: + assert(false); // unhandled property type + return 0; + } + } + else + return 1; +} + +/** Removes a property value at a given index. + * + * \param[in] stIndex - index of value to remove + */ +void property::remove(size_t stIndex) +{ + if (m_uiPropType & prop_flags::flag_array) + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + { + assert(stIndex < m_paStrings->size()); + m_paStrings->erase(m_paStrings->begin()+stIndex); + break; + } + case prop_type::type_signed_num: + { + assert(stIndex < m_paSigneds->size()); + m_paSigneds->erase(m_paSigneds->begin()+stIndex); + break; + } + case prop_type::type_unsigned_num: + { + assert(stIndex < m_paUnsigneds->size()); + m_paUnsigneds->erase(m_paUnsigneds->begin()+stIndex); + break; + } + case prop_type::type_bool: + { + assert(stIndex < m_paBools->size()); + m_paBools->erase(m_paBools->begin()+stIndex); + break; + } + default: + assert(false); // unhandled property type + } + } + else + assert(false); +} + +/** Clears the array property value. + */ +void property::clear_array() +{ + if (m_uiPropType & prop_flags::flag_array) + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + m_paStrings->clear(); + break; + case prop_type::type_signed_num: + m_paSigneds->clear(); + break; + case prop_type::type_unsigned_num: + m_paUnsigneds->clear(); + break; + case prop_type::type_bool: + m_paBools->clear(); + break; + default: + assert(false); // unhandled property type + } + } +} + +/** Completely clears the value part internal members. + * Unallocates all the memory associated with values and sets + * those members to NULL. + */ +void property::clear_value() +{ + if (m_uiPropType & prop_flags::flag_array) + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + delete m_paStrings; + break; + case prop_type::type_signed_num: + delete m_paSigneds; + break; + case prop_type::type_unsigned_num: + delete m_paUnsigneds; + break; + case prop_type::type_bool: + delete m_paBools; + break; + default: + assert(false); // unhandled property type + } + + m_val.hArray=NULL; + } + else + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_string: + delete [] m_val.pszVal; + m_val.pszVal=NULL; + break; + case prop_type::type_signed_num: + m_val.llVal=0LL; + break; + case prop_type::type_unsigned_num: + m_val.ullVal=0ULL; + break; + case prop_type::type_bool: + m_val.bVal=false; + break; + default: + assert(false); // not implemented? + } + } +} + +/** Function corrects the property value(s) based on the provided + * property value range. + */ +void property::check_range() +{ + if (m_uiPropType & prop_flags::flag_array) + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_signed_num: + { + for (std::vector::iterator it=m_paSigneds->begin();it != m_paSigneds->end();it++) + { + if ((*it) < m_range.ll.llLo) + (*it)=m_range.ll.llLo; + else if ((*it) > m_range.ll.llHi) + (*it)=m_range.ll.llHi; + } + break; + } + case prop_type::type_unsigned_num: + { + for (std::vector::iterator it=m_paUnsigneds->begin();it != m_paUnsigneds->end();it++) + { + if ((*it) < m_range.ull.ullLo) + (*it)=m_range.ull.ullLo; + else if ((*it) > m_range.ull.ullHi) + (*it)=m_range.ull.ullHi; + } + break; + } + } + } + else + { + switch(m_uiPropType & prop_mask::mask_type) + { + case prop_type::type_signed_num: + { + // check range + if (m_val.llVal < m_range.ll.llLo) + m_val.llVal=m_range.ll.llLo; + else if (m_val.llVal > m_range.ll.llHi) + m_val.llVal=m_range.ll.llHi; + break; + } + case prop_type::type_unsigned_num: + { + // check range + if (m_val.ullVal < m_range.ull.ullLo) + m_val.ullVal=m_range.ull.ullLo; + else if (m_val.ullVal > m_range.ull.ullHi) + m_val.ullVal=m_range.ull.ullHi; + break; + } + default: + assert(false); // need to be implemented + } + } +} + +/** Makes a copy of a given string with allocating the necessary memory. + * + * \param[in] pszSrc - a source string + * \return Pointer to a newly allocated memory with new string + */ +tchar_t* property::copy_string(const tchar_t* pszSrc) +{ + if (pszSrc) + { + tchar_t *psz=new tchar_t[_tcslen(pszSrc)+1]; + _tcscpy(psz, pszSrc); + return psz; + } + else + return NULL; +} + +/** Converts a string to a boolean value. + * + * \param[in] pszSrc - string to convert + * \return Converted value. + */ +bool property::bool_from_string(const tchar_t* pszSrc) +{ + assert(pszSrc); + return pszSrc[0] != _t('0'); +} + +/** Converts a string to a signed number value. + * + * \param[in] pszSrc - string to convert + * \return Converted value. + */ +ll_t property::signed_from_string(const tchar_t* pszSrc) +{ +#if defined(_WIN32) || defined(_WIN64) + return _ttoi64(pszSrc); +#else + return atoll(pszSrc); +#endif +} + +/** Converts a string to an unsigned number value. + * + * \param[in] pszSrc - string to convert + * \return Converted value. + */ +ull_t property::unsigned_from_string(const tchar_t* pszSrc) +{ + // currently does not support full range of unsigned long long + // since there are no (?) function to convert string to ull_t +#if defined(_WIN32) || defined(_WIN64) + return _ttoi64(pszSrc); +#else + return atoll(pszSrc); +#endif +} + +END_ICPF_NAMESPACE Index: ext/libicpf/src/config_property.h =================================================================== diff -u -N --- ext/libicpf/src/config_property.h (revision 0) +++ ext/libicpf/src/config_property.h (revision 771dac1fbb7608aa92942c6cab7c5c8b0cccb791) @@ -0,0 +1,161 @@ +#ifndef __CONFIGPROPERTY_H__ +#define __CONFIGPROPERTY_H__ + +#include "gen_types.h" +#include "libicpf.h" + +BEGIN_ICPF_NAMESPACE + +/** \brief Basic property description class. + */ +class LIBICPF_API property +{ +public: + /// Masks identifiers for property type + enum prop_mask + { + mask_type=0x0000ffff, ///< Property type mask + mask_flags=0xffff0000 ///< Property flags mask + }; + + /// Property type definitions + enum prop_type + { + type_unknown=0x00000001, /// Unknown type (partial synonym of PT_STRING) + type_signed_num=0x00000002, /// Signed 64-bit type property + type_unsigned_num=0x00000003, /// Unsigned 64-bit type property + type_bool=0x00000004, /// Bool type property + type_string=0x00000005 /// String type property + }; + + /// Property flags definitions + enum prop_flags + { + flag_none=0x00000000, /// Standard property flag + flag_path=0x00010000, /// The string specifies a pathname flag + flag_encrypt=0x00040000, /// This flag indicates that the property has been encrypted with a password (only string values) + flag_decoded=0x00080000, /// The property is currently in decrypted state (but should be encrypted when saving) + flag_array=0x00100000, /// Array property type + flag_modified=0x00200000 /// Modification flag + }; + + // actions used by set_xxx() + enum actions + { + action_add, ///< Value should be added + action_replace, ///< Value should replace all previous values + action_setat ///< Value should replace only a specific value + }; +public: +/** \brief Construction/destruction/operators */ +/**@{*/ + property(); ///< Standard constructor + property(const tchar_t* pszName, uint_t uiType); ///< Constructor with initializer + property(const property& src); ///< Copy constructor + ~property(); ///< Standard destructor + + property& operator=(const property& rSrc); ///< Assignment operator +/**@}*/ + +/** \brief Property settings/operations */ +/**@{*/ + /// Resets the internal members + void clear(); + + /// Sets a property type + void init(const tchar_t* pszName, uint_t uiType, bool bClear=true); + /// Retrieves a property type (with flags) + uint_t get_type() const { return m_uiPropType; }; + + /// Sets a property name + void set_name(const tchar_t* pszName) { m_pszName=copy_string(pszName); }; + /// Gets a property name + const tchar_t* get_name() const { return m_pszName; }; + + /// Sets the modified flag + void set_modified(bool bModified) { if (bModified) m_uiPropType |= prop_flags::flag_modified; else m_uiPropType &= ~prop_flags::flag_modified; }; + /// Gets the modified flag + bool is_modified() const { return (m_uiPropType & prop_flags::flag_modified) != false; }; +/**@}*/ + +/** \brief Property values */ +/**@{*/ + /// Sets a value from string + void set_value(const tchar_t* pszValue, actions a=actions::action_replace, size_t tIndex=0); + /// Gets the value as string + const tchar_t* get_value(tchar_t* pszString, size_t stMaxSize, size_t stIndex=0); + + /// Sets the string value + void set_string(const tchar_t* pszValue, actions a=actions::action_replace, size_t tIndex=0); + /// Gets the string value + const tchar_t* get_string(size_t stIndex=0) const; + + /// Sets the signed number value + void set_signed_num(ll_t llValue, actions a=actions::action_replace, size_t tIndex=0); + /// Sets the signed number range + void set_signed_range(ll_t llMin, ll_t llMax); + /// Gets the signed number value + ll_t get_signed_num(size_t stIndex=0) const; + + /// Sets the unsigned number value + void set_unsigned_num(ull_t ullValue, actions a=actions::action_replace, size_t tIndex=0); + /// Sets the unsigned number range + void set_unsigned_range(ull_t ullMin, ull_t ullMax); + /// Gets the unsigned number value + ull_t get_unsigned_num(size_t stIndex=0) const; + + /// Sets the bool value + void set_bool(bool bValue, actions a=actions::action_replace, size_t tIndex=0); + /// Gets the bool value + bool get_bool(size_t stIndex=0) const; + + /// Gets the property count for an array property type + size_t get_count() const; + /// Removes a property at a given index + void remove(size_t stIndex); + /// Clears the array + void clear_array(); +/**@}*/ + +protected: + void clear_value(); ///< Clears the current value (frees any allocated memory) + void check_range(); ///< Performs a range check on the property value + + tchar_t* copy_string(const tchar_t* pszSrc); ///< Makes a copy of a given string + bool bool_from_string(const tchar_t* pszSrc); ///< Retrieves a bool value from a string + ll_t signed_from_string(const tchar_t* pszSrc); ///< Retrieves a signed number from a string + ull_t unsigned_from_string(const tchar_t* pszSrc); ///< Retrieves an unsigned number from a string + +protected: + // basic, common property description + uint_t m_uiPropType; ///< Property type and flags + tchar_t* m_pszName; ///< Name of the property + + // values + union _VALUE /// Union with different types of properties + { + ll_t llVal; ///< Signed number value + ull_t ullVal; ///< Unsigned number value + bool bVal; ///< A bool-type value + tchar_t* pszVal; ///< A string-type value + ptr_t hArray; ///< An array-type value + } m_val; + + union _RANGE /// Union with numeric properties ranges + { + struct LLRANGE + { + ll_t llLo; ///< Minimum allowed value for the longlong_t property + ll_t llHi; ///< Maximum allowed value for the longlong_t property + } ll; + struct ULLRANGE + { + ull_t ullLo; ///< Minimum allowed value for the ull_t property + ull_t ullHi; ///< Maximum allowed value for the ull_t property + } ull; + } m_range; +}; + +END_ICPF_NAMESPACE + +#endif