配置文件的读取

ngx_c_conf.h:

#ifndef __NGX_CONF_H__
#define __NGX_CONF_H__

#include <vector>

#include "ngx_global.h" // 一些全局/通用定义

// 类名遵照一定的命名规范,比如这里第一个字母是C,后续的单词首字母大写
class CConfig
{
// 单例设计模式
private:
	CConfig();
public:
	~CConfig();
private:
	static CConfig* m_instance;

public:
	static CConfig* GetInstance()
	{
		if (m_instance == NULL)
		{
			// 锁
			if (m_instance == NULL)
			{
				m_instance = new CConfig();
				static CGarhuishou cl; 
			}
			// 放锁
		}
		return m_instance;
	}

	class CGarhuishou // 类中套类,用于释放对象
	{
	public:
		~CGarhuishou()
		{
			if (CConfig::m_instance)
			{
				delete CConfig::m_instance;
				CConfig::m_instance = NULL;				
			}
		}
	};

public:
    bool Load(const char* pconfName); // 装载配置文件
	const char* GetString(const char* p_itemname);
	int GetIntDefault(const char* p_itemname, const int def);

public:
	std::vector<LPCConfItem> m_ConfigItemList; // 存储配置信息的列表
};

#endif

ngx_c_conf.cxx:

// 系统头文件放上边
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>

// 自定义头文件放下边,因为g++中用了-I参数,所以这里用<>也可以
#include "ngx_func.h" // 函数声明
#include "ngx_c_conf.h" // 和配置文件处理相关的类,名字带c_表示和类有关

// 静态成员赋值
CConfig* CConfig::m_instance = NULL;

// 构造函数
CConfig::CConfig()
{

}

// 析构函数
CConfig::~CConfig()
{
    std::vector<LPCConfItem>::iterator pos;	
	for (pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
	{
        delete (*pos);
	}
    m_ConfigItemList.clear(); 
}

// 装载配置文件
bool CConfig::Load(const char* pconfName)
{
    FILE *fp;
    fp = fopen(pconfName, "r");
    if (fp == NULL) return false;

    // 每一行配置文件读出来都放这里,每行配置都不要太长,保持500字符以内,防止出现问题
    char linebuf[501];

    // 走到这里,文件打开成功
    while (!feof(fp)) // 检查文件是否结束,没有结束则条件成立
    {
        // 注意写法的严密性,商业代码就是要首先确保代码的严密性
        // 从文件中读数据,每次读一行,一行最多不要超过500个字符

        if (fgets(linebuf, 500, fp) == NULL) continue; // 读取失败直接continue

        if (linebuf[0] == 0) continue; // 读到空行直接continue

        // 处理注释行
        if (*linebuf == ';' || *linebuf == ' ' || *linebuf == '#' || *linebuf == '\t' || *linebuf == '\n') continue;
        
    lblprocstring:
        // 屁股后边若有换行、回车、空格等都截取掉
		if (strlen(linebuf) > 0)
		{
			if (linebuf[strlen(linebuf) - 1] == 10 || linebuf[strlen(linebuf) - 1] == 13 || linebuf[strlen(linebuf) - 1] == 32)
			{
				linebuf[strlen(linebuf) - 1] = 0;
				goto lblprocstring;
			}
		}

        if (linebuf[0] == 0) continue; // 空行直接continue

        if (*linebuf == '[') continue; // [开头的也不处理

        // 这种配置项"ListenPort = 5678"走下来
        char* ptmp = strchr(linebuf, '=');
        if (ptmp != NULL)
        {
            LPCConfItem p_confitem = new CConfItem; // 注意前边类型带LP,后边new这里的类型不带
            memset(p_confitem, 0, sizeof(CConfItem));
            strncpy(p_confitem->ItemName, linebuf, (int)(ptmp - linebuf)); // 等号左侧的拷贝到p_confitem->ItemName
            strcpy(p_confitem->ItemContent, ptmp + 1); // 等号右侧的拷贝到p_confitem->ItemContent

            Rtrim(p_confitem->ItemName);
			Ltrim(p_confitem->ItemName);
			Rtrim(p_confitem->ItemContent);
			Ltrim(p_confitem->ItemContent);
            
            // printf("itemname=%s | itemcontent=%s\n", p_confitem->ItemName, p_confitem->ItemContent);
            m_ConfigItemList.push_back(p_confitem); // 内存要释放,因为这里是new出来的
        }
    }

    fclose(fp); // 这步不可忘记

    return true;
}

// 根据ItemName获取配置信息字符串,不修改不用互斥
const char* CConfig::GetString(const char* p_itemname)
{
    std::vector<LPCConfItem>::iterator pos;
    for (pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
	{
        if (strcasecmp((*pos)->ItemName, p_itemname) == 0)
        {
            return (*pos)->ItemContent;
        }
	}
	return NULL;
}

// 根据ItemName获取数字类型配置信息,不修改不用互斥
int CConfig::GetIntDefault(const char* p_itemname, const int def)
{
    std::vector<LPCConfItem>::iterator pos;	
	for (pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
	{
		if (strcasecmp((*pos)->ItemName, p_itemname) == 0)
        {
            return atoi((*pos)->ItemContent);
        }
	}
	return def;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值