Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

Ini.cpp

Go to the documentation of this file.
00001 /*
00002  * Ini.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  */
00022 
00027 #include "../Include/FlyLegacy.h"
00028 #include "../Include/Ini.h"
00029 #include "../Include/Globals.h"
00030 
00031 using namespace std;
00032 
00033 
00034 //
00035 // CIniSetting - Individual setting in an INI file
00036 //
00037 
00038 CIniSetting::CIniSetting (const char* key)
00039 {
00040   type = INI_INT_SETTING;
00041   strncpy (this->key, key, 64);
00042 
00043   value = 0.0;
00044   memset (s_value, 0, 64);
00045 }
00046 
00047 
00048 //
00049 // Set a float INI setting
00050 //
00051 void CIniSetting::Set (float f)
00052 {
00053   type = INI_FLOAT_SETTING;
00054   value = f;
00055 }
00056 
00057 
00058 //
00059 // Set an integer INI setting
00060 //
00061 void CIniSetting::Set (int i)
00062 {
00063   type = INI_INT_SETTING;
00064   value = (float)i;
00065 }
00066 
00067 
00068 //
00069 // Set a string INI setting
00070 //
00071 void CIniSetting::Set (const char* s)
00072 {
00073   type = INI_STRING_SETTING;
00074   strncpy (s_value, s, 64);
00075   value = 0;
00076 }
00077 
00078 
00079 //
00080 // Get a float INI setting
00081 //
00082 void CIniSetting::Get (float *f)
00083 {
00084   type = INI_FLOAT_SETTING;
00085   *f = value;
00086 }
00087 
00088 
00089 //
00090 // Get an integer INI setting
00091 //
00092 void CIniSetting::Get (int *i)
00093 {
00094   type = INI_INT_SETTING;
00095   *i = (int)value;
00096 }
00097 
00098 
00099 //
00100 // Get a string INI setting
00101 //
00102 void CIniSetting::Get (char *s, int maxLength)
00103 {
00104   type = INI_STRING_SETTING;
00105   strncpy (s, s_value, maxLength);
00106 }
00107 
00108 
00109 void CIniSetting::Save (FILE *f)
00110 {
00111   switch (type) {
00112   case INI_FLOAT_SETTING:
00113     fprintf (f, "%s=%f\n", key, value);
00114     break;
00115 
00116   case INI_INT_SETTING:
00117     fprintf (f, "%s=%d\n", key, (int)value);
00118     break;
00119 
00120   case INI_STRING_SETTING:
00121     fprintf (f, "%s=%s\n", key, s_value);
00122     break;
00123     
00124   default:
00125     gtfo ("CIniSetting::Save : Invalid INI setting type %d", type);
00126   }
00127 }
00128 
00129 
00130 
00131 //
00132 // CIniSection - Group of related settings in an INI file
00133 //
00134 
00135 CIniSection::CIniSection (const char* section)
00136 {
00137   strncpy (this->section, section, 64);
00138 }
00139 
00140 
00141 CIniSection::~CIniSection (void)
00142 {
00143   Clear ();
00144 }
00145 
00146 
00147 //
00148 // Clear the contents of the INI settings
00149 //
00150 void CIniSection::Clear (void)
00151 {
00152   map<string,CIniSetting*>::iterator i;
00153   for (i=setting.begin(); i!=setting.end(); i++) {
00154     CIniSetting *s = i->second;
00155     delete s;
00156   }
00157 }
00158 
00159 
00160 //
00161 // Protected method to find the index of the specified INI section if it exists
00162 //
00163 // Input Parameters:
00164 //  key       Attribute key name to search for
00165 //
00166 // Return Code:
00167 //  CIniSetting*  Pointer to CIniSetting. This should never be NULL; if the
00168 //          setting of the specified name does not exist it will be created
00169 //
00170 CIniSetting* CIniSection::FindSetting (const char* key)
00171 {
00172   CIniSetting *rc = NULL;
00173 
00174   map<string,CIniSetting*>::iterator i = setting.find(key);
00175   if (i != setting.end()) {
00176     // Found the setting, copy to the return value
00177     rc = i->second;
00178   } else {
00179     // Setting not found, add it to the section
00180     rc = new CIniSetting (key);
00181     if (rc == NULL) {
00182       gtfo ("CIniFile : Could not add setting %s in section %s", key, section);
00183     }
00184     setting[key] = rc;
00185   }
00186 
00187   return rc;
00188 }
00189 
00190 
00191 //
00192 // Set a float INI setting
00193 //
00194 void CIniSection::Set (const char* key, float f)
00195 {
00196   // Get reference to CIniSetting, or create it if it does not exist
00197   CIniSetting* setting = FindSetting (key);
00198   if (setting != NULL) {
00199     // Set the attribute value
00200     setting->Set (f);
00201   }
00202 }
00203 
00204 
00205 //
00206 // Set an integer INI setting
00207 //
00208 void CIniSection::Set (const char* key, int i)
00209 {
00210   // Get reference to CIniSetting, or create it if it does not exist
00211   CIniSetting* setting = FindSetting (key);
00212   if (setting != NULL) {
00213     // Set the attribute value
00214     setting->Set (i);
00215   }
00216 }
00217 
00218 
00219 //
00220 // Set a string INI setting
00221 //
00222 void CIniSection::Set (const char* key, const char* s)
00223 {
00224   // Get reference to CIniSetting, or create it if it does not exist
00225   CIniSetting* setting = FindSetting (key);
00226   if (setting != NULL) {
00227     // Set the attribute value
00228     setting->Set (s);
00229   }
00230 }
00231 
00232 
00233 //
00234 // Get a float INI setting
00235 //
00236 void CIniSection::Get (const char* key, float* f)
00237 {
00238   // Get reference to CIniSetting, or create it if it does not exist
00239   CIniSetting* setting = FindSetting (key);
00240   if (setting != NULL) {
00241     // Set the attribute value
00242     setting->Get (f);
00243   }
00244 }
00245 
00246 
00247 //
00248 // Get an integer INI setting
00249 //
00250 void CIniSection::Get (const char* key, int* i)
00251 {
00252   // Get reference to CIniSetting, or create it if it does not exist
00253   CIniSetting* setting = FindSetting (key);
00254   if (setting != NULL) {
00255     // Set the attribute value
00256     setting->Get (i);
00257   }
00258 }
00259 
00260 
00261 //
00262 // Get a string INI setting
00263 //
00264 void CIniSection::Get (const char* key, char* s, int maxLength)
00265 {
00266   // Get reference to CIniSetting, or create it if it does not exist
00267   CIniSetting* setting = FindSetting (key);
00268   if (setting != NULL) {
00269     // Set the attribute value
00270     setting->Get (s, maxLength);
00271   }
00272 }
00273 
00274 
00275 //
00276 // Save contents of the section to file
00277 //
00278 void CIniSection::Save (FILE *f)
00279 {
00280   fprintf (f, "[%s]\n", section);
00281   map<string,CIniSetting*>::iterator i;
00282   for (i=setting.begin(); i!=setting.end(); i++) {
00283     i->second->Save(f);
00284   }
00285 
00286   fprintf (f, "\n");
00287 }
00288 
00289 
00290 //
00291 // Remove the INI entry with the specified key
00292 //
00293 void CIniSection::Remove (const char* key)
00294 {
00295 }
00296 
00297 
00298 //
00299 // CIniFile - Collection of INI settings in a single disk file
00300 //
00301 
00302 CIniFile::CIniFile (void)
00303 {
00304 }
00305 
00306 
00307 CIniFile::CIniFile (const char* iniFilename)
00308 {
00309   Load (iniFilename);
00310 }
00311 
00312 
00313 CIniFile::~CIniFile (void)
00314 {
00315   Clear ();
00316 }
00317 
00318 
00319 //
00320 // Clear the contents of the INI settings
00321 //
00322 void CIniFile::Clear (void)
00323 {
00324   map<string,CIniSection*>::iterator i;
00325   for (i=section.begin(); i!=section.end(); i++) {
00326     delete i->second;
00327   }
00328 }
00329 
00330 
00331 //
00332 // Protected method to find the index of the specified INI section if it exists
00333 //
00334 // Input Parameters:
00335 //  section     Section name to search for
00336 //
00337 // Return Code:
00338 //  CIniSection*  Pointer to CIniSection. This should never be NULL; if the
00339 //          section of the specified name does not exist it will be created
00340 //
00341 CIniSection* CIniFile::FindSection (const char* sectname)
00342 {
00343   CIniSection *rc = NULL;
00344 
00345   map<string,CIniSection*>::iterator i = section.find(sectname);
00346   if (i != section.end()) {
00347     // Found the section, copy to the return value
00348     rc = i->second;
00349   } else {
00350     // Section not found, add it to the file
00351     rc = new CIniSection (sectname);
00352     if (rc == NULL) {
00353       gtfo ("CIniFile : Could not add section %s", sectname);
00354     }
00355     section[sectname] = rc;
00356   }
00357 
00358   return rc;
00359 }
00360 
00361 
00362 //
00363 // Local function that trims trailing whitespace from a line of text
00364 //
00365 void TrimTrailingWhitespace (char* s)
00366 {
00367   // Trim all trailing whitespace by walking backwards from end of string until
00368   //   a non-whitespace char is found, then replace the succeeding char with \0
00369   char *q = s + strlen(s) - 1;
00370   while (isspace(*q)) {
00371     *q = '\0';
00372     q--;
00373   }
00374   q++;
00375   *q = '\0';
00376 }
00377 
00378 
00379 //
00380 // Local function which parses the supplied line, looking for a new INI section
00381 //   header of the form [Section].
00382 //
00383 // Input parameters:
00384 //  s     String to parse
00385 //
00386 // Output parameters:
00387 //  section   Name of the section found, if rc == true
00388 //
00389 // Return code:
00390 //  bool    true if a new [Section] was found
00391 //
00392 static bool ParseSection (char* s, char* section)
00393 {
00394   bool rc = false;
00395 
00396   TrimTrailingWhitespace (s);
00397 
00398   char *p = strchr (s, '[');
00399   if (p != NULL) {
00400     // Increment to first character of section name
00401     p++;
00402 
00403     // Opening square bracket found
00404     char *q = strchr (p, ']');
00405     if (q != NULL) {
00406       // Closing square bracket found
00407       int len = q - p;
00408       strncpy (section, p, len);
00409       section[len] = '\0';
00410       rc = true;
00411     }
00412   }
00413 
00414   return rc;
00415 }
00416 
00417 
00418 //
00419 // Local function which parses the supplied line and returns the key and value
00420 //   (strings) if the line conforms to the standard INI format key=value
00421 //
00422 static bool ParseKeyValue (char* s, char* key, char* value)
00423 {
00424   bool rc = false;
00425 
00426   TrimTrailingWhitespace (s);
00427 
00428   char *p = strchr (s, '=');
00429   if (p != NULL) {
00430     // Copy key string
00431     int len = strlen(s) - strlen(p);
00432     strncpy (key, s, len);
00433     key[len] = '\0';
00434 
00435     // Copy value string
00436     strcpy (value, p+1);
00437 
00438     rc = true;
00439   }
00440 
00441   return rc;
00442 }
00443 
00444 
00445 //
00446 // Load (or re-load) the INI settings from disk file.  All existing settings are cleared.
00447 //
00448 // Input parameters:
00449 //  iniFilename   Name of normal disk file (not POD file) containing INI settings
00450 //
00451 // Return code:
00452 //  int       1 if settings were successfully loaded; 0 if file could not be opened
00453 //
00454 int CIniFile::Load (const char* iniFilename)
00455 {
00456   int rc = 0;
00457 
00458   // Clear all existing INI settings
00459   Clear ();
00460 
00461   // Declare local variables used in parsing of INI file lines
00462   char section[64];
00463   char key[64];
00464   char value[64];
00465   float f_value;
00466 
00467   // Open normal (non-POD) file
00468   FILE *f = fopen (iniFilename, "r");
00469   if (f) {
00470     // Begin parsing file
00471     char s[256];
00472     while (!feof (f)) {
00473       fgets (s, 256, f);
00474 
00475       // First check for a new section header : [Section]
00476       if (ParseSection (s, section)) {
00477         // New section header found
00478       } else {
00479         // No new section header found, parse for key/value pair
00480         if (ParseKeyValue (s, key, value)) {
00481           // Parse the value to determine whether it is numeric (int/float)
00482           //   or string.
00483           if (sscanf (value, "%f", &f_value) == 1) {
00484             // Value is numeric
00485             Set (section, key, f_value);
00486           } else {
00487             // Value is a string
00488             Set (section, key, value);
00489           }
00490         }
00491       }
00492     }
00493     fclose (f);
00494 
00495     // Set success return code
00496     rc = 1;
00497   }
00498 
00499   return rc;
00500 }
00501 
00502 
00503 //
00504 // Merge the contents of an INI settings file with the currently loaded settings
00505 //
00506 int CIniFile::Merge (const char* iniFilename)
00507 {
00508   int rc = 0;
00509 
00510   return rc;
00511 }
00512 
00513 
00514 //
00515 // Save the INI settings to a disk file
00516 //
00517 int CIniFile::Save (const char* iniFilename)
00518 {
00519   int rc = 0;
00520 
00521   // Open disk file
00522   FILE *f = fopen (iniFilename, "w");
00523   if (f) {
00524     map<string,CIniSection*>::iterator i;
00525     for (i=section.begin(); i!=section.end(); i++) {
00526       i->second->Save(f);
00527     }
00528 
00529     fclose (f);
00530 
00531     // Set success return code
00532     rc = 1;
00533   } else {
00534     globals->logWarning->Write ("CIniFile : Unable to save INI file to %s", iniFilename);
00535   }
00536 
00537   return rc;
00538 }
00539 
00540 
00541 //
00542 // Set a float INI setting
00543 //
00544 void CIniFile::Set (const char* section, const char* key, float f)
00545 {
00546   // Get reference to CIniSection, or create it if it does not exist
00547   CIniSection* sect = FindSection (section);
00548   if (sect != NULL) {
00549     // Set the key/value attribute in the section
00550     sect->Set (key, f);
00551   }
00552 }
00553 
00554 
00555 //
00556 // Set an integer INI setting
00557 //
00558 void CIniFile::Set (const char* section, const char* key, int i)
00559 {
00560   // Get reference to CIniSection, or create it if it does not exist
00561   CIniSection* sect = FindSection (section);
00562   if (sect != NULL) {
00563     // Set the key/value attribute in the section
00564     sect->Set (key, i);
00565   }
00566 }
00567 
00568 
00569 //
00570 // Set a string INI setting
00571 //
00572 void CIniFile::Set (const char* section, const char* key, const char* s)
00573 {
00574   // Get reference to CIniSection, or create it if it does not exist
00575   CIniSection* sect = FindSection (section);
00576   if (sect != NULL) {
00577     // Set the key/value attribute in the section
00578     sect->Set (key, s);
00579   }
00580 }
00581 
00582 
00583 //
00584 // Get a float INI setting
00585 //
00586 void CIniFile::Get (const char* section, const char* key, float* f)
00587 {
00588   // Get reference to CIniSection, or create it if it does not exist
00589   CIniSection* sect = FindSection (section);
00590   if (sect != NULL) {
00591     // Section exists, update the return parameter
00592     sect->Get (key, f);
00593   }
00594 }
00595 
00596 
00597 //
00598 // Get an integer INI setting
00599 //
00600 void CIniFile::Get (const char* section, const char* key, int* i)
00601 {
00602   // Get reference to CIniSection, or create it if it does not exist
00603   CIniSection* sect = FindSection (section);
00604   if (sect != NULL) {
00605     // Section exists, update the return parameter
00606     sect->Get (key, i);
00607   }
00608 }
00609 
00610 
00611 //
00612 // Get an string INI setting
00613 //
00614 void CIniFile::Get (const char* section, const char* key, char* s, int maxLength)
00615 {
00616   // Get reference to CIniSection, or create it if it does not exist
00617   CIniSection* sect = FindSection (section);
00618   if (sect != NULL) {
00619     // Section exists, update the return parameter
00620     sect->Get (key, s, maxLength);
00621   }
00622 }
00623 
00624 
00625 //
00626 // Remove a setting from the INI file
00627 //
00628 void CIniFile::Remove (const char* section, const char* key)
00629 {
00630   // Get reference to CIniSection, or create it if it does not exist
00631   CIniSection* sect = FindSection (section);
00632   if (sect != NULL) {
00633     // Set the key/value attribute in the section
00634     sect->Remove (key);
00635   }
00636 }
00637 
00638 int CIniFile::GetNumSections (void)
00639 {
00640   return section.size();
00641 }
00642 
00647 char* CIniFile::GetSectionName (int i)
00648 {
00649   char* rc = NULL;
00650 
00651   map<string,CIniSection*>::iterator iter = section.begin();
00652   for (int count=i; (iter != section.end()) && (count > 0); count--, iter++);
00653   CIniSection *pSection = iter->second;
00654   rc = pSection->section;
00655 
00656   return rc;
00657 }
00658 
00659 
00660 /*
00661  * INI functions defined in FlyLegacy.h
00662  */
00663 static CIniFile *ini;
00664 
00665 void LoadIniSettings (void)
00666 {
00667   ini = new CIniFile (); 
00668 
00669   // Attempt to load INI settings from FlyLegacy.ini
00670   int rc = ini->Load ("System\\FlyLegacy.ini");
00671   if (rc == 0) {
00672     // Could not load Fly! II settings from FlyLegacy.ini
00673     rc = ini->Load ("System\\Fly.ini");
00674 
00675     if (rc == 0) {
00676       gtfo ("LoadIniSettings : Cannot read settings from Fly.ini");
00677     } else {
00679     }
00680   }
00681 }
00682 
00683 void UnloadIniSettings (void)
00684 {
00685   delete ini;
00686 }
00687 
00688 void SaveIniSettings (void)
00689 {
00690   ini->Save ("System\\FlyLegacy.ini");
00691 }
00692 
00693 
00694 void  GetIniVar(const char *section, const char *varname, int *value)
00695 {
00696   ini->Get (section, varname, value);
00697 }
00698 
00699 
00700 void  GetIniFloat(const char *section, const char *varname, float *value)
00701 {
00702   ini->Get (section, varname, value);
00703 }
00704 
00705 
00706 void  GetIniString(const char *section, const char *varname, char *strvar, int maxLength)
00707 {
00708   ini->Get (section, varname, strvar, maxLength);
00709 }
00710 
00711 
00712 void  SetIniVar(const char *section, const char *varname, int value)
00713 {
00714   ini->Set (section, varname, value);
00715 }
00716 
00717 
00718 void  SetIniFloat(const char *section, const char *varname, float value)
00719 {
00720   ini->Set (section, varname, value);
00721 }
00722 
00723 
00724 void  SetIniString(const char *section, const char *varname, char *strvar)
00725 {
00726   ini->Set (section, varname, strvar);
00727 }
00728 
00729 
SourceForge.net Logo Documentation generated by doxygen