⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 configfile.cpp

📁 C++连接一写常用数据库的接口
💻 CPP
字号:
/*
 * ConfigFile and ConfigSections Objects allows the reading and writing of config files
 * and name value pairs within sections of the config files.
 * Copyright (C) 2002 Johnathan Ingram, jingram@rogue-order.net
 *
 * This library is free software; you can redistribute it and/or
 *   modify it under the terms of the GNU Lesser General Public
 *   License as published by the Free Software Foundation; either
 *   version 2.1 of the License, or (at your option) any later version.
 *
 *   This library 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
 *   Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  US
 *
 */

#include "configFile.h"

#include "string.h"
#include "ctype.h"


//------------------------------------------------------------------------------
// ConfigSection::ConfigSection
//------------------------------------------------------------------------------
ConfigSection::ConfigSection(const string& sectionName)
   : sectionName(sectionName)
{
   
} // ConfigSection::ConfigSection


//------------------------------------------------------------------------------
// ConfigSection::operator[]
//------------------------------------------------------------------------------
const string& 
ConfigSection::operator[]
      (const string& name) 
   throw 
      (NameKeyNotFoundError)
{
   // Find the section or throw an exception.   
   // Find the section as lower case or throw an exception.   
   string nameLower = name;
   for (int i=0; i<nameLower.length(); i++)
      nameLower[i] = tolower(nameLower[i]);

   ValuesIterator it = values.find(nameLower);
   
   if (it == values.end())
   {
      string errMsg = "The name key ";
      errMsg        += name.c_str();
      errMsg        += " does not exist in the config section ";
      errMsg        += sectionName.c_str();
      throw NameKeyNotFoundError(errMsg);      
   }
  
   return (const string&)it->second;
} // ConfigSection::operator[]



//------------------------------------------------------------------------------
// ConfigFile::ConfigFile
//------------------------------------------------------------------------------
ConfigFile::ConfigFile(const string& aConfigFile)
: configFile(aConfigFile)
{
 
}  // ConfigFile::ConfigFile


//------------------------------------------------------------------------------
// ConfigFile::~ConfigFile
//------------------------------------------------------------------------------
ConfigFile::~ConfigFile()
{
}  // ConfigFile::~ConfigFile



//------------------------------------------------------------------------------
// ConfigFile::operator[]
//------------------------------------------------------------------------------
ConfigSection& 
ConfigFile::operator[](
      const string& section)
   throw(
      SectionNotFoundError)      
{
   // Find the section as lower case or throw an exception.   
   string sectLower = section;
   for (int i=0; i<sectLower.length(); i++)
      sectLower[i] = tolower(sectLower[i]);
      
   ConfigSectionsIterator it = configSections.find(sectLower);
   
   if (it == configSections.end())
   {
      string errMsg = "The section ";
      errMsg        += section.c_str();
      errMsg        += " does not exist in the config file.";
      throw SectionNotFoundError(errMsg);      
   }
  
   return it->second;
} // ConfigFile::operator[]


//------------------------------------------------------------------------------
// ConfigFile::read
//------------------------------------------------------------------------------
void 
ConfigFile::read()
{
   // Synchronize the function.
   SimpleThread_Synchronize sync(classMutex);

   string currentSection;
   
   char maxLine[2048];       // Line can be a maximum of 2048 characters big.
   char *ptr, *ptr2, *ptr3;
   int  i;

   ifstream in;
   in.open(configFile.c_str());

   // Make sure we opened the file.
   if (in.fail())
   {
      string errMsg = "Unable to open the configuration file: ";
      errMsg       += configFile.c_str();
      throw OpenError(errMsg.c_str());
   }

   // Start with the global config section.
   currentSection = "";
   configSections.insert(ConfigSectionsPair(currentSection.c_str(), ConfigSection(currentSection)) );     
   

   // Read and process all the lines that are read in.
   while(in)
   {
      memset(maxLine, 0, sizeof(maxLine));
      in.getline(maxLine, sizeof(maxLine)-1);
      
      // Strip any '#' comments and ignore.
      ptr = strchr(maxLine, '#');
      if (ptr)
         ptr[0] = '\0';      

      // Make sure we have no \n or \r still in the line.
      ptr = strchr(maxLine, '\n');
      if (ptr)
         ptr[0] = '\0';      
      ptr = strchr(maxLine, '\r');
      if (ptr)
         ptr[0] = '\0';      
      
      
      // Don't waste time processing empty or too short lines.
      if (strlen(maxLine) > 3)
      {
         // Check if we have a new section and add it as the current section.
         if ((ptr = strchr(maxLine, '[')) && (ptr2 = strchr(maxLine, ']')) )
         {
            // Get the section name.
            ptr += 1;
            ptr2[0] = '\0';
            
            //Convert the section name to lower case
            for (i=0; i<strlen(ptr); i++)
               ptr[i] = tolower(ptr[i]);

            currentSection = ptr;
            configSections.insert(ConfigSectionsPair(currentSection.c_str(), ConfigSection(currentSection)) );
         }
         // else do we have a name value pair.
         else if ((ptr = strchr(maxLine, '=')) )
         {
            ptr3 = ptr + 1;   // Point to first char after = sign for start of value.           
            ptr[0] = '\0';

            // Lets get the name and strip any leading and trailing spaces. ptr=name
            //Convert the name to lower case
            for (i=0; i<strlen(maxLine); i++)
               maxLine[i] = tolower(maxLine[i]);
                             
            // Leading
            ptr = maxLine;
            for (i=0; i<strlen(maxLine); i++)
               if (maxLine[i] != ' ')
               {
                  ptr = maxLine + i;
                  break;
               }
               
            // Trailing
            for (i=strlen(maxLine)-1; i>=0; i--)
               if (maxLine[i] == ' ')
                  maxLine[i] = '\0';
               else
                  break;            
            
            // Lets get the value and strip any trailing and leading spaces. ptr2=value
            // Leading
            ptr2 = ptr3;
            for (i=0; i<strlen(ptr3); i++)
               if (ptr3[i] != ' ')
               {
                  ptr2 = ptr3 + i;
                  break;
               }
               
            // Trailing
            for (i=strlen(ptr3)-1; i>=0; i--)
               if (ptr3[i] == ' ')
                  ptr3[i] = '\0';
               else
                  break;


            // Now add the name value pair to the section if it is unique.
            ConfigSectionsIterator it = configSections.find(currentSection);
            
            ConfigSection::ValuesIterator itValue = it->second.values.find(string(ptr));
            if (itValue != it->second.values.end())
            {
               string errMsg = "The section ";
               errMsg        += currentSection.c_str();
               errMsg        += " contains a duplicate key name: ";
               errMsg        += ptr;
               throw DuplicateNameError(errMsg);
            }

            ConfigSection::Value val;
            val.value = ptr2;
            val.status = ConfigSection::CURRENT;
            it->second.values.insert( ConfigSection::ValuesPair(ptr, val) );            
         }
         
         //If none of the above then ignore the line.  
      }           
   }

   in.close();   
}  // ConfigFile::read



//------------------------------------------------------------------------------
// ConfigFile::write
//------------------------------------------------------------------------------
void 
ConfigFile::write()
{
   // Synchronize the function.
   SimpleThread_Synchronize sync(classMutex);

   // TODO 
   // (Only try write values that have been flagged as new or changed)   

} // ConfigFile::write



//------------------------------------------------------------------------------
// ConfigFile::hasSection
//------------------------------------------------------------------------------
bool 
ConfigFile::hasSection(
      const string& section)
{
   try
   {   
      // Try and get the config section object for the section name
      // using the subscript operator.
      (*this)[section];
      return true;
   }
   catch(...)
   {
      return false;      
   }      
} // ConfigFile::hasSection      
   


//------------------------------------------------------------------------------
// ConfigFile::hasKeyName
//------------------------------------------------------------------------------
bool 
ConfigFile::hasKeyName(
      const string& section, 
      const string& name)
{
   try
   {   
      // Try and get the key name value using the subscript operators.
      (*this)[section][name];
      return true;
   }
   catch(...)
   {
      return false;      
   }      
} // ConfigFile::hasKeyName



//------------------------------------------------------------------------------
// ConfigFile::getSectionNames
//------------------------------------------------------------------------------
vector<string>
ConfigFile::getSectionNames()
{
   vector<string> sectionNames;
   
   ConfigSectionsIterator i;
   for (i = configSections.begin(); i != configSections.end(); i++)
      sectionNames.push_back(i->first.c_str());
      
   return sectionNames;   
} // ConfigFile::getSectionNames



//------------------------------------------------------------------------------
// ConfigFile::getSectionKeyNames
//------------------------------------------------------------------------------
vector<string>
ConfigFile::getSectionKeyNames(
      const string& section)
{
   // Find the section as lower case or throw an exception.   
   string sectLower = section;
   for (int i=0; i<sectLower.length(); i++)
      sectLower[i] = tolower(sectLower[i]);
      
   ConfigSectionsIterator it = configSections.find(sectLower);
   
   if (it == configSections.end())
   {
      string errMsg = "The section ";
      errMsg        += section.c_str();
      errMsg        += " does not exist in the config file.";
      throw SectionNotFoundError(errMsg);      
   }
   
   // Build the list of keyname;
   vector<string> keyNames;
   ConfigSection::ValuesIterator p;

   for (p = it->second.values.begin(); p != it->second.values.end(); p++)
      keyNames.push_back(p->first.c_str());

   return keyNames;   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -