#include "citem.h"
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
using namespace cfg;
//-------------------------------------------------------------------
//! конвертация строки в число изменит ок только при удаче
template<class T,bool check_neg>
static T build_T(const char *buf,bool &ok)
{
T ret = 0;
bool is_neg = false;
T over_v = 0;
for(const char *pbuf=buf;*pbuf;++pbuf){
if(check_neg && pbuf==buf){
is_neg = (*pbuf=='-');
if(is_neg) continue;
}
if(!isdigit(*pbuf))
return 0;
else{
ret = ret*10+(*pbuf-48);
if(ret < over_v) //попытка отловить переполнение
return 0;
over_v = ret;
}
}
if(check_neg && is_neg) ret*=(-1);
ok = true;
return ret;
}
struct CItem::sItemData {
bool m_empty;
std::string m_name;
std::string m_data;
void setNotEmpty() {
m_empty = false;
}
sItemData():
m_empty( true )
{}
sItemData( const std::string &name, const std::string &data ):
m_empty( false ),
m_name( name ),
m_data( data )
{}
};
//-------------------------------------------------------------------
CItem::CItem()
{
m_data = new sItemData;
}
//-------------------------------------------------------------------
CItem::CItem( const std::string &name, const std::string &data )
{
m_data = new sItemData( name, data );
}
//-------------------------------------------------------------------
CItem::~CItem()
{
delete m_data;
}
//-------------------------------------------------------------------
const std::string CItem::getName() const
{
return m_data->m_name;
}
//-------------------------------------------------------------------
void CItem::setData( const std::string &data )
{
m_data->m_data = data;
}
//-------------------------------------------------------------------
const std::string CItem::toString() const
{
return m_data->m_data;
}
//-------------------------------------------------------------------
int CItem::toInt( bool &ok ) const
{
ok = false;
return m_data->m_data.size() ? build_T<int,true> (m_data->m_data.c_str(),ok) : 0;;
}
//-------------------------------------------------------------------
unsigned CItem::toUInt( bool &ok ) const
{
ok = false;
return m_data->m_data.size() ? build_T<unsigned,false> (m_data->m_data.c_str(),ok) : 0;
}
//-------------------------------------------------------------------
long CItem::toLong( bool &ok ) const
{
ok = false;
return m_data->m_data.size() ? build_T<long,false> (m_data->m_data.c_str(),ok) : 0;
}
//-------------------------------------------------------------------
unsigned long CItem::toULong( bool &ok ) const
{
ok = false;
return m_data->m_data.size() ? build_T<unsigned long,false> (m_data->m_data.c_str(),ok) : 0;
}
//-------------------------------------------------------------------
float CItem::toFloat( bool &ok ) const
{
float ret = 0.0;
std::string::size_type pos;
if( m_data->m_data.size() ) {
if ( std::string::npos != ( pos = m_data->m_data.find( ',' ) ) )
m_data->m_data[pos] = '.';
errno = 0;
ret = strtof( m_data->m_data.c_str(), 0 );
ok = ( 0 == errno );
}else
ok = false;
return ret;
}
//-------------------------------------------------------------------
double CItem::toDouble( bool &ok ) const
{
double ret = 0.0;
std::string::size_type pos;
if( m_data->m_data.size() ) {
if ( std::string::npos != ( pos = m_data->m_data.find( ',' ) ) )
m_data->m_data[pos] = '.';
errno = 0;
ret = strtod( m_data->m_data.c_str(), 0 );
ok = ( 0 == errno );
}else
ok = false;
return ret;
}
//-------------------------------------------------------------------
bool CItem::empty() const
{
return m_data->m_empty;
}
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------------------------------------------------
CItemTree::~ CItemTree()
{
delete m_data;
std::map< std::string, CItemTree * >::iterator it,
it_e = m_items.end();
for ( it = m_items.begin(); it != it_e; ++it ) {
delete it->second;
it->second = 0;
}
}
//-------------------------------------------------------------------
bool CItemTree::addItem( CItemTree *item )
{
if ( !m_isNode )
return false;
m_items[ item->m_name ] = item;
printf("add item name=%s\n", item->m_name.c_str());
return true;
}
//-------------------------------------------------------------------
bool CItemTree::addNode( CItemTree *item )
{
item->setIsNode();
printf("add node name=%s\n", item->m_name.c_str());
return addItem( item );
}
//-------------------------------------------------------------------
bool CItemTree::setData( CItem *item )
{
if ( m_isNode )
return false;
m_data = item;
m_name = item->getName();
return true;
}
//-------------------------------------------------------------------
CItemTree* CItemTree::getItem( const std::string &name )
{
std::map< std::string, CItemTree* >::iterator
it = m_items.find( name );
if ( m_items.end() == it ) {
printf("not found item name=%s\n", name.c_str() );
return NULL;
}
return it->second;
}
//-------------------------------------------------------------------
const CItemTree* CItemTree::getNode( const std::string &name ) const
{
std::map< std::string, CItemTree* >::const_iterator
it = m_items.find( name );
if ( m_items.end() == it )
return NULL;
return it->second;
}
//-------------------------------------------------------------------
bool CItemTree::empty() const
{
if ( m_isNode )
return m_items.empty();
return ( 0 == m_data );
}
//-------------------------------------------------------------------
评论0