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.