This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Cross-platform Property Set Submitted by

Yes, this is yet another property set for storing configuration parameters and values sorted by keys. Features include: OOP, file mode constraints for handling an existing config file, a flexible configuration format that can change, support for bool, char, short, int, long, float, double, and string values, automatic type conversions between values, a separate state-machine based config file parser that can ignore white space, separate property set file writer, support for multiple values per parameter, parameter default values, informational comments for parameters, and it's easy to use :) Here's an example of the interface:

    cPropertySet config ( "config.cfg" );

    // key, parameter name, value, multi-value index
    config.SetString ( "key", "param1", "my string value" );

    // multi-value
    config.SetString ( "multiplayer", "server1", "http://www.kickass.com" );
    config.SetString ( "multiplayer", "server1", "24/7 multiplayer madness!", 1 );
    config.SetShort ( "multiplayer", "server1", 27910, 2 );
    config.SetBool ( "multiplayer", "server1", true, 3 );
    config.SetShort ( "multiplayer", "server1", 10, 4 );

That could represent address, name, port, ping at startup, connect retry... The default config file format:

    # Comment line
    # These comments are associated with the key below
    [ Foo ]

    # This comment is for the next param
    param1 = some long string for this param

    # This is a multi-value param
    # and values can be empty
    multi value param = ; value 2; ; value 4; ; value6

The code has been compiled successfully with MSVC++ 6.0 and GCC 2.96. I've tested the reading, writing, and some string conversion so far and I worked out quite a few bugs. Of course, anything that pops up please email me. I'm currently putting together a more complete regression test suit for automatic testing so that can be an update. I just hope this can be of use to anyone. I worked on this code for the Open Racer Project to replace some TCL and lots of macro code. Hopefully this code will find a home there :)

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_string_conv.hpp] - (2,317 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    /*********************************************************************************************
    *	Class:		cStringConverter
    *
    *	Purpose:	This class converts strings to values.
    *
    *	Notes:
    *
    *	This class attempts to convert a string to the requested value.
    *
    *	For bool, a value of "0" or "false" is considered false,
    *	any non-zero value or "true" is considered true.
    *	For char, the first character of the string is returned or '\0' if empty.
    *	For all other values, the value is converted or first character's
    *	value is used, 0 if empty.
    *
    *	FIXME:	1. Add logging for conversions that don't make sense
    *
    *	Author:	Robert Farrell
    *	Email:	farrellr@accis.edu
    *
    *	History:
    *	12/18/2001	Initial version.
    *********************************************************************************************/
    #ifndef _STRING_CONVERTER_HPP
    #define _STRING_CONVERTER_HPP

    #include <sstream>

    using std::stringstream;
    using std::string;

    class cStringConverter
    {
    public:
    	cStringConverter ( string &s );
    	cStringConverter ();
    	virtual ~cStringConverter ();

    	void	SetString ( string &s );

    	bool	ToBool ();
    	char	ToChar ();
    	short	ToShort ();
    	int		ToInt ();
    	long	ToLong ();
    	float	ToFloat ();
    	double	ToDouble ();

    private:
    	string *			m_string;
    	static stringstream	m_temp;
    };
    #endif // _STRING_CONVERTER_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_config.hpp] - (3,380 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    /*********************************************************************************************
    *	Class:		cPropertySetConfig
    *
    *	Purpose:	A property set config file tracks the tokens used to parse a property set file.
    *
    *	Notes:
    *
    *	The tokens are as follows:
    *	key string is <m_key_start> any text <m_key_end>
    *	parameter string is <m_line_end> parameter name <m_assign>
    *	value string is <m_assign> value <m_multi_value> value <m_multi_value> ... <m_line_end>
    *	an information string is <m_info_start> any text <m_line_end>
    *
    *	the defaults:
    *	m_info_start	= '#'
    *	m_line_end		= '\n'
    *	m_assign			= '='
    *	m_key_start		= '['
    *	m_key_end		= ']'
    *	m_multi_value	= ';'
    *
    *	File Mode:
    *	When a property set is opened, the rules are used to determine how
    *	an existing file of the same name is handled
    *
    *	Author:	Robert Farrell
    *	Email:	farrellr@accis.edu
    *
    *	History:
    *	12/18/2001	Initial version.
    *********************************************************************************************/
    #ifndef _PROPERTY_SET_CONFIG_HPP
    #define _PROPERTY_SET_CONFIG_HPP

    #include "ps_exception.hpp"
    #include <string>

    using std::string;

    class cPropertySetConfig
    {
    public:
    	cPropertySetConfig ();
    	virtual ~cPropertySetConfig ();

    	enum eFileMode {	EXISTS_OVERWRITE_OR_CREATE,
    						EXISTS_OVERWRITE_OR_FAIL,
    						EXISTS_FAIL_OR_CREATE };

    	// Exceptions
    	class cInvalidFileMode;

    	char	GetAssignSymbol () const;
    	void	SetAssignSymbol ( const char assign );

    	char	GetKeyStartDelim () const;
    	void	SetKeyStartDelim ( const char start );

    	char	GetKeyEndDelim () const;
    	void	SetKeyEndDelim ( const char end );

    	char	GetLineEndDelim () const;
    	void	SetLineEndDelim ( const char end );

    	char	GetInfoStartDelim () const;
    	void	SetInfoStartDelim ( const char start );

    	char	GetMultiValueDelim () const;
    	void	SetMultiValueDelim ( const char multi );

    	eFileMode	GetFileMode () const;
    	void		SetFileMode ( const eFileMode mode );

    	void		SetFileName ( const string &filename );
    	string		GetFileName () const;

    private:
    	char		m_assign;
    	char		m_key_start;
    	char		m_key_end;
    	char		m_line_end;
    	char		m_info_start;
    	char		m_multi_value;
    	eFileMode	m_file_mode;
    	string		m_filename;
    };

    class cPropertySetConfig::cInvalidFileMode : public cPropertyException
    {
    public:
    	cInvalidFileMode ( string msg );
    };
    #endif // _PROPERTY_SET_CONFIG_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_property_set.cpp] - (17,791 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_property_set.hpp"
    #include "ps_reader.hpp"
    #include "ps_writer.hpp"
    #include <utility>

    using std::make_pair;
    using std::ios;

    cPropertySet::cPropertySet ( const string &filename,
    							 const cPropertySetConfig::eFileMode mode )
    {
    	config.SetFileName ( filename );
    	config.SetFileMode ( mode );

    	cPropertySetReader reader ( *this );
    	reader.Read ();
    }

    cPropertySet::~cPropertySet ()
    {
    	cPropertySetWriter writer ( *this );
    	writer.Write ();

    	Destroy ();
    }

    void cPropertySet::Clear ()
    {
    	std::multimap < string, cMultiProperty >::iterator key;

    	for ( key = m_property_set.begin (); key != m_property_set.end (); ++key )
    		key->second.Clear ();
    }

    void cPropertySet::Destroy ()
    {
    	std::multimap < string, cMultiProperty >::iterator key;

    	for ( key = m_property_set.begin (); key != m_property_set.end (); ++key )
    		key->second.Destroy ();
    }

    unsigned short cPropertySet::NumValues ( const string &key, const string &name )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0;

    	else
    	{
    		cMultiProperty * p = RetrieveMultiProperty ( key, name );
    		return p->NumValues ();
    	}
    }

    bool cPropertySet::IsValidValueIndex (	const string &key,
    										const string &name,
    										const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return false;

    	else
    	{
    		cMultiProperty * p = RetrieveMultiProperty ( key, name );
    		return p->IsValidIndex ( index );
    	}
    }

    void
    cPropertySet::SetBool ( const string &key,
    						const string &name,
    						const bool value,
    						const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetBool ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetBool ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetChar ( const string &key,
    						const string &name,
    						const char value,
    						const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetChar ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetChar ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetShort ( const string &key,
    						 const string &name,
    						 const short value,
    						 const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetShort ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetShort ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetInt (	const string &key,
    						const string &name,
    						const int value,
    						const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetInt ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetInt ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetLong ( const string &key,
    						const string &name,
    						const long value,
    						const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetLong ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetLong ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetFloat ( const string &key,
    						 const string &name,
    						 const float value,
    						 const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetFloat ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetFloat ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetDouble ( const string &key,
    						  const string &name,
    						  const double value,
    						  const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetDouble ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetDouble ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetString ( const string &key,
    						  const string &name,
    						  const string &value,
    						  const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetString ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetString ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetInfo (	const string &key,
    						const string &name,
    						const string &info )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->Info ( info );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.Info ( info );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetBoolDefault (	const string &key,
    								const string &name,
    								const bool value,
    								const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetBoolDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetBoolDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetCharDefault (	const string &key,
    								const string &name,
    								const char value,
    								const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetCharDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetCharDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetShortDefault (	const string &key,
    								const string &name,
    								const short value,
    								const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetShortDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetShortDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetIntDefault (	const string &key,
    								const string &name,
    								const int value,
    								const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetIntDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetIntDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetLongDefault (	const string &key,
    								const string &name,
    								const long value,
    								const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetLongDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetLongDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetFloatDefault (	const string &key,
    								const string &name,
    								const float value,
    								const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetFloatDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetFloatDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetDoubleDefault ( const string &key,
    								 const string &name,
    								 const double value,
    								 const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetDoubleDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetDoubleDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    void
    cPropertySet::SetStringDefault ( const string &key,
    								 const string &name,
    								 const string &value,
    								 const unsigned short index )
    {
    	// if the param exists, replace the value
    	if ( IsParamExist ( key, name ) )
    	{
    		cMultiProperty * cur = 0;
    		cur = RetrieveMultiProperty ( key, name );
    		cur->SetStringDefault ( value, index );
    	}
    	else
    	{
    		// no need to replace, just add it
    		cMultiProperty cur;
    		cur.Name ( name );
    		cur.SetStringDefault ( value );
    		m_property_set.insert( make_pair ( key, cur ) );
    	}
    }

    bool
    cPropertySet::GetBool ( const string &key,
    						const string &name,
    						const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return false;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetBool ( index );
    }

    char
    cPropertySet::GetChar ( const string &key,
    						const string &name,
    						const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return '\0';

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetChar ( index );
    }

    short
    cPropertySet::GetShort ( const string &key,
    						 const string &name,
    						 const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetShort ( index );
    }

    int
    cPropertySet::GetInt ( const string &key,
    					   const string &name,
    					   const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetInt ( index );
    }

    long
    cPropertySet::GetLong ( const string &key,
    						const string &name,
    						const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetLong ( index );
    }

    float
    cPropertySet::GetFloat ( const string &key,
    						 const string &name,
    						 const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0.0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetFloat ( index );
    }

    double
    cPropertySet::GetDouble ( const string &key,
    						  const string &name,
    						  const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0.0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetDouble ( index );
    }

    string
    cPropertySet::GetString (	const string &key,
    							const string &name,
    							const unsigned short index )
    {
    	// return empty string if key/param doesn't exist
    	if ( !IsParamExist ( key, name ) )
    		return "";

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetString ( index );
    }

    bool
    cPropertySet::GetBoolDefault ( const string &key,
    							   const string &name,
    							   const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return false;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetBoolDefault ( index );
    }

    char
    cPropertySet::GetCharDefault ( const string &key,
    							   const string &name,
    							   const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return '\0';

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetCharDefault ( index );
    }

    short
    cPropertySet::GetShortDefault (  const string &key,
    								 const string &name,
    								 const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetShortDefault ( index );
    }

    int
    cPropertySet::GetIntDefault ( const string &key,
    							  const string &name,
    							  const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetIntDefault ( index );
    }

    long
    cPropertySet::GetLongDefault ( const string &key,
    							   const string &name,
    							   const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetLongDefault ( index );
    }

    float
    cPropertySet::GetFloatDefault ( const string &key,
    							    const string &name,
    							    const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0.0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetFloatDefault ( index );
    }

    double
    cPropertySet::GetDoubleDefault ( const string &key,
    								 const string &name,
    								 const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return 0.0;

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetFloatDefault ( index );
    }

    string
    cPropertySet::GetStringDefault ( const string &key,
    								 const string &name,
    								 const unsigned short index )
    {
    	if ( !IsParamExist ( key, name ) )
    		return "";

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->GetStringDefault ( index );
    }

    string
    cPropertySet::GetInfo ( const string &key,
    						const string &name )
    {
    	// return empty string if key/param doesn't exist
    	if ( !IsParamExist ( key, name ) )
    		return "";

    	cMultiProperty * cur = 0;

    	cur = RetrieveMultiProperty ( key, name );
    	return cur->Info ();
    }

    bool	cPropertySet::IsKeyExist ( const string &key ) const
    {
    	if ( m_property_set.find ( key ) != m_property_set.end () )
    		return true;

    	return false;
    }

    bool	cPropertySet::IsParamExist ( const string &key, const string ¶m )
    {
    	if ( !IsKeyExist ( key ) )
    		return false;

    	std::multimap < string, cMultiProperty >::const_iterator cur_param;

    	// try to find the parameter name using for the sent key
    	for ( cur_param = m_property_set.lower_bound ( key ); cur_param != m_property_set.upper_bound ( key ); ++cur_param )
    	{
    		if ( cur_param->second.Name () == param )
    			return true;
    	}

    	return false;
    }

    cMultiProperty * cPropertySet::RetrieveMultiProperty ( const string &key, const string ¶m )
    {
    	std::multimap < string, cMultiProperty >::iterator cur_param;

    	// try to find the parameter name
    	for ( cur_param = m_property_set.lower_bound ( key ); cur_param != m_property_set.upper_bound ( key ); ++cur_param )
    	{
    		if ( cur_param->second.Name () == param )
    			return &(cur_param->second);
    	}

    	// not there
    	return 0;
    }

    cPropertySet::cFileModeConstraint::cFileModeConstraint ( string msg ) :
    cPropertyException ( msg )
    {
    }

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_config.cpp] - (3,076 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_config.hpp"

    cPropertySetConfig::cPropertySetConfig () :
    m_line_end ( '\n' ),
    m_assign ( '=' ),
    m_key_start ( '[' ),
    m_key_end ( ']' ),
    m_info_start ( '#' ),
    m_multi_value ( ';' ),
    m_file_mode ( EXISTS_OVERWRITE_OR_CREATE ),
    m_filename ( "filename" )
    {
    }

    cPropertySetConfig::~cPropertySetConfig ()
    {
    }

    char cPropertySetConfig::GetAssignSymbol () const
    {
    	return m_assign;
    }

    void cPropertySetConfig::SetAssignSymbol ( const char assign )
    {
    	m_assign = assign;
    }

    char cPropertySetConfig::GetKeyStartDelim () const
    {
    	return m_key_start;
    }

    void cPropertySetConfig::SetKeyStartDelim ( const char start )
    {
    	m_key_start = start;
    }

    char cPropertySetConfig::GetKeyEndDelim () const
    {
    	return m_key_end;
    }

    void cPropertySetConfig::SetKeyEndDelim ( const char end )
    {
    	m_key_end = end;
    }

    char cPropertySetConfig::GetLineEndDelim () const
    {
    	return m_line_end;
    }

    void cPropertySetConfig::SetLineEndDelim ( const char end )
    {
    	m_line_end = end;
    }

    char cPropertySetConfig::GetInfoStartDelim () const
    {
    	return m_info_start;
    }

    void cPropertySetConfig::SetInfoStartDelim ( const char start )
    {
    	m_info_start = start;
    }

    char cPropertySetConfig::GetMultiValueDelim () const
    {
    	return m_multi_value;
    }

    void cPropertySetConfig::SetMultiValueDelim ( const char multi )
    {
    	m_multi_value = multi;
    }

    cPropertySetConfig::eFileMode cPropertySetConfig::GetFileMode () const
    {
    	return m_file_mode;
    }

    void cPropertySetConfig::SetFileMode ( const eFileMode mode )
    {
    	switch ( mode )
    	{
    		case EXISTS_OVERWRITE_OR_CREATE:
    		case EXISTS_OVERWRITE_OR_FAIL:
    		case EXISTS_FAIL_OR_CREATE:			m_file_mode = mode; break;

    		default: cInvalidFileMode e ( "Error: Invalid file mode found in cPropertySetConfig::SetFileMode ()" );
    				 throw e;
    	}
    }

    void cPropertySetConfig::SetFileName ( const string &filename )
    {
    	m_filename = filename;
    }

    string cPropertySetConfig::GetFileName () const
    {
    	return m_filename;
    }

    cPropertySetConfig::cInvalidFileMode::cInvalidFileMode ( string msg ) :
    cPropertyException ( msg )
    {
    }

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_value.hpp] - (3,337 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    /*********************************************************************************************
    *	Class:		cPropertyValue
    *
    *	Purpose:	This class stores a type and value.
    *
    *	Notes:
    *
    *	This class offers type conversion from strings to values, and values to strings.
    *	The type changes if Type () is called, or if a Set* () member function is called.
    *	When Get* () is called, a value conversion is performed but the type
    *	remains unchanged.
    *	This class uses cStringConverter for converting strings to values.
    *
    *	Author:	Robert Farrell
    *	Email:	farrellr@accis.edu
    *
    *	History:
    *	12/18/2001	Initial version.
    *********************************************************************************************/
    #ifndef _PROPERTY_VALUE_HPP
    #define _PROPERTY_VALUE_HPP

    #include "ps_exception.hpp"
    #include "ps_string_conv.hpp"
    #include <string>

    using std::string;

    class cPropertyValue
    {
    public:
    	typedef union property_value
    	{
    		bool	bool_val;
    		char	char_val;
    		short	short_val;
    		int		int_val;
    		long	long_val;
    		float	float_val;
    		double	double_val;
    	} property_value_t;

    	enum eValueType {	PV_BOOL,
    						PV_CHAR,
    						PV_SHORT,
    						PV_INT,
    						PV_LONG,
    						PV_FLOAT,
    						PV_DOUBLE,
    						PV_STRING,
    						PV_NONE };

    	// Exceptions
    	class cInvalidValueType;

    	cPropertyValue ( const eValueType type );
    	cPropertyValue ();
    	virtual ~cPropertyValue ();

    	eValueType	Type () const;
    	void		Type ( const eValueType type );

    	bool	GetBool ();
    	void	SetBool ( const bool value );
    	char	GetChar ();
    	void	SetChar ( const char value );
    	short	GetShort ();
    	void	SetShort ( const short value );
    	int		GetInt ();
    	void	SetInt ( const int value );
    	long	GetLong ();
    	void	SetLong ( const long value );
    	float	GetFloat ();
    	void	SetFloat ( const float value );
    	double	GetDouble ();
    	void	SetDouble ( const double value );
    	string	GetString ();
    	void	SetString ( const string value );

    	// sets type to PV_NONE, empty string, 0 for all values
    	void	Clear ();

    private:
    	bool	IsValidType ( const eValueType type );

    private:
    	eValueType				m_type;
    	property_value_t		m_value;
    	string					m_string;
    	static cStringConverter	m_conv;
    };

    class cPropertyValue::cInvalidValueType : public cPropertyException
    {
    public:
    	cInvalidValueType ( string msg );
    };
    #endif // _PROPERTY_VALUE_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_reader.hpp] - (6,276 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    /*********************************************************************************************
    *	Class:		cPropertySetReader
    *
    *	Purpose:	Parses a property set file and stores data in a cPropertySet.
    *
    *	Notes:		A simple state machine is used to parse the input file:
    *
    *				info		param-start	key		key-end		param	value		multi-value
    * -------------------------------------------------------------------------------------------
    * info-start	info		info		key		error		error	value		multi-value
    * key-start		info		key			key		error		error	value		multi-value
    * key-end		info		error		key-end	error		error	value		multi-value
    * line-end		param-start	param-start	key		param-start	error	param-start	param-start
    * assign		info		error		key		error		value	value		multi-value
    * non-white		info		param		key		error		param	value		multi-value
    * white space	info		param-start	key		key-end		param	value		multi-value
    * multi-value	info		error		key		error		error	multi-value	multi-value
    *
    * ProcessEOF ()
    * After we encounter EOF the accepting states are:
    * PARAM_START
    * KEY_END
    *
    * non-accepting states are:
    * KEY
    * INFO
    * VALUE
    * MULTI_VALUE
    * PARAM
    * PARSE_ERROR
    *
    *	This class uses the state machine in the following way:
    *	Info is processed by stripping the M_INFO_START delimiter from the string and
    *	accumulating the string in the vector m_cur_multi_info. The vector holds single
    *	lines of a multi-line comment. Info is associated with a key when a key
    *	is processed or for a parameter when a value or multi-value is processed.
    *
    *	Keys are processed when M_LINE_END is reached and in KEY_END state. Any comment before
    *	the key is stored in the property set as key=keyname, param=keyname.
    *	All keys are stored as key=keyname, param=keyname.
    *	Key delimiters are stripped from the key.
    *
    *	Single value parameters are processed when a token is M_LINE_END and
    *	the current state is VALUE. Any info comment is associated with the param name,
    *	and the key/value pair is added to the property set.
    *
    *	Multi-valued parameters are processed when a token is M_LINE_END and
    *	the current state is MULTI_VALUE. As each M_MULTI_VALUE token is encountered, the
    *	current value is pushed into the vector, when M_LINE_END is reached, each value in
    *	the vector is added to the property set. Any info is associated with the param name.
    *
    *	Attempts to recover from parsing errors are to skip the line in the file that caused
    *	the error.
    *
    *	FIXME:	1. Currently if info is not textually before a key or parameter, info is not saved.
    *			3. M_LINE_END in info comments are preserved.
    *			4. This class doesn't check for "orphaned" parameters, i.e., all parameters must
    *			come after a key, this class just sets up a key of NONE
    *			in case params come before the first key in the file.
    *			5. Class does not throw an exception for any kind of parse error, should it? Can't
    *			really do anything about it if a parse error happens, one less exception to catch...
    *			6. Create a state transition graph and include in documentation.
    *			7. Doesn't handle tabs in comments yet.
    *
    *	Author:	Robert Farrell
    *	Email:	farrellr@accis.edu
    *
    *	History:
    *	12/18/2001	Initial version.
    *	1/8/2002	Properly strips key-start, key-end, and info-start delimiters.
    *				Keys with no parameters are now preserved in the file.
    *********************************************************************************************/
    #ifndef _PROPERTY_SET_READER_HPP
    #define _PROPERTY_SET_READER_HPP

    #include "ps_property_set.hpp"
    #include <fstream>

    using std::fstream;
    using std::string;

    class cPropertySetReader
    {
    public:
    	cPropertySetReader ( cPropertySet &ps );
    	virtual ~cPropertySetReader ();

    	void Read ();

    private:
    	enum eParseState {	INFO,
    						PARAM_START,
    						PARAM,
    						KEY,
    						KEY_END,
    						VALUE,
    						MULTI_VALUE,
    						PARSE_ERROR };

    	char GetNextChar ();
    	void ProcessInfo ( const char token );
    	void ProcessParamStart ( const char token );
    	void ProcessKey ( const char token );
    	void ProcessKeyEnd ( const char token );
    	void ProcessParam ( const char token );
    	void ProcessValue ( const char token );
    	void ProcessMultiValue ( const char token );
    	void ProcessEOF ();
    	void ProcessError ();

    	// returns false if hit EOF before skipping line
    	bool SkipLine ();

    	// utility
    	void TrimWhiteSpace ( string &toTrim );

    	// combines all multi-line info comments into a single string
    	string	MergeMultiInfo ();

    #ifdef _DEBUG
    	void DisplayKeyParamValueInfo ();
    	void DisplayMultiValues ();
    #endif // _DEBUG

    	// no copying allowed
    	cPropertySetReader ( const cPropertySetReader & );
    	cPropertySetReader & operator= ( const cPropertySetReader & );

    private:
    	cPropertySet *		m_property_set;
    	fstream				m_in;
    	eParseState			m_cur_state;
    	eParseState			m_prev_state;	// when a PARSE_ERROR occurs, this is set, otherwise ignored
    	string				m_cur_key;
    	string				m_cur_param;
    	string				m_cur_value;
    	string				m_cur_info;
    	std::vector<string>	m_cur_multi_values;
    	std::vector<string>	m_cur_multi_info;
    	const char			M_INFO_START;
    	const char			M_KEY_START;
    	const char			M_KEY_END;
    	const char			M_LINE_END;
    	const char			M_ASSIGN;
    	const char			M_MULTI_VALUE;
    };
    #endif // _PROPERTY_SET_READER_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/main.cpp] - (1,678 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_property_set.hpp"

    #include <iostream>

    using std::exception;
    using std::cout;
    using std::endl;

    int main ( void )
    {
    	try
    	{
    		cPropertySet p ( "test_read3.wri" );

    		// add some stuff
    		p.SetString ( "dragon lance", "authors", "tracy hickman" );
    		p.SetString ( "dragon lance", "authors", "margaret weiss", 1 );
    		p.SetChar ( "wee", "my char", 'A' );
    		p.SetChar ( "wee", "my char", 'B', 1 );
    		p.SetString ( "dragon lance characters", "wizard", "fizban" );
    		p.SetString ( "one more key for good measure", "whizbang", "I am whizbang, hear me roar!" );

    		p.config.SetFileName ( "test_write3.wri" );
    	}
    	catch ( exception &e )
    	{
    		cout << e.what () << endl;
    	}

    	return 0;
    }

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_property_set.hpp] - (7,968 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    /*********************************************************************************************
    *	Class:		cPropertySet
    *
    *	Purpose:	To store name/value pairs and name/multi-value pairs sorted by keys.
    *
    *	Notes:
    *
    *	Keys:	Delimiters are not stored in the key, there is no validation.
    *	Parameters:
    *	Values:
    *	Default Values:
    *	Info: Start delimiters are not stored in the info string, there is no validation.
    *
    *	Property set file is read upon construction and saved upon destruction.
    *
    *	Rules for missing keys and/or parameters:
    *	GetBool* () returns false if key or parameter name is not found
    *	GetChar* () returns '\0' if key or parameter name is not found
    *	GetShort* () returns 0 if key or parameter name is not found
    *	GetInt* () returns 0 if key or parameter name is not found
    *	GetLong* () returns 0 if key or parameter name is not found
    *	GetFloat* () returns 0.0 if key or parameter name is not found
    *	GetDouble* () returns 0.0 if key or parameter name is not found
    *	GetString* () returns "" if key or parameter name is not found
    *
    *	FIXME:	1. cPropertySetConfig is read during construction and changes are
    *			only reflected in cPropertySet destruction where the config info
    *			is re-read (pointless to change it unless you want to change the file
    *			the stuff is written to basically). This is as it should be.
    *			2. Add logging for retrieval of missing keys and/or params.
    *			3. Info associated with a key is stored as key=keyname, param=keyname,
    *			there may be a better way to do this.
    *			4. Add a footer variable to store info not associated with any keys
    *			or params that should come at the end of a file.
    *
    *	Author:	Robert Farrell
    *	Email:	farrellr@accis.edu
    *
    *	History:
    *	12/18/2001	Initial version.
    *	1/8/2002	Key-start, key-end and info-start delimiters are not stored in the class.
    *	1/11/2002	IsParamExist and RetrieveMultiProperty now only search the sent key's
    *				parameters rather than all keys and parameters. This caused the first matching
    *				parameter name to be retrieved regardless of the key it was found in.
    *********************************************************************************************/
    #ifndef _PROPERTY_SET_HPP
    #define _PROPERTY_SET_HPP

    #pragma warning( disable:4786 )

    #include "ps_multi_property.hpp"
    #include "ps_config.hpp"
    #include <map>
    #include <fstream>

    using std::fstream;
    using std::string;
    using std::multimap;

    class cPropertySet
    {
    	friend class cPropertySetWriter;

    public:
    	cPropertySetConfig config;

    	// Exceptions
    	class cFileModeConstraint;

    	cPropertySet (	const string &filename,
    					const cPropertySetConfig::eFileMode mode = cPropertySetConfig::EXISTS_OVERWRITE_OR_CREATE );

    	virtual ~cPropertySet ();

    	// calls Clear () for each multi value
    	void	Clear ();

    	// calls Destroy () for each multi value
    	void	Destroy ();
    	bool	IsValidValueIndex ( const string &key, const string &name, const unsigned short index );

    	unsigned short NumValues ( const string &key, const string &name );

    	void	SetBool ( const string &key, const string &name, const bool value, const unsigned short index = 0 );
    	void	SetChar ( const string &key, const string &name, const char value, const unsigned short index = 0 );
    	void	SetShort ( const string &key, const string &name, const short value, const unsigned short index = 0 );
    	void	SetInt ( const string &key, const string &name, const int value, const unsigned short index = 0 );
    	void	SetLong ( const string &key, const string &name, const long value, const unsigned short index = 0 );
    	void	SetFloat ( const string &key, const string &name, const float value, const unsigned short index = 0 );
    	void	SetDouble ( const string &key, const string &name, const double value, const unsigned short index = 0 );
    	void	SetString ( const string &key, const string &name, const string &value, const unsigned short index = 0 );
    	void	SetInfo ( const string &key, const string &name, const string &info );

    	void	SetBoolDefault ( const string &key, const string &name, const bool value, const unsigned short index = 0 );
    	void	SetCharDefault ( const string &key, const string &name, const char value, const unsigned short index = 0 );
    	void	SetShortDefault ( const string &key, const string &name, const short value, const unsigned short index = 0 );
    	void	SetIntDefault ( const string &key, const string &name, const int value, const unsigned short index = 0 );
    	void	SetLongDefault ( const string &key, const string &name, const long value, const unsigned short index = 0 );
    	void	SetFloatDefault ( const string &key, const string &name, const float value, const unsigned short index = 0 );
    	void	SetDoubleDefault ( const string &key, const string &name, const double value, const unsigned short index = 0 );
    	void	SetStringDefault ( const string &key, const string &name, const string &value, const unsigned short index = 0 );

    	bool	GetBool ( const string &key, const string &name, const unsigned short index = 0 );
    	char	GetChar ( const string &key, const string &name, const unsigned short index = 0 );
    	short	GetShort ( const string &key, const string &name, const unsigned short index = 0 );
    	int		GetInt ( const string &key, const string &name, const unsigned short index = 0 );
    	long	GetLong ( const string &key, const string &name, const unsigned short index = 0 );
    	float	GetFloat ( const string &key, const string &name, const unsigned short index = 0 );
    	double	GetDouble ( const string &key, const string &name, const unsigned short index = 0 );
    	string	GetString ( const string &key, const string &name, const unsigned short index = 0 );
    	string	GetInfo ( const string &key, const string &name );

    	bool	GetBoolDefault ( const string &key, const string &name, const unsigned short index = 0 );
    	char	GetCharDefault ( const string &key, const string &name, const unsigned short index = 0 );
    	short	GetShortDefault ( const string &key, const string &name, const unsigned short index = 0 );
    	int		GetIntDefault ( const string &key, const string &name, const unsigned short index = 0 );
    	long	GetLongDefault ( const string &key, const string &name, const unsigned short index = 0 );
    	float	GetFloatDefault ( const string &key, const string &name, const unsigned short index = 0 );
    	double	GetDoubleDefault ( const string &key, const string &name, const unsigned short index = 0 );
    	string	GetStringDefault ( const string &key, const string &name, const unsigned short index = 0 );

    	bool	IsKeyExist ( const string &key ) const;
    	bool	IsParamExist ( const string &key, const string ¶m );

    private:
    	// returns 0 if not found
    	cMultiProperty * RetrieveMultiProperty ( const string &key, const string ¶m );

    private:
    	std::multimap < string, cMultiProperty >	m_property_set;
    };

    class cPropertySet::cFileModeConstraint : public cPropertyException
    {
    public:
    	cFileModeConstraint ( string msg );
    };
    #endif // _PROPERTY_SET_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_writer.hpp] - (3,370 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    /*********************************************************************************************
    *	Class:		cPropertySetWriter
    *
    *	Purpose:	This class writes a cPropertySet to a file stream.
    *
    *	Notes:		This class assumes that any info that is associated with a key
    *				is stored as key=key name, param=key name.
    *
    *				An example file is the following:
    *
    *				# This is a comment
    *				# This makes it a multi-line comment
    *				# One more line just for kicks
    *
    *				# All info will be associated with the following key
    *				[ First Key ]
    *
    *				# This info is associated with this param
    *				param = foo
    *
    *				# This is a multi-valued param
    *				param1 = foo; bar; baz
    *
    *				# Multi value params can have emtpy values, just put in extra ;'s
    *				# This one has eight values
    *				param2 = ; two;; four;; six; ;
    *
    *				# Any info that is not before a param or key will be lost
    *				# That includes these lines
    *				# Any key without parameters will be lost
    *
    *				This class does not write empty info, key, or param strings.
    *				This class does not write any default values for any parameters.
    *
    *	Author:	Robert Farrell
    *	Email:	farrellr@accis.edu
    *
    *	History:
    *	12/18/2001	Initial version.
    *	1/8/2002	Fixed bug when key had info but no parameters, blank param was written.
    *	1/8/2002	Key delimiters are now written in this class.
    *	1/8/2002	Info start delimiters are now written in this class.
    *********************************************************************************************/
    #ifndef _PROPERTY_SET_WRITER_HPP
    #define _PROPERTY_SET_WRITER_HPP

    #include "ps_property_set.hpp"
    #include <fstream>

    using std::fstream;

    class cPropertySetWriter
    {
    public:
    	cPropertySetWriter ( cPropertySet &ps );
    	virtual ~cPropertySetWriter ();

    	void Write ();

    private:
    	void WriteKey ( const string &key );
    	void WriteInfo ( const string &info );
    	void WriteParam ( const string &name );
    	void WriteMultiProperty ( cMultiProperty &p );

    	// no copying is allowed
    	cPropertySetWriter ( const cPropertySetWriter & );
    	cPropertySetWriter & operator= ( const cPropertySetWriter & );

    private:
    	cPropertySet *	m_property_set;
    	fstream			m_out;
    	const char		M_INFO_START;
    	const char		M_KEY_START;
    	const char		M_KEY_END;
    	const char		M_LINE_END;
    	const char		M_ASSIGN;
    	const char		M_MULTI_VALUE;
    };
    #endif // _PROPERTY_SET_WRITER_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_reader.cpp] - (14,879 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_reader.hpp"
    #include <sstream>

    #ifdef _DEBUG
    #include <iostream>
    using std::cout;
    using std::endl;
    #endif // _DEBUG

    using std::stringstream;
    using std::ios;

    cPropertySetReader::cPropertySetReader ( cPropertySet &ps ) :
    m_property_set ( &ps ),
    m_cur_state ( PARAM_START ),
    m_prev_state ( PARAM_START ),
    M_INFO_START ( ps.config.GetInfoStartDelim () ),
    M_KEY_START ( ps.config.GetKeyStartDelim () ),
    M_KEY_END ( ps.config.GetKeyEndDelim () ),
    M_LINE_END ( ps.config.GetLineEndDelim () ),
    M_ASSIGN ( ps.config.GetAssignSymbol () ),
    M_MULTI_VALUE ( ps.config.GetMultiValueDelim () )
    {
    	// if parameters are found before the first key, they are assigned to this key
    	m_cur_key = "NONE";
    	m_in.unsetf ( ios::skipws );

    	stringstream buffer;
    	string file = ps.config.GetFileName ();

    	// open the file based on the constraints
    	if ( ps.config.GetFileMode () == cPropertySetConfig::EXISTS_OVERWRITE_OR_CREATE )
    	{
    		// attempt to open existing file
    		m_in.open ( file.c_str (), ios::in );
    		if ( !m_in )
    		{
    			// file doesn't exist so create it
    			m_in.clear ();
    			m_in.open ( file.c_str (), ios::out );
    			if ( !m_in )
    			{
    				buffer << "Error: File IO error while attempting to create file: " << file.c_str ();
    				cPropertySet::cFileModeConstraint e ( buffer.str () );
    				throw e;
    			}
    		}
    	}
    	else
    	if ( ps.config.GetFileMode () == cPropertySetConfig::EXISTS_OVERWRITE_OR_FAIL )
    	{
    		// attempt to open existing file
    		m_in.open ( file.c_str (), ios::in );
    		if ( !m_in )
    		{
    			// file doesn't exist so fail
    			buffer << "Error: File IO error while attempting to open existing file: " << file.c_str ();
    			cPropertySet::cFileModeConstraint e ( buffer.str () );
    			throw e;
    		}
    		else
    		{
    			// file exists, so overwrite
    			m_in.close ();
    			m_in.clear ();
    			m_in.open ( file.c_str (), ios::out );
    			if ( !m_in )
    			{
    				// file io error
    				buffer << "Error: File IO error while attempting to overwrite existing file: " << file.c_str ();
    				cPropertySet::cFileModeConstraint e ( buffer.str () );
    				throw e;
    			}
    		}
    	}
    	else
    	if ( ps.config.GetFileMode () == cPropertySetConfig::EXISTS_FAIL_OR_CREATE )
    	{
    		// see if the file exists
    		m_in.open ( file.c_str (), ios::in );
    		if ( !m_in )
    		{
    			// file doesn't exist so create it
    			m_in.clear ();
    			m_in.open ( file.c_str (), ios::out );
    			if ( !m_in )
    			{
    				buffer << "Error: File IO error while attempting to create file: " << file.c_str ();
    				cPropertySet::cFileModeConstraint e ( buffer.str () );
    				throw e;
    			}
    		}
    		else
    		{
    			// file exists, so fail
    			buffer << "Error: File: " << file.c_str () << " exists and should not";
    			cPropertySet::cFileModeConstraint e ( buffer.str () );
    			throw e;
    		}
    	}
    	else
    	{
    		buffer << "Error: File constraint not specified for file: " << file.c_str ();
    		cPropertySet::cFileModeConstraint e ( buffer.str () );
    		throw e;
    	}
    }
    cPropertySetReader::~cPropertySetReader ()
    {
    	m_in.clear ();
    	m_in.close ();
    }

    void cPropertySetReader::Read ()
    {
    	// parse the file char by char until EOF is returned
    	char token = EOF;
    	while ( (token = GetNextChar ()) != EOF )
    	{
    		switch ( m_cur_state )
    		{
    			case INFO:			ProcessInfo ( token );			break;
    			case PARAM_START:	ProcessParamStart ( token );	break;
    			case KEY:			ProcessKey ( token );			break;
    			case KEY_END:		ProcessKeyEnd ( token );		break;
    			case PARAM:			ProcessParam ( token );			break;
    			case VALUE:			ProcessValue ( token );			break;
    			case MULTI_VALUE:	ProcessMultiValue ( token );	break;

    			default: break;
    		}

    		if ( m_cur_state == PARSE_ERROR )
    			ProcessError ();
    	}

    	ProcessEOF ();
    }

    char cPropertySetReader::GetNextChar ()
    {
    	char next = EOF;

    	m_in >> next;
    	return next;
    }

    void cPropertySetReader::ProcessInfo ( const char token )
    {
    	if ( m_cur_state != INFO || !m_property_set )
    		return;

    	m_cur_info += token;

    	if ( token == M_LINE_END )
    	{
    		TrimWhiteSpace ( m_cur_info );
    		m_cur_multi_info.push_back ( m_cur_info );
    		m_cur_info = "";
    		m_cur_state = PARAM_START;
    	}
    }

    void cPropertySetReader::ProcessParamStart ( const char token )
    {
    	if ( m_cur_state != PARAM_START || !m_property_set )
    		return;

    	if ( token == M_INFO_START )
    	{
    		// strip the delimiter by not accumulating it
    		m_cur_state = INFO;
    	}
    	else
    	if ( token == M_KEY_START )
    	{
    		// strip the key delim by discarding the token
    		m_cur_key = "";
    		m_cur_state = KEY;
    	}
    	else
    	if ( token == M_KEY_END )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	if ( token == M_LINE_END )
    	{
    		// do nothing
    	}
    	else
    	if ( token == M_ASSIGN )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	if ( token == ' ' || token == '\t' )
    	{
    		// ignore white space
    	}
    	else
    	if ( token == M_MULTI_VALUE )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	{
    		m_cur_param = token;
    		m_cur_state = PARAM;
    	}
    }

    void cPropertySetReader::ProcessKey ( const char token )
    {
    	if ( m_cur_state != KEY || !m_property_set )
    		return;

    	if ( token == M_KEY_END )
    	{
    		// discard the key-end delimiter token
    		TrimWhiteSpace ( m_cur_key );
    		m_cur_state = KEY_END;
    	}
    	else
    	{
    		m_cur_key += token;
    	}
    }

    void cPropertySetReader::ProcessKeyEnd ( const char token )
    {
    	if ( m_cur_state != KEY_END || !m_property_set )
    		return;

    #ifdef _DEBUG
    	cout << "have end of key..." << endl;
    	DisplayKeyParamValueInfo ();
    #endif // _DEBUG

    	// we have found the end of a key
    	// if there was an informational comment prior to this key
    	// it can be associated with the key in the property set
    	m_cur_info = MergeMultiInfo ();

    	if ( !m_cur_info.empty () )
    		m_property_set->SetInfo ( m_cur_key, m_cur_key, m_cur_info );

    	else
    		m_property_set->SetString ( m_cur_key, m_cur_key, m_cur_info );

    	// clean up
    	m_cur_info = "";

    	if ( token == M_LINE_END )
    	{
    		m_cur_state = PARAM_START;
    	}
    	else
    	if ( token == ' ' || token == '\t' )
    	{
    		// ignore white space
    	}
    	else
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    }

    void cPropertySetReader::ProcessParam ( const char token )
    {
    	if ( m_cur_state != PARAM || !m_property_set )
    		return;

    	if ( token == M_INFO_START )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	if ( token == M_KEY_START )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	if ( token == M_KEY_END )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	if ( token == M_LINE_END )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	if ( token == M_ASSIGN )
    	{
    		// we have come to the end of a parameter name
    		TrimWhiteSpace ( m_cur_param );
    		m_cur_state = VALUE;
    	}
    	else
    	if ( token == M_MULTI_VALUE )
    	{
    		m_prev_state = m_cur_state;
    		m_cur_state = PARSE_ERROR;
    	}
    	else
    	{
    		// accumulate the parameter
    		m_cur_param += token;
    	}
    }

    void cPropertySetReader::ProcessValue ( const char token )
    {
    	if ( m_cur_state != VALUE || !m_property_set )
    		return;

    	if ( token == M_MULTI_VALUE )
    	{
    		TrimWhiteSpace ( m_cur_value );
    		m_cur_multi_values.push_back ( m_cur_value );
    		m_cur_value = "";
    		m_cur_state = MULTI_VALUE;
    	}
    	else
    	if ( token == M_LINE_END )
    	{
    		TrimWhiteSpace ( m_cur_value );

    #ifdef _DEBUG
    		cout << "end of a single value..." << endl;
    		DisplayKeyParamValueInfo ();
    #endif // _DEBUG

    		m_property_set->SetString ( m_cur_key, m_cur_param, m_cur_value );

    		// process the info for this parameter if there is any
    		m_cur_info = MergeMultiInfo ();

    		if ( !m_cur_info.empty () )
    			m_property_set->SetInfo ( m_cur_key, m_cur_param, m_cur_info );

    		// clean up
    		m_cur_info = m_cur_param = m_cur_value = "";
    		m_cur_state = PARAM_START;
    	}
    	else
    	{
    		m_cur_value += token;
    	}
    }

    void cPropertySetReader::ProcessMultiValue ( const char token )
    {
    	if ( m_cur_state != MULTI_VALUE || !m_property_set )
    		return;

    	if ( token == M_MULTI_VALUE )
    	{
    		TrimWhiteSpace ( m_cur_value );
    		m_cur_multi_values.push_back ( m_cur_value );
    		m_cur_value = "";
    	}
    	else
    	if ( token == M_LINE_END )
    	{
    		TrimWhiteSpace ( m_cur_value );
    		m_cur_multi_values.push_back ( m_cur_value );
    		m_cur_value = "";

    		// for each multi value
    		//		set the value to the appropriate index based on the key and param name

    		// if info, write the info to the parameter name

    		// clean up
    		//		reset info, param, and cur value
    		//		delete all multi values

    #ifdef _DEBUG
    		cout << "hit end of multi-value..." << endl;
    #endif // _DEBUG

    		for ( short i = 0; i < m_cur_multi_values.size (); ++i )
    		{

    #ifdef _DEBUG
    			cout << "processing multi-value= " << m_cur_multi_values [ i ] << endl;
    #endif // _DEBUG

    			m_property_set->SetString ( m_cur_key, m_cur_param, m_cur_multi_values [ i ], i );
    		}

    #ifdef _DEBUG
    		DisplayMultiValues ();
    #endif // _DEBUG

    		// if there is info, process it
    		m_cur_info = MergeMultiInfo ();

    		if ( !m_cur_info.empty () )
    			m_property_set->SetInfo ( m_cur_key, m_cur_param, m_cur_info );

    		// clean up
    		m_cur_info = m_cur_param = m_cur_value = "";
    		m_cur_multi_values.erase ( m_cur_multi_values.begin (), m_cur_multi_values.end () );
    		m_cur_state = PARAM_START;
    	}
    	else
    	{
    		m_cur_value += token;
    	}
    }

    void cPropertySetReader::ProcessEOF ()
    {
    	// After we encounter EOF the accepting states are:
    	// PARAM_START
    	// KEY_END

    	// non-accepting states are:
    	// KEY
    	// INFO
    	// VALUE
    	// MULTI_VALUE
    	// PARAM
    	//	PARSE_ERROR
    	switch ( m_cur_state )
    	{
    		// accepting states
    		case PARAM_START:
    		case KEY_END:		return;

    		// non-accepting states
    		case KEY:			// for some reason the key is mangled, can't do anything

    		case INFO:			// we can't associate the info with a key or param name, oh well...

    		case VALUE:			// probably forgot the line end after the param,
    							// finish this off
    							// should be ok after this
    							ProcessValue ( M_LINE_END ); break;

    		case MULTI_VALUE:	// forgot line end after the last param
    							// finish it off
    							ProcessMultiValue ( M_LINE_END ); break;

    		case PARAM:			// missing a value
    							// FIXME: maybe throw an exception with this message

    		case PARSE_ERROR:	;// couldn't recover from an error, oh well...
    	}
    }

    void cPropertySetReader::ProcessError ()
    {
    	// based on the last state we were in, try to recover from the error

    	if ( m_cur_state != PARSE_ERROR )
    		return;

    	if ( m_prev_state == PARAM_START )
    	{
    		// we got a key end symbol or an assign symbol
    		// skip to the end of the line and reset to param start
    		if ( SkipLine () )
    		{
    			m_prev_state = m_cur_state;
    			m_cur_state = PARAM_START;
    		}
    	}
    	else
    	if ( m_prev_state == KEY_END )
    	{
    		// we didn't get a line end or white space
    		// skip to the end of the line and reset to param start
    		if ( SkipLine () )
    		{
    			m_prev_state = m_cur_state;
    			m_cur_state = PARAM_START;
    		}
    	}
    	else
    	if ( m_prev_state == PARAM )
    	{
    		// we can only get an assign symbol, white or non-white space
    		// that means we got a character that can't be part of the param name
    		// the param name is currently invalid so delete it
    		// if there was info associated with this param name delete it since param is invalid
    		// skip to the end of the line and reset to param start

    		m_cur_info = m_cur_param = "";

    		if ( SkipLine () )
    		{
    			m_prev_state = m_cur_state;
    			m_cur_state = PARAM_START;
    		}
    	}

    	// if we couldn't recover we are SOL. Just let ProcessEOF() worry about it.
    }

    bool cPropertySetReader::SkipLine ()
    {

    	bool no_eof = true;
    	char next = '0';

    	while ( (next = GetNextChar ()) != M_LINE_END )
    	{
    		// make sure we didn't hit EOF prematurely
    		if ( next == EOF )
    		{
    			no_eof = false;
    			break;
    		}
    	}

    	return no_eof;
    }

    // utility
    void cPropertySetReader::TrimWhiteSpace ( string &toTrim )
    {
    	// white space is ' ', '\t'
    	// trims leading and trailing whitespace
    	if ( toTrim.empty () )
    		return;

    	// left side
    	while ( !toTrim.empty () && (toTrim.at ( 0 ) == ' ' || toTrim.at ( 0 ) == '\t') )
    		toTrim.erase ( 0, 1 );

    	// right side
    	short pos = toTrim.length () - 1;
    	while ( !toTrim.empty () && (toTrim.at ( pos ) == ' ' || toTrim.at ( pos ) == '\t') )
    	{
    		toTrim.erase ( pos, pos + 1 );
    		--pos;
    	}
    }

    string cPropertySetReader::MergeMultiInfo ()
    {
    	string temp = "";

    	// for every string in m_cur_multi_info, concatenate to a single string
    	for ( short i = 0; i < m_cur_multi_info.size (); ++i )
    		temp += m_cur_multi_info [ i ];

    	// clean up
    	m_cur_multi_info.erase ( m_cur_multi_info.begin (), m_cur_multi_info.end () );

    	return temp;
    }

    #ifdef _DEBUG
    void cPropertySetReader::DisplayKeyParamValueInfo ()
    {
    	cout << "key=" << m_cur_key << endl;
    	cout << "param=" << m_cur_param << endl;
    	cout << "value=" << m_cur_value << endl;
    	cout << "info=";

    	string temp = "";

    	// for every string in m_cur_multi_info, concatenate to a single string
    	for ( short i = 0; i < m_cur_multi_info.size (); ++i )
    		temp += m_cur_multi_info [ i ];

    	cout << temp << endl << endl;
    }

    void cPropertySetReader::DisplayMultiValues ()
    {
    	cout << "key=" << m_cur_key << endl;
    	cout << "param=" << m_cur_param << endl;
    	cout << "info=";

    	string temp = "";

    	short i = 0;
    	// for every string in m_cur_multi_info, concatenate to a single string
    	for ( i = 0; i < m_cur_multi_info.size (); ++i )
    		temp += m_cur_multi_info [ i ];

    	cout << temp << endl;

    	cout << "multi-values=";

    	for ( i = 0; i < m_cur_multi_values.size (); ++i )
    		cout << m_cur_multi_values [ i ] << ',';

    	cout << endl;
    }
    #endif // _DEBUG

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_multi_property.hpp] - (6,965 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    /*********************************************************************************************
    *	Class:	cMultiProperty
    *
    *	Purpose:
    *
    *	This class encapsulates a single property with a parameter name, value, default
    *	value, and informational comment that can have zero or more additional values
    *	associated with it.
    *
    *	Notes:
    *
    *	An example of a multiple value property would be:
    *	server1 = http://www.kickbutt.com; Fragfest 24/7; 34567; 20; true
    *	This might represent the parameter name of server1 with five values
    *	for server_address, server_name, server_port, connect_rety_count,
    *	and ping_on_startup. This way, five values can be associated with the parameter
    *	name: server1.
    *
    *	Each of the multiple property values has a value and a default value.
    *	For a cMultiProperty with a single value, it's represented by index 0.
    *	The multi-values start at index 1. This class guarantees that the total number
    *	of values and default values are always equal.
    *
    *	This class offers no type conversion safety by itself. Type changes occur when
    *	any Set* () member functions are called. A call to a Set* () member function will
    *	cause a corresponding type change for either the default or regular value depending
    *	if Set* () or Set*Default () was called.
    *	For instance, a call to SetBool () will cause a change to the value's type but
    *	will not change the default value's type to cPropertyValue::PV_BOOL.
    *
    *	New values are created in the Set* () and Type () member functions if an index
    *	is sent that is out of range. The new value will be added to next available index.
    *	For instance, if there are 3 values, and a call to SetBool ( true, 3 ) is made,
    *	a new value will be created at m_values [ 3 ]. If a call to SetBool ( true, 10 )
    *	is made and there are only 3 values, the new value is still only added to index 3.
    *
    *	When a Get* () function is called with an index that is out of range, the highest
    *	valid index value is returned.
    *
    *	The types for values and default values are not guaranteed to be the same for
    *	identical indexes. So if Type ( 1 ) is set to PV_INT, TypeDefault ( 1 ) is not
    *	changed and may not be the same (and vice versa). Internally this shouldn't matter
    *	much since type conversions can occur for any value.
    *
    *	Author:	Robert Farrell
    *	Email:	farrellr@accis.edu
    *
    *	History:
    *	12/18/2001	Initial version.
    *********************************************************************************************/
    #ifndef _MULTI_PROPERTY_HPP
    #define _MULTI_PROPERTY_HPP

    #include "ps_value.hpp"
    #include <vector>

    using std::string;

    class cMultiProperty
    {
    public:
    	cMultiProperty ( const cPropertyValue::eValueType type );
    	cMultiProperty ();
    	virtual ~cMultiProperty ();

    	cPropertyValue::eValueType	Type (	const unsigned short index = 0 );
    	void						Type (	const cPropertyValue::eValueType type,
    										const unsigned short index = 0 );

    	cPropertyValue::eValueType	TypeDefault (	const unsigned short index = 0 );
    	void						TypeDefault (	const cPropertyValue::eValueType type,
    												const unsigned short index = 0 );
    	string	Name () const;
    	void	Name ( const string name );
    	string	Info () const;
    	void	Info ( const string info );

    	// values
    	bool	GetBool ( const unsigned short index = 0 );
    	void	SetBool ( const bool value, const unsigned short index = 0 );
    	char	GetChar ( const unsigned short index = 0 );
    	void	SetChar ( const char value, const unsigned short index = 0 );
    	short	GetShort ( const unsigned short index = 0 );
    	void	SetShort ( const short value, const unsigned short index = 0 );
    	int		GetInt ( const unsigned short index = 0 );
    	void	SetInt ( const int value, const unsigned short index = 0 );
    	long	GetLong ( const unsigned short index = 0 );
    	void	SetLong ( const long value, const unsigned short index = 0 );
    	float	GetFloat ( const unsigned short index = 0 );
    	void	SetFloat ( const float value, const unsigned short index = 0 );
    	double	GetDouble ( const unsigned short index = 0 );
    	void	SetDouble ( const double value, const unsigned short index = 0 );
    	string	GetString ( const unsigned short index = 0 );
    	void	SetString ( const string value, const unsigned short index = 0 );

    	// default values
    	bool	GetBoolDefault ( const unsigned short index = 0 );
    	void	SetBoolDefault ( const bool value, const unsigned short index = 0 );
    	char	GetCharDefault ( const unsigned short index = 0 );
    	void	SetCharDefault ( const char value, const unsigned short index = 0 );
    	short	GetShortDefault ( const unsigned short index = 0 );
    	void	SetShortDefault ( const short value, const unsigned short index = 0 );
    	int		GetIntDefault ( const unsigned short index = 0 );
    	void	SetIntDefault ( const int value, const unsigned short index = 0 );
    	long	GetLongDefault ( const unsigned short index = 0 );
    	void	SetLongDefault ( const long value, const unsigned short index = 0 );
    	float	GetFloatDefault ( const unsigned short index = 0 );
    	void	SetFloatDefault ( const float value, const unsigned short index = 0 );
    	double	GetDoubleDefault ( const unsigned short index = 0 );
    	void	SetDoubleDefault ( const double value, const unsigned short index = 0 );
    	string	GetStringDefault ( const unsigned short index = 0 );
    	void	SetStringDefault ( const string value, const unsigned short index = 0 );

    	// sets all property values to cPropertValue::PV_NONE, does not deallocate memory
    	void	Clear ();

    	// deallocates memory for all values, allocates values for index 0
    	void	Destroy ();
    	bool	IsValidIndex ( const unsigned short index ) const;

    	unsigned int NumValues () const;

    private:
    	bool	IsValidDefaultIndex ( const unsigned short index ) const;
    	void	AllocateValue ( const cPropertyValue::eValueType type = cPropertyValue::PV_NONE );

    private:
    	string							m_name;
    	string							m_info;
    	std::vector < cPropertyValue >	m_values;
    	std::vector < cPropertyValue >	m_defaults;
    };
    #endif // _MULTI_PROPERTY_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_value.cpp] - (5,001 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_value.hpp"

    using std::stringstream;

    cStringConverter cPropertyValue::m_conv;

    cPropertyValue::cPropertyValue (	const eValueType type )
    {
    	Type ( type );
    }

    cPropertyValue::cPropertyValue () :
    m_type ( PV_NONE )
    {
    	m_value.bool_val	= 0;
    	m_value.double_val	= 0;
    	m_value.float_val	= 0;
    }

    cPropertyValue::~cPropertyValue ()
    {
    }

    cPropertyValue::eValueType cPropertyValue::Type () const
    {
    	return m_type;
    }

    void cPropertyValue::Type ( const eValueType type )
    {
    	if ( !IsValidType ( type ) )
    	{
    		cInvalidValueType e ( "Error: Invalid type sent to cPropertyValue::Type ()" );
    		throw e;
    	}

    	m_type = type;
    }

    bool cPropertyValue::IsValidType ( const eValueType type )
    {
    	switch ( type )
    	{
    		case PV_BOOL:
    		case PV_CHAR:
    		case PV_SHORT:
    		case PV_INT:
    		case PV_LONG:
    		case PV_FLOAT:
    		case PV_DOUBLE:
    		case PV_STRING:
    		case PV_NONE:	return true;

    		default: return false;
    	}
    }

    bool cPropertyValue::GetBool ()
    {
    	if ( m_type == PV_STRING )
    	{
    		m_conv.SetString ( m_string );
    		return m_conv.ToBool ();
    	}
    	else
    	{
    		return m_value.bool_val;
    	}
    }

    void cPropertyValue::SetBool ( const bool value )
    {
    	Type ( PV_BOOL );
    	m_value.bool_val = value;
    }

    char cPropertyValue::GetChar ()
    {
    	if ( m_type == PV_STRING )
    	{
    		m_conv.SetString ( m_string );
    		return m_conv.ToChar ();
    	}
    	else
    	{
    		return m_value.char_val;
    	}
    }

    void cPropertyValue::SetChar ( const char value )
    {
    	Type ( PV_CHAR );
    	m_value.char_val = value;
    }

    short cPropertyValue::GetShort ()
    {
    	if ( m_type == PV_STRING )
    	{
    		m_conv.SetString ( m_string );
    		return m_conv.ToShort ();
    	}
    	else
    	{
    		return m_value.short_val;
    	}
    }

    void cPropertyValue::SetShort ( const short value )
    {
    	Type ( PV_SHORT );
    	m_value.short_val = value;
    }

    int cPropertyValue::GetInt ()
    {
    	if ( m_type == PV_STRING )
    	{
    		m_conv.SetString ( m_string );
    		return m_conv.ToInt ();
    	}
    	else
    	{
    		return m_value.int_val;
    	}
    }

    void cPropertyValue::SetInt ( const int value )
    {
    	Type ( PV_INT );
    	m_value.int_val = value;
    }

    long cPropertyValue::GetLong ()
    {
    	if ( m_type == PV_STRING )
    	{
    		m_conv.SetString ( m_string );
    		return m_conv.ToLong ();
    	}
    	else
    	{
    		return m_value.long_val;
    	}
    }

    void cPropertyValue::SetLong ( const long value )
    {
    	Type ( PV_LONG );
    	m_value.long_val = value;
    }

    float cPropertyValue::GetFloat ()
    {
    	if ( m_type == PV_STRING )
    	{
    		m_conv.SetString ( m_string );
    		return m_conv.ToFloat ();
    	}
    	else
    	{
    		return m_value.float_val;
    	}
    }

    void cPropertyValue::SetFloat ( const float value )
    {
    	Type ( PV_FLOAT );
    	m_value.float_val = value;
    }

    double cPropertyValue::GetDouble ()
    {
    	if ( m_type == PV_STRING )
    	{
    		m_conv.SetString ( m_string );
    		return m_conv.ToDouble ();
    	}
    	else
    	{
    		return m_value.double_val;
    	}
    }

    void cPropertyValue::SetDouble ( const double value )
    {
    	Type ( PV_DOUBLE );
    	m_value.double_val = value;
    }

    string cPropertyValue::GetString ()
    {
    	if ( m_type == PV_STRING )
    	{
    		return m_string;
    	}
    	else
    	{
    		// convert the value
    		stringstream temp;
    		temp.str ( "" );

    		switch ( m_type )
    		{
    			case PV_BOOL:	temp << m_value.bool_val;		break;
    			case PV_CHAR:	temp << m_value.char_val;		break;
    			case PV_SHORT:	temp << m_value.short_val;		break;
    			case PV_INT:	temp << m_value.int_val;		break;
    			case PV_LONG:	temp << m_value.long_val;		break;
    			case PV_FLOAT:	temp << m_value.float_val;		break;
    			case PV_DOUBLE:	temp << m_value.double_val;	break;
    			case PV_NONE:	return m_string;

    			default: break;
    		}

    		return temp.str ();
    	}
    }

    void cPropertyValue::SetString ( const string value )
    {
    	Type ( PV_STRING );
    	m_string = value;
    }

    void cPropertyValue::Clear ()
    {
    	Type ( PV_NONE );
    	m_string = "";
    	m_value.bool_val	= 0;
    	m_value.double_val	= 0;
    	m_value.float_val	= 0;
    }

    cPropertyValue::cInvalidValueType::cInvalidValueType ( string msg ) :
    cPropertyException ( msg )
    {
    }

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_writer.cpp] - (6,906 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_writer.hpp"

    #ifdef _DEBUG
    #include <iostream>
    using std::cout;
    using std::endl;
    #endif // _DEBUG

    using std::ios;

    cPropertySetWriter::cPropertySetWriter ( cPropertySet &ps ) :
    m_property_set ( &ps ),
    M_INFO_START ( ps.config.GetInfoStartDelim () ),
    M_KEY_START ( ps.config.GetKeyStartDelim () ),
    M_KEY_END ( ps.config.GetKeyEndDelim () ),
    M_LINE_END ( ps.config.GetLineEndDelim () ),
    M_ASSIGN ( ps.config.GetAssignSymbol () ),
    M_MULTI_VALUE ( ps.config.GetMultiValueDelim () )
    {
    	stringstream buffer;
    	string file = ps.config.GetFileName ();

    	// open the file based on the constraints
    	if ( ps.config.GetFileMode () == cPropertySetConfig::EXISTS_OVERWRITE_OR_CREATE )
    	{
    		// overwrite file in either case
    		m_out.open ( file.c_str (), ios::out );
    		if ( !m_out )
    		{
    			buffer << "Error: File IO error while attempting to open file: " << file.c_str ();
    			cPropertySet::cFileModeConstraint e ( buffer.str () );
    			throw e;
    		}
    	}
    	else
    	if ( ps.config.GetFileMode () == cPropertySetConfig::EXISTS_OVERWRITE_OR_FAIL )
    	{
    		m_out.open ( file.c_str (), ios::in );
    		if ( !m_out )
    		{
    			// file doesn't exist so fail
    			buffer << "Error: File IO error while attempting to open existing file: " << file.c_str ();
    			cPropertySet::cFileModeConstraint e ( buffer.str () );
    			throw e;
    		}
    		else
    		{
    			// file exists, so overwrite
    			m_out.close ();
    			m_out.clear ();
    			m_out.open ( file.c_str (), ios::out );
    			if ( !m_out )
    			{
    				// file io error
    				buffer << "Error: File IO error while attempting to open existing file: " << file.c_str ();
    				cPropertySet::cFileModeConstraint e ( buffer.str () );
    				throw e;
    			}
    		}
    	}
    	else
    	if ( ps.config.GetFileMode () == cPropertySetConfig::EXISTS_FAIL_OR_CREATE )
    	{
    		// see if the file exists
    		m_out.open ( file.c_str (), ios::in );
    		if ( !m_out )
    		{
    			// file doesn't exist so create it
    			m_out.clear ();
    			m_out.open ( file.c_str (), ios::out );
    			if ( !m_out )
    			{
    				buffer << "Error: File IO error while attempting to create file: " << file.c_str ();
    				cPropertySet::cFileModeConstraint e ( buffer.str () );
    				throw e;
    			}
    		}
    		else
    		{
    			// file exists, so fail
    			buffer << "Error: File: " << file.c_str () << " exists and should not";
    			cPropertySet::cFileModeConstraint e ( buffer.str () );
    			throw e;
    		}
    	}
    	else
    	{
    		buffer << "Error: File constraint not specified for file: " << file.c_str ();
    		cPropertySet::cFileModeConstraint e ( buffer.str () );
    		throw e;
    	}
    }

    cPropertySetWriter::~cPropertySetWriter ()
    {
    	m_out.clear ();
    	m_out.close ();
    }

    void cPropertySetWriter::Write ()
    {
    	// iterate through all the keys and all the parameter values
    	// if there is info associated with a key, write that first
    	// then write the key once
    	// after the key, write all the parameter names and values
    	// if a parameter has info associated with it, write it before the parameter

    	// example:
    	// M_INFO_START info
    	// M_KEY_START key M_KEY_END<M_LINE_END>
    	// M_INFO_START info
    	// parameter<M_ASSIGN>value <M_MULTI_VALUE> ... <M_LINE_END>

    	if ( !m_out )
    		return;

    	std::multimap < string, cMultiProperty >::const_iterator cur_key;
    	std::multimap < string, cMultiProperty >::const_iterator cur_param;

    	for ( (cur_key = m_property_set->m_property_set.begin () ); cur_key != m_property_set->m_property_set.end (); cur_key = cur_param )
    	{
    		WriteInfo ( m_property_set->GetInfo ( cur_key->first, cur_key->first ) );
    		WriteKey ( cur_key->first );

    		// try to find the parameters
    		for ( cur_param = m_property_set->m_property_set.lower_bound ( cur_key->first ); cur_param != m_property_set->m_property_set.upper_bound ( cur_key->first ); ++cur_param )
    		{
    			// don't write the parameter key=key name, param=key name
    			if ( cur_param->second.Name () != cur_key->first )
    			{
    				WriteInfo ( m_property_set->GetInfo ( cur_key->first, cur_param->second.Name () ) );
    				WriteParam ( cur_param->second.Name () );
    				WriteMultiProperty ( const_cast< cMultiProperty& >( cur_param->second ) );

    				m_out << M_LINE_END;
    			} // end if
    		} // end for

    		m_out << M_LINE_END;
    	} // end for
    }

    void cPropertySetWriter::WriteKey ( const string &key )
    {
    	if ( !m_out )
    		return;

    #ifdef _DEBUG
    	cout << "writing key=" << key.c_str () << endl;
    #endif // _DEBUG

    	if ( !key.empty () )
    		m_out << M_KEY_START << ' ' << key.c_str () << ' ' << M_KEY_END << M_LINE_END;

    #ifdef _DEBUG
    	m_out.flush ();
    #endif // _DEBUG
    }

    void cPropertySetWriter::WriteInfo ( const string &info )
    {
    	if ( !m_out )
    		return;

    	if ( !info.empty () )
    	{

    #ifdef _DEBUG
    		cout << "writing info=" << info.c_str () << endl;
    #endif // _DEBUG

    		m_out << M_LINE_END << M_INFO_START << ' ';

    		// for every M_LINE_END, start a new M_INFO_START
    		for ( int i = 0; i < info.length (); ++i )
    		{
    			m_out << info.at ( i );

    			if ( (info.at ( i ) == M_LINE_END) && (i < info.length () - 1) )
    				m_out << M_INFO_START << ' ';
    		}
    	}

    #ifdef _DEBUG
    	m_out.flush ();
    #endif // _DEBUG
    }

    void cPropertySetWriter::WriteParam ( const string &name )
    {
    	if ( !m_out )
    		return;

    #ifdef _DEBUG
    	cout << "writing param=" << name.c_str () << endl;
    #endif // _DEBUG

    	if ( !name.empty () )
    		m_out << name.c_str () << M_ASSIGN;

    #ifdef _DEBUG
    	m_out.flush ();
    #endif // _DEBUG
    }

    void cPropertySetWriter::WriteMultiProperty ( cMultiProperty &p )
    {
    	if ( !m_out )
    		return;

    	// if a multi property has more than one value, use M_MULTI_VALUE to separate the values
    	for ( unsigned int i = 0; i < p.NumValues (); ++i )
    	{

    #ifdef _DEBUG
    		cout << "writing multi-property=" << p.GetString ( i ).c_str () << endl;
    #endif // _DEBUG

    		m_out << p.GetString ( i );

    		if ( i < p.NumValues () - 1 )
    			m_out << M_MULTI_VALUE;
    	}
    #ifdef _DEBUG
    	m_out.flush ();
    #endif // _DEBUG
    }

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_multi_property.cpp] - (11,358 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_multi_property.hpp"

    cMultiProperty::cMultiProperty ( const cPropertyValue::eValueType type )
    {
    	// create a single value and default value
    	AllocateValue ( type );
    }

    cMultiProperty::cMultiProperty ()
    {
    	// create a single value and default value
    	AllocateValue ();
    }

    cMultiProperty::~cMultiProperty ()
    {
    	Destroy ();
    }

    void cMultiProperty::AllocateValue ( const cPropertyValue::eValueType type )
    {
    	cPropertyValue p ( type );
    	m_values.push_back ( p );
    	m_defaults.push_back ( p );
    }

    cPropertyValue::eValueType
    cMultiProperty::Type ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].Type ();

    	return m_values [ index ].Type ();
    }

    cPropertyValue::eValueType
    cMultiProperty::TypeDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].Type ();

    	return m_defaults [ index ].Type ();
    }

    void cMultiProperty::Type ( const cPropertyValue::eValueType type,
    							const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].Type ( type );
    	}
    	else
    	{
    		m_values [ index ].Type ( type );
    	}
    }

    void cMultiProperty::TypeDefault ( const cPropertyValue::eValueType type,
    								   const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].Type ( type );
    	}
    	else
    	{
    		m_defaults [ index ].Type ( type );
    	}
    }

    string cMultiProperty::Name () const
    {
    	return m_name;
    }

    void cMultiProperty::Name ( const string name )
    {
    	m_name = name;
    }

    string cMultiProperty::Info () const
    {
    	return m_info;
    }

    void cMultiProperty::Info ( const string info )
    {
    	m_info = info;
    }

    // values
    bool cMultiProperty::GetBool ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetBool ();

    	return m_values [ index ].GetBool ();
    }

    void cMultiProperty::SetBool ( const bool value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetBool ( value );
    	}
    	else
    	{
    		m_values [ index ].SetBool ( value );
    	}
    }

    char cMultiProperty::GetChar ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetChar ();

    	return m_values [ index ].GetChar ();
    }

    void cMultiProperty::SetChar ( const char value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetChar ( value );
    	}
    	else
    	{
    		m_values [ index ].SetChar ( value );
    	}
    }

    short cMultiProperty::GetShort ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetShort ();

    	return m_values [ index ].GetShort ();
    }

    void cMultiProperty::SetShort ( const short value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetShort ( value );
    	}
    	else
    	{
    		m_values [ index ].SetShort ( value );
    	}
    }

    int cMultiProperty::GetInt ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetInt ();

    	return m_values [ index ].GetInt ();
    }

    void cMultiProperty::SetInt ( const int value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetInt ( value );
    	}
    	else
    	{
    		m_values [ index ].SetInt ( value );
    	}
    }

    long cMultiProperty::GetLong ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetLong ();

    	return m_values [ index ].GetLong ();
    }

    void cMultiProperty::SetLong ( const long value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetLong ( value );
    	}
    	else
    	{
    		m_values [ index ].SetLong ( value );
    	}
    }

    float cMultiProperty::GetFloat ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetFloat ();

    	return m_values [ index ].GetFloat ();
    }

    void cMultiProperty::SetFloat ( const float value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetFloat ( value );
    	}
    	else
    	{
    		m_values [ index ].SetFloat ( value );
    	}
    }

    double cMultiProperty::GetDouble ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetDouble ();

    	return m_values [ index ].GetDouble ();
    }

    void cMultiProperty::SetDouble ( const double value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetDouble ( value );
    	}
    	else
    	{
    		m_values [ index ].SetDouble ( value );
    	}
    }

    string cMultiProperty::GetString ( const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    		return m_values [ m_values.size () - 1 ].GetString ();

    	return m_values [ index ].GetString ();
    }

    void cMultiProperty::SetString ( const string value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_values [ m_values.size () - 1 ].SetString ( value );
    	}
    	else
    	{
    		m_values [ index ].SetString ( value );
    	}
    }

    // default values
    bool cMultiProperty::GetBoolDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetBool ();

    	return m_defaults [ index ].GetBool ();
    }

    void cMultiProperty::SetBoolDefault ( const bool value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetBool ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetBool ( value );
    	}
    }

    char cMultiProperty::GetCharDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetChar ();

    	return m_defaults [ index ].GetChar ();
    }

    void cMultiProperty::SetCharDefault ( const char value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetChar ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetChar ( value );
    	}
    }

    short cMultiProperty::GetShortDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetShort ();

    	return m_defaults [ index ].GetShort ();
    }

    void cMultiProperty::SetShortDefault ( const short value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetShort ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetShort ( value );
    	}
    }

    int cMultiProperty::GetIntDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetInt ();

    	return m_defaults [ index ].GetInt ();
    }

    void cMultiProperty::SetIntDefault ( const int value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetInt ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetInt ( value );
    	}
    }

    long cMultiProperty::GetLongDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetLong ();

    	return m_defaults [ index ].GetLong ();
    }

    void cMultiProperty::SetLongDefault ( const long value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetLong ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetLong ( value );
    	}
    }

    float cMultiProperty::GetFloatDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetFloat ();

    	return m_defaults [ index ].GetFloat ();
    }

    void cMultiProperty::SetFloatDefault ( const float value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetFloat ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetFloat ( value );
    	}
    }

    double cMultiProperty::GetDoubleDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetDouble ();

    	return m_defaults [ index ].GetDouble ();
    }

    void cMultiProperty::SetDoubleDefault ( const double value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetDouble ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetDouble ( value );
    	}
    }

    string cMultiProperty::GetStringDefault ( const unsigned short index  )
    {
    	if ( !IsValidDefaultIndex ( index ) )
    		return m_defaults [ m_defaults.size () - 1 ].GetString ();

    	return m_defaults [ index ].GetString ();
    }

    void cMultiProperty::SetStringDefault ( const string value, const unsigned short index  )
    {
    	if ( !IsValidIndex ( index ) )
    	{
    		AllocateValue ();
    		m_defaults [ m_defaults.size () - 1 ].SetString ( value );
    	}
    	else
    	{
    		m_defaults [ index ].SetString ( value );
    	}
    }

    void cMultiProperty::Destroy ()
    {
    	// iterate through all the values and destroy them
    	m_values.erase ( m_values.begin (), m_values.end () );
    	m_defaults.erase ( m_defaults.begin (), m_defaults.end () );
    	AllocateValue ();
    }

    bool cMultiProperty::IsValidIndex ( const unsigned short index ) const
    {
    	return ( index < m_values.size () );
    }

    bool cMultiProperty::IsValidDefaultIndex ( const unsigned short index ) const
    {
    	return ( index < m_defaults.size () );
    }

    unsigned int cMultiProperty::NumValues () const
    {
    	return m_values.size ();
    }

    void cMultiProperty::Clear ()
    {
    	unsigned int i = 0;

    	for ( i = 0; i < m_values.size (); ++i )
    		m_values [ i ].Clear ();

    	for ( i = 0; i < m_defaults.size (); ++i )
    		m_defaults [ i ].Clear ();
    }

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_exception.hpp] - (1,323 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #ifndef _PROPERTY_EXCEPTION_HPP
    #define _PROPERTY_EXCEPTION_HPP

    #include <string>
    #include <exception>

    using std::string;

    class cPropertyException : public exception
    {
    public:
    	cPropertyException ( string msg );
    	virtual ~cPropertyException ();

    	virtual const char * what () const;

    private:
    	string m_msg;
    };
    #endif // _PROPERTY_EXCEPTION_HPP

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_exception.cpp] - (1,199 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_exception.hpp"

    cPropertyException::cPropertyException ( string msg ) :
    m_msg ( msg )
    {
    }

    cPropertyException::~cPropertyException ()
    {
    }

    const char * cPropertyException::what () const
    {
    	return m_msg.c_str ();
    }

Currently browsing [PropertySet.zip] (102,782 bytes) - [PropertySet/property_set/src/ps_string_conv.cpp] - (2,908 bytes)

    /*********************************************************************************************
    *	Copyright (C) 2002 Robert Farrell
    *
    *	This program is free software; you can redistribute it and/or
    *	modify it under the terms of the GNU General Public License
    *	as published by the Free Software Foundation; either version 2
    *	of the License, or (at your option) any later version.
    *
    *	This program is distributed in the hope that it will be useful,
    *	but WITHOUT ANY WARRANTY; without even the implied warranty of
    *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    *
    *	See the GNU General Public License for more details.
    *
    *	You should have received a copy of the GNU General Public License
    *	along with this program; if not, write to the Free Software
    *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    *
    **********************************************************************************************/
    #include "ps_string_conv.hpp"

    using std::stringstream;

    stringstream cStringConverter::m_temp;

    cStringConverter::cStringConverter ( string &s ) :
    m_string ( &s )
    {
    }

    cStringConverter::cStringConverter () :
    m_string ( 0 )
    {
    }

    cStringConverter::~cStringConverter ()
    {
    }

    void cStringConverter::SetString ( string &string )
    {
    	m_string = &string;
    }

    bool cStringConverter::ToBool ()
    {
    	if ( !m_string )
    		return false;

    	if ( m_string->empty () )
    		return false;

    	if ( m_string->at ( 0 ) == '0' || *m_string == "false" )
    		return false;

    	if ( *m_string == "true" )
    		return true;

    	m_temp.str ( "" );
    	bool val = false;
    	m_temp << *m_string;
    	m_temp >> val;
    	return val;
    }

    char cStringConverter::ToChar ()
    {
    	if ( !m_string )
    		return '\0';

    	if ( m_string->empty () )
    		return '\0';

    	return m_string->at ( 0 );
    }

    short	cStringConverter::ToShort ()
    {
    	if ( !m_string )
    		return 0;

    	if ( m_string->empty () )
    		return 0;

    	m_temp.str ( "" );
    	short val = 0;
    	m_temp << *m_string;
    	m_temp >> val;
    	return val;
    }

    int cStringConverter::ToInt ()
    {
    	if ( !m_string )
    		return 0;

    	if ( m_string->empty () )
    		return 0;

    	m_temp.str ( "" );
    	int val = 0;
    	m_temp << *m_string;
    	m_temp >> val;
    	return val;
    }

    long	cStringConverter::ToLong ()
    {
    	if ( !m_string )
    		return 0;

    	if ( m_string->empty () )
    		return 0;

    	m_temp.str ( "" );
    	long val = 0;
    	m_temp << *m_string;
    	m_temp >> val;
    	return val;
    }

    float	cStringConverter::ToFloat ()
    {
    	if ( !m_string )
    		return 0.0;

    	if ( m_string->empty () )
    		return 0.0;

    	m_temp.str ( "" );
    	float val = 0.0;
    	m_temp << *m_string;
    	m_temp >> val;
    	return val;
    }

    double cStringConverter::ToDouble ()
    {
    	if ( !m_string )
    		return 0.0;

    	if ( m_string->empty () )
    		return 0.0;

    	m_temp.str ( "" );
    	double val = 0.0;
    	m_temp << *m_string;
    	m_temp >> val;
    	return val;
    }

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.