INI 文件解析类 StdC++实现

// INI 文件解析类 StdC++实现, Window CE(VS2005)/ Linux(GCC)/ Windows(VS2005)
// ***************************************************************
//  WgtIniFile   version:  1.0   ·  date: 04/14/2009
//  -------------------------------------------------------------
//  
//  -------------------------------------------------------------
//  Copyright (C) 2009 - All Rights Reserved
//  You may free and copy use this source code, but you must add author 
//  information. Thanks.
// ***************************************************************
//   Design and write by Steven.zdwang@gmail.com
// ***************************************************************
#pragma  once
#ifndef CWGTINIFILE_H
#define CWGTINIFILE_H
#include <map>
#include <vector>
#include <fstream>
#include <string>
#include <sstream>
#include <codecvt>
template < class STR_T, class READ_FILE_T, class WRITE_FILE_T >
class CWgtCustomIniFile
{
public:
    //-----------------------------------------------------------
    //    Constructors & Destructor
    //-----------------------------------------------------------
    // Default constructor
    CWgtCustomIniFile()
    {
    }
    virtual ~CWgtCustomIniFile()
    {
    }
    //-----------------------------------------------------------
    //    Load and save ini file
    //-----------------------------------------------------------
    bool loadFromFile(const STR_T& aPathName)
    {
#ifdef UNICODE
        READ_FILE_T fin( aPathName.c_str(), std::ios::binary);
		fin.imbue(std::locale(fin.getloc(),new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>));
#else
		READ_FILE_T fin( aPathName.c_str());
#endif
        if(!fin.is_open())return false;
        m_pathName = aPathName;
        STR_T inbuf;
        while(!fin.eof())
        {
            std::getline(fin, inbuf);
            _trim_string(inbuf, TEXT(" "), true);
            _parser_line(inbuf);
        }
        fin.close();
        return true;
    }
    void saveToFile(const STR_T& aPathName)
    {
        WRITE_FILE_T fout( aPathName.c_str() );
        if( !fout.is_open() ) return;
        STR_T outbuf;
        typename _mem_ini_type::iterator ps;
        typename _key_value_map_type::iterator pk;
        for( ps = m_memIni.begin(); ps != m_memIni.end(); ++ps ){
            // write section name
            fout << std::endl;
            fout << TEXT("[") << ps->first << TEXT("]") << std::endl;
            // write section values
            _key_value_map_type & key_values = ps->second;
            for( pk = key_values.begin(); pk != key_values.end(); ++pk ){
                fout << pk->first << TEXT(" = ") << pk->second << std::endl;
            }
        }
        fout.close();
    }
    void clear()
    {
        m_memIni.clear();
    }
    STR_T getFileName() const { return m_pathName; }
    //------------------------------------------------------------
    //    String Access
    //------------------------------------------------------------
    STR_T getString(const STR_T& aSectionName, const STR_T& aKeyName, const STR_T& aDefaultValue)
    {
        if( !aSectionName.empty() && !aKeyName.empty() ){
            typename _mem_ini_type::iterator ps = m_memIni.find(aSectionName);
            if( ps != m_memIni.end() ){
                typename _key_value_map_type::iterator pk = ps->second.find(aKeyName);
                if( pk != ps->second.end() ){
                    return pk->second;
                }
            }
        }
        return aDefaultValue;
    }
    void setString(const STR_T& aSectionName, const STR_T& aKeyName, const STR_T& aValue)
    {
        if( !aSectionName.empty() && !aKeyName.empty() ){
            m_memIni[aSectionName][aKeyName] = aValue;
        }
    }
    //------------------------------------------------------------
    //    Primitive Data Type Access
    //------------------------------------------------------------
    int getInteger(const STR_T& aSectionName, const STR_T& aKeyName, int aDefaultValue)
    {
        STR_T temp = getString( aSectionName, aKeyName, TEXT("") );
        std::basic_stringstream< typename STR_T::value_type > sstream;
        sstream << temp;
        sstream >> aDefaultValue;
        return aDefaultValue;
    }
    void setInteger(const STR_T& aSectionName, const STR_T& aKeyName, int aValue)
    {
        std::basic_stringstream< typename STR_T::value_type > sstream;
        sstream << aValue;
        setString(aSectionName, aKeyName, sstream.str() );
    }
    bool getBoolean(const STR_T& aSectionName, const STR_T& aKeyName, bool aDefaultValue)
    {
        STR_T temp = getString( aSectionName, aKeyName, TEXT("") );
        if( !temp.empty() ){
            return _string_to_boolean( temp,  aDefaultValue);
        }
        return aDefaultValue;
    }
    void setBoolean(const STR_T& aSectionName, const STR_T& aKeyName, bool aValue)
    {
        setInteger(aSectionName, aKeyName, aValue ? 1 : 0);
    }
    double getDouble(const STR_T& aSectionName, const STR_T& aKeyName, double aDefaultValue)
    {
        STR_T temp = getString( aSectionName, aKeyName, TEXT("") );
        std::basic_stringstream< typename STR_T::value_type > sstream;
        if( !temp.empty() ){
            sstream << temp;
            sstream >> aDefaultValue;
        }
        return aDefaultValue;
    }
    void setDouble(const STR_T& aSectionName, const STR_T& aKeyName, double aValue, int aPrecision)
    {
        std::basic_stringstream< typename STR_T::value_type > sstream;
        if( aPrecision )
            sstream.precision(aPrecision);
        sstream << aValue;
        setString( aSectionName, aKeyName, sstream.str() );
    }
    //------------------------------------------------------------
    //    Section Operations
    //------------------------------------------------------------
    bool isSectionExist(const STR_T& aSectionName) const
    {
        return ( m_memIni.find(aSectionName) != m_memIni.end() );
    }
    void getSectionNames(std::vector<STR_T> & aSectionNames)
    {
        if( !aSectionNames.empty() )
            aSectionNames.clear();
        typename _mem_ini_type::iterator ps = m_memIni.begin();
        for( ; ps != m_memIni.end(); ++ps ){
            aSectionNames.push_back(ps->first);
        }
    }
    bool deleteSection(const STR_T& aSectionName)
    {
        if( aSectionName.empty() ) return false;
        typename _mem_ini_type::iterator ps = m_memIni.find(aSectionName);
        if( ps != m_memIni.end() ){
            m_memIni.erase(ps);
            return true;
        }
        return false;
    }
    //------------------------------------------------------------
    //    Key Operations
    //------------------------------------------------------------
    bool isKeyExist(const STR_T& aSectionName, const STR_T& aKeyName) const
    {
        if( aSectionName.length() == 0 || aKeyName.empty() ) return false;
        typename _mem_ini_type::const_iterator ps = m_memIni.find(aSectionName);
        if( ps != m_memIni.end() ){
            return ( ps->second.find( aKeyName ) !=  ps->second.end() );
        }
        return false;
    }
    void getKeyNames(const STR_T& aSectionName, std::vector<STR_T> & aKeyNames) 
    {
        if( aSectionName.empty() ) return;
        if( !aKeyNames.empty() )
            aKeyNames.clear();
        typename _mem_ini_type::iterator ps = m_memIni.find(aSectionName);
        typename _key_value_map_type::iterator pk;
        if( ps != m_memIni.end() ){
            for( pk = ps->second.begin(); pk != ps->second.end(); ++pk ){
                aKeyNames.push_back( pk->first );
            }
        }
    }
    bool deleteKey(const STR_T& aSectionName, const STR_T& aKeyName)
    {
        if( aSectionName.empty() || aKeyName.empty() ) return false;
        typename _mem_ini_type::iterator ps = m_memIni.find(aSectionName);
        typename _key_value_map_type::iterator pk;
        if( ps != m_memIni.end() ){
            pk = ps->second.find(aKeyName);
            if( pk != ps->second.end() ){
                ps->second.erase(pk);
                return true;
            }
        }
        return false;
    }
protected:
    //------------------------------------------------------------
    //    Helper Functions
    //------------------------------------------------------------
    void _trim_string(STR_T& val, const STR_T& chars, bool strip_all)
    {
        if( val.empty() ) return;
        // delete from head
        while( val.find(chars) == 0 ){
            val.erase( 0, chars.length() );
            if( !strip_all ) break;
        }
        // delete from tail
        while( !val.empty() && (val.rfind(chars) == (val.length() - chars.length())) ){
            val.erase( val.length() - chars.length(), chars.length() );
            if( !strip_all ) break;
        }
    }
    STR_T _middle_string(const STR_T& value, const STR_T& first, const STR_T& last)
    {
        STR_T result;
        if( !value.empty() ) {
            typename STR_T::size_type pos_begin = 0, pos_end = 0;
            if( !first.empty() ){
                pos_begin = value.find(first);
                if(pos_begin == STR_T::npos) return result;
                pos_begin += first.size();
            }else{
                pos_begin = 0;
            }
            if( !last.empty() ){
                pos_end = value.find(last, pos_begin);
                if(pos_end == STR_T::npos) return result;
                result = value.substr(pos_begin, pos_end - pos_begin);
            }else{
                result = value.substr(pos_begin, STR_T::npos);
            }
        }
        return result;
    }
    void _parser_line(const STR_T& val)
    {
        if( val.empty() ) return;
        switch( val[0] ){
        case TEXT('[') :
            {
                STR_T aSectionName = _middle_string( val, TEXT("["), TEXT("]") );
                _trim_string( aSectionName, TEXT(" "), true );
                if( !aSectionName.empty() )
                    m_activeSectionName = aSectionName;
            }
        return;
        case TEXT('#') :
        return;
        default:
            {
                if( val.find(TEXT("=")) != STR_T::npos && !m_activeSectionName.empty() ){
                    STR_T aKeyName =  _middle_string(val, TEXT(""), TEXT("=") );
                    _trim_string( aKeyName, TEXT(" "), true );
                    STR_T aKeyValue = _middle_string(val, TEXT("="), TEXT("") );
                    _trim_string( aKeyValue, TEXT(" "), true );
                    if( !aKeyName.empty() )
                        m_memIni[m_activeSectionName][aKeyName] = aKeyValue;
                }
                return;
            }
        }
    }
    bool _string_to_boolean(const STR_T& aStringValue, bool aDefaultValue)
    {
        // Default: empty string
        // TRUE: "true", "yes", non-zero decimal numner
        // FALSE: all other cases
        if ( aStringValue.empty() )
            return aDefaultValue;
        std::basic_stringstream< typename STR_T::value_type > sstream;
        sstream << aStringValue;
        int val = 0;
        sstream >> val;
        return (aStringValue.compare(TEXT("true")) == 0 || val > 0);
    }
    //------------------------------------------------------------
    //    Member Data
    //------------------------------------------------------------
    STR_T m_pathName; // Stores path of the associated ini file
    STR_T m_activeSectionName;
    typedef std::map< STR_T, STR_T > _key_value_map_type;
    typedef std::map< STR_T,  _key_value_map_type > _mem_ini_type;
    _mem_ini_type m_memIni;
};
typedef CWgtCustomIniFile< std::wstring, std::wifstream, std::wofstream >   CWgtUnicodeIniFile;
typedef CWgtCustomIniFile< std::string, std::ifstream, std::ofstream >   CWgtIniFile;
#endif // CWGTINIFILE_H


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值