Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

GenericValues.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2000-2003, Jelle Kok, University of Amsterdam
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008 1. Redistributions of source code must retain the above copyright notice, this
00009 list of conditions and the following disclaimer.
00010 
00011 2. Redistributions in binary form must reproduce the above copyright notice,
00012 this list of conditions and the following disclaimer in the documentation
00013 and/or other materials provided with the distribution.
00014 
00015 3. Neither the name of the University of Amsterdam nor the names of its
00016 contributors may be used to endorse or promote products derived from this
00017 software without specific prior written permission.
00018 
00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00020 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00021 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
00023 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00024 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00025 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00026 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00027 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00028 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029 */
00030 
00055 #include "GenericValues.h"
00056 #include "Parse.h"           // needed for 'gotoFirstNonSpace'
00057 #include <stdio.h>           // needed for 'sprintf'
00058 #include <stdlib.h>          // needed for 'free'
00059 #include <string.h>          // needed for 'strdup'
00060 #include <ctype.h>           // needed for 'isdigit'
00061 #include <fstream>           // needed for 'ifstream'
00062 
00063 /*****************************************************************************/
00064 /*******************   CLASS GENERICVALUET   *********************************/
00065 /*****************************************************************************/
00066 
00076 GenericValueT::GenericValueT( const char *str, void *vAddr, GenericValueKind t)
00077 {
00078   m_strName  = strdup( str ); // strdup needed to alloc right amount of memory
00079   m_vAddress = vAddr;
00080   m_type     = t;
00081 }
00082 
00085 GenericValueT::~GenericValueT( )
00086 {
00087   if( m_strName )
00088     free( ( char * ) m_strName );
00089 }
00090 
00094 const char* GenericValueT::getName ( )
00095 {
00096   return ( m_strName );
00097 }
00098 
00108 bool GenericValueT::setValue( const char *strValue )
00109 {
00110   bool bReturn = true, b;
00111 
00112   // determine the generic type associated with this GenericValueT
00113   // object and apply the correct conversion of the string argument
00114   switch( m_type )
00115   {
00116     case GENERIC_VALUE_DOUBLE:
00117       *( double * ) m_vAddress = atof( strValue ? strValue : 0 );
00118       break;
00119     case GENERIC_VALUE_STRING:
00120       strcpy( ( char * ) m_vAddress, strValue );
00121       break;
00122     case GENERIC_VALUE_BOOLEAN:
00123       b = false;
00124       if( !strValue )
00125         ;
00126       else if( isdigit( strValue[ 0 ] ) )
00127         b = atoi( strValue ? strValue : 0 );
00128 #ifdef WIN32
00129       else if( strcmp( strValue, "on"  ) == 0 ||
00130                strcmp( strValue, "true") == 0 ||
00131                strcmp( strValue, "yes" ) == 0 )
00132 #else
00133       else if( strcasecmp( strValue, "on"  ) == 0 ||
00134                strcasecmp( strValue, "true") == 0 ||
00135                strcasecmp( strValue, "yes" ) == 0 )
00136 #endif
00137         b = true;
00138 
00139       *( bool * ) m_vAddress = ( b == true ) ? true : false;
00140       break;
00141     case GENERIC_VALUE_INTEGER:
00142       *( int * ) m_vAddress = atoi( strValue ? strValue : 0 );
00143       break;
00144     default:
00145       bReturn = false;
00146   }
00147 
00148   return ( bReturn );
00149 }
00150 
00164 char* GenericValueT::getValue( char *strValue )
00165 {
00166   // determine the generic type associated with this GenericValueT
00167   // object and apply the correct conversion into a string
00168   switch( m_type )
00169   {
00170     case GENERIC_VALUE_DOUBLE:
00171       sprintf( strValue, "%2f", *( double * ) m_vAddress );
00172       break;
00173     case GENERIC_VALUE_STRING:
00174       sprintf( strValue, "%s", ( char * ) m_vAddress );
00175       break;
00176     case GENERIC_VALUE_BOOLEAN:
00177       sprintf( strValue, "%d", *( int * ) m_vAddress );
00178       break;
00179     case GENERIC_VALUE_INTEGER:
00180       sprintf( strValue, "%d", *( int * ) m_vAddress );
00181       break;
00182     default:
00183       *strValue = '\0';
00184   }
00185 
00186   return ( strValue );
00187 }
00188 
00202 void GenericValueT::show( ostream& out, const char *strSeparator )
00203 {
00204   // write the name associated with the variable in this GenericValueT
00205   // object followed by the separator to the specified output stream
00206   out << m_strName << strSeparator;
00207 
00208   // determine the generic type associated with this GenericValueT
00209   // object and write the correct value to the specified output stream
00210   switch( m_type )
00211   {
00212     case GENERIC_VALUE_DOUBLE:
00213       out << *( double * ) m_vAddress;
00214       break;
00215     case GENERIC_VALUE_STRING:
00216       out << ( char * ) m_vAddress;
00217       break;
00218     case GENERIC_VALUE_BOOLEAN:
00219       out << ( ( *( bool * ) m_vAddress == true ) ? "true" : "false");
00220       break;
00221     case GENERIC_VALUE_INTEGER:
00222       out << *( int * ) m_vAddress;
00223       break;
00224     default:
00225       break;
00226   }
00227 
00228   out << endl;
00229 }
00230 
00231 
00232 /*****************************************************************************/
00233 /*******************   CLASS GENERICVALUES   *********************************/
00234 /*****************************************************************************/
00235 
00243 GenericValues::GenericValues( char *strName, int iMaxValues )
00244 {
00245   m_iValuesTotal = 0;   // total number of values in collection is set to zero
00246 
00247   if( strName )       // set the name of the collection
00248     m_strClassName = strdup( strName );
00249 
00250   m_iMaxGenericValues = iMaxValues;
00251 
00252   // a GenericValues object is a collection of GenericValueT objects
00253   m_values = new GenericValueT*[ iMaxValues ];
00254 }
00255 
00258 GenericValues::~GenericValues( void )
00259 {
00260   for( int i = 0 ; i < getValuesTotal( ) ; i++ )
00261     delete m_values[ i ];
00262   delete m_values;
00263 
00264   if( m_strClassName )
00265     free( m_strClassName );
00266 }
00267 
00271 char* GenericValues::getClassName( )
00272 {
00273   return ( m_strClassName );
00274 }
00275 
00278 int GenericValues::getValuesTotal( )
00279 {
00280   return ( m_iValuesTotal );
00281 }
00282 
00297 bool GenericValues::addSetting( const char *strName, void *vAddress,
00298                                                      GenericValueKind type )
00299 {
00300   if( getValuePtr( strName ) )               // setting already installed
00301   {
00302     cerr << "Setting '" << strName << "' already installed." << endl;
00303     return false;
00304   }
00305   if( m_iValuesTotal == m_iMaxGenericValues )    // buffer is full
00306   {
00307     cerr << "GenericValues::addSetting buffer for " << m_strClassName <<
00308             " is full (cannot add '" << strName << "')" << endl;
00309     return false;
00310   }
00311 
00312   m_values[ m_iValuesTotal++ ] = new GenericValueT( strName, vAddress, type );
00313 
00314   return ( true );
00315 }
00316 
00329 GenericValueT* GenericValues::getValuePtr( const char *strName )
00330 {
00331   GenericValueT *ptr = 0;
00332 
00333   // search through the collection for a GenericValueT object of which the name
00334   // associated with the variable matches the argument passed to the method
00335   for( int i = 0 ; i < getValuesTotal( ) ; i++ )
00336   {
00337     if( strcmp( m_values[ i ]->getName( ), strName ) == 0 )
00338     {
00339       ptr = m_values[ i ];
00340       break;
00341     }
00342   }
00343 
00344   return ( ptr );
00345 }
00346 
00360 char* GenericValues::getValue( const char *strName, char *strValue )
00361 {
00362   GenericValueT *parptr;
00363 
00364   parptr = getValuePtr( strName );
00365 
00366   if( parptr )
00367     strValue = parptr->getValue( strValue );   // this method returns a string
00368   else
00369     strValue[ 0 ] = '\0';
00370 
00371   return ( strValue );
00372 }
00373 
00387 bool GenericValues::setValue( const char *strName, const char *strValue )
00388 {
00389   bool bReturn = false;
00390   GenericValueT *parptr;
00391 
00392   parptr = getValuePtr( strName );
00393 
00394   if( parptr )
00395     bReturn = parptr->setValue( strValue ); // string is converted to its type
00396 
00397   return ( bReturn );
00398 }
00399 
00412 bool GenericValues::readValues( const char *strFile, const char *strSeparator )
00413 {
00414   ifstream in( strFile );
00415 
00416   if( !in )
00417   {
00418     cerr << "(GenericValues::readValues) Could not open file '" <<
00419     strFile << "'" << endl;
00420     return ( false );
00421   }
00422 
00423   bool  bReturn = true;
00424   char  strLine[ 256 ], strName[ 100 ], strValue[ 100 ];
00425   char* c;
00426   int   iLineNr = 0;
00427 
00428   // read each line in the configuration file and store the values
00429   while( in.getline( strLine, sizeof( strLine ) ) )
00430   {
00431     iLineNr++;
00432 
00433     // skip comment lines and empty lines; " #" is for server.conf version 7.xx
00434     if( !( strLine[ 0 ] == '\n' ||
00435            strLine[ 0 ] == '#'  ||
00436            strLine[ 0 ] == '\0' ||
00437            ( strlen( strLine ) > 1 &&
00438              strLine[ 0 ] == ' ' &&
00439              strLine[ 1 ] == '#' ) ) )
00440     {
00441       // convert all characters belonging to the separator to spaces
00442       if( strSeparator && ( c = strstr( strLine, strSeparator ) ) != NULL )
00443         for( size_t i = 0; i < strlen( strSeparator ); i++ )
00444           *( c + i ) = ' ';
00445 
00446       // read the name and value on this line and store the value
00447       if( !( sscanf( strLine, "%s%s", strName, strValue ) == 2 &&
00448              setValue( strName, strValue ) ) )
00449       {
00450         bReturn = false;
00451         cerr << "(GenericValues::readValues) '" << strFile << "' linenr "
00452              << iLineNr << ",  error in '" << strLine << "'" << endl;
00453       }
00454     }
00455   }
00456 
00457   return ( bReturn );
00458 }
00459 
00478 bool GenericValues::saveValues( const char *strFile, const char *strSeparator,
00479                                 bool bAppend )
00480 {
00481   ofstream outf( strFile, ( bAppend == false ? ( ios::out )
00482                                              : ( ios::out | ios::app ) ) );
00483 
00484   if( !outf )
00485   {
00486     cerr << "Could not open file '" << strFile << "'" << endl;
00487     return ( false );
00488   }
00489 
00490   // values are written to file using 'show' (note that
00491   // output stream to write to is a file in this case)
00492   show( outf, strSeparator );
00493 
00494   return ( true );
00495 }
00496 
00509 void GenericValues::show( ostream& out, const char *strSeparator )
00510 {
00511   for( int i = 0; i < getValuesTotal( ); i++ )
00512     m_values[ i ]->show( out, strSeparator );
00513 }
00514 
00515 /********************* TESTING PURPOSES **************************************/
00516 /*
00517 int main( void )
00518 {
00519   GenericValues g("ServerSettings", 6);
00520 
00521   int    i = 10;
00522   char   c[256];
00523   sprintf( c, "hallo" );
00524   bool   b = true;
00525   double d = 10.14;
00526 
00527   cout << g.addSetting( "var1", &i, GENERIC_VALUE_INTEGER ) << endl;
00528   cout << g.addSetting( "var2", c, GENERIC_VALUE_STRING  ) << endl;
00529   cout << g.addSetting( "var3", &d, GENERIC_VALUE_DOUBLE  ) << endl;
00530   cout << g.addSetting( "var4", &b, GENERIC_VALUE_BOOLEAN ) << endl;
00531   g.show( cout, ":"  );
00532 
00533   g.setValue( "var1", "11"      );
00534   g.setValue( "var2", "hoi"     );
00535   g.setValue( "var3", "20.2342" );
00536   g.setValue( "var4", "false"   );
00537   g.show( cout, ":"  );
00538 
00539 //  g.setIntegerValue( "var1", 22      );
00540 //  g.setStringValue ( "var2", "hoi2"  );
00541 //  g.setDoubleValue ( "var3", 30.2342 );
00542 //  g.setBooleanValue( "var4", true    );
00543 //  g.show( cout, ":"  );
00544 
00545 //  g.readValues( "server.conf", ":" );
00546 //  g.show( cout, ":"  );
00547 
00548   return ( 0 );
00549 }
00550 
00551 */

Generated on Fri Nov 7 11:45:39 2003 for UvA Trilearn 2003 Base Code by doxygen1.2.12 written by Dimitri van Heesch, © 1997-2001