You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

515 lines
15 KiB
C

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/******************************************************************************************
*
* 作者: m.j.y
*
* Pgc配置文件读写等操作--内部函数定义
*
* $Log: Profile_Hash.h,v $
* Revision 1.2 2006/08/04 03:37:33 zhuzhenhua
* no message
*
* Revision 1.1.2.1 2006/07/28 07:54:02 zhuzhenhua
* no message
*
* Revision 1.4 2003/07/14 01:56:23 scada
* 使用def文件导出函数
*
* Revision 1.3 2003/06/05 03:56:16 jehu
* 将注释修改为符合doxgen工具提取开发文档
*
* Revision 1.2 2002/12/04 07:47:36 scada
* for NT
*
* Revision 1.1.1.1 2002/08/21 07:16:37 harold
* temporarily import
*
* Revision 1.14 2002/06/03 10:07:04 mhorse
* 更改了宏的值
*
* Revision 1.13 2002/03/20 03:40:02 harold
* no message
*
* Revision 1.1.1.1 2002/03/15 13:43:18 harold
* no message
*
* Revision 1.1.1.1 2002/03/15 08:17:08 harold
* no message
*
* Revision 1.12 2002/01/23 05:27:39 harold
* no message
*
* Revision 1.11 2002/01/23 02:39:57 harold
* test_function
*
* Revision 1.10 2002/01/22 08:54:26 harold
* modify2002-01-22-16:46
*
* Revision 1.9 2002/01/21 12:58:49 harold
* no message
*
* Revision 1.8 2002/01/21 04:52:41 harold
* no message
*
* Revision 1.7 2002/01/18 12:56:14 harold
* revise errno
*
* Revision 1.6 1997/03/29 12:49:05 harold
* revise bug in read/write/listsec function
*
* Revision 1.5 2002/01/18 01:08:03 harold
* revise bugs in write/close/listsec function
*
* Revision 1.4 2002/01/16 09:49:41 harold
* no message
*
* Revision 1.3 2002/01/16 08:13:41 harold
* no message
*
* Revision 1.2 2002/01/09 09:42:40 harold
* no message
*
*
******************************************************************************************/
#ifndef profile_hashisdjfidsxxxxxxxxxxxxxijpsijfspo
#define profile_hashisdjfidsxxxxxxxxxxxxxijpsijfspo
/*!
* \if developer_doc
* \file
*
* \brief Pgc配置文件读写等操作--内部函数定义头文件。
*
* id: $Id: Profile_Hash.h,v 1.2 2006/08/04 03:37:33 zhuzhenhua Exp $
*
* \author 杨小波 prcharold@sina.com.cn develop1@szscada.com
* \endif
*/
//#include <util/util.h>
#include <string.h>
#include <stdio.h>
//#ifdef OS_LINUX
// #include <sys/time.h>
//#else
#include <winsock.h>
#include <time.h>
//#endif //OS_LINUX
#include "global_errno.h"
#include "typedef.h"
//#include "basetype.h"
#include "harximoban.h"
/*!
* \if by_group
* \addtogroup grp_config_rw
* @{
* \endif
*/
/*!
* 配置文件中, 每一行的最大长度
*/
#define MAX_CONF_LINE_L (1024)
//!< 定义每行(注释行的字符个数无限制)允许的最大字符个数, 包括换行符号'\r\n'及null字符
#define MAX_CHAR_LINE (MAX_CONF_LINE_L)
#ifndef PATH_MAX
#define PATH_MAX 260
#endif
#define MAX_PATH 260
//!< 定义存储文件路径的字符串数组的大小
#define MAX_PATH_NUM (MAX_PATH)
//在重新生成配置文件时,是否将'\r\n'作为行结束标志
//#define REWRITEFILE_ADDCHAR_13
//!< 设置缓冲区的最大段数
#define MAX_SEC_NUM 2500
//!< 设置缓冲区的每一段的最大项目个数
#define MAX_ITEM_NUM 30
//!< 定义初始化缓冲区容纳项目的个数
#define INITCACHE_ITEM_NUM 5000
//!< 缓冲区增大时的递增项目的个数
#define RESIZE_ITEM_NUM 5000
//!< 定义在一个进程中允许同时打开的配置文件缓冲句柄的个数
#define MAX_PROFILEHANDLE_NUM 50
//!< 定义配置文件缓冲句柄
typedef pgc32 HPROFILE;
//!< 保存注释的链表
typedef struct tagMemoChain
{
pgcchar *szMemo;
tagMemoChain * NextNode;
} SMemoChain;
//!< 缓冲项的结构
typedef struct tagItemInCache
{
pgcchar szItemName[MAX_CHAR_LINE];
pgcchar szItemVal[MAX_CHAR_LINE];
pgcchar szSecName[MAX_CHAR_LINE];
PGCBOOL valid;
PGCBOOL bIsSecName;
SMemoChain *memo;
tagItemInCache()
{
memset(this, 0, sizeof(*this));
}
} SItemInCache;
//!< 项目位置链表结构
typedef struct tagItemSequence
{
pgc32 iPos;
tagItemSequence *NextNode;
tagItemSequence()
{
memset(this, 0, sizeof(*this));
}
} SItemSequence;
//!< 定义存储句柄对应的信息的结构
typedef struct tagProfileHanleInfo
{
FILE *fstream;
//!< 保存配置文件全路径名
pgcchar szPathName[MAX_PATH_NUM];
//!< 配置文件上一次被修改的时间
timeval tLastModify;
//!< 哈希表指针
TChainHash<SItemInCache> *pHashTable;
//!< 行位置链表头指针
SItemSequence *pSequence;
//!< 行位置链表当前指针
SItemSequence *pCurSeq;
//!< 缓冲区数组入口
SItemInCache* pCacheEntry;
//!< 段总数
pgc32 CurSecNum;
//!< 当前缓冲区能容纳的项目个数
pgc32 CurItemCount;
//!< 已经使用的项目个数
pgc32 CurUseItems;
//!< 当前文件中的行数
pgc32 CurLines;
tagProfileHanleInfo()
{
memset(this, 0, sizeof(*this));
}
} SProfileHanleInfo;
/*!
* \brief 根据已知的历史数据库索引数组, 为其建立一个哈希表.
*
* \param pindex --[in] 索引数组的指针
* \param count --[in] pindex索引数组中索引的个数, pindex[0] -- pindex[count - 1]为索引
* \param pphash_of_index --[in] 将pindex所指向的数组哈希化, 这样, 在随后的索引搜索时, 使用该哈希索引.
*
* \retval SUCCESS -- 成功
* \retval 其它 -- 失败代码
*
*/
pgc32 profile_build_hash_index ( SItemInCache * pindex,
pgc32 count,
TChainHash<SItemInCache> ** pphash_of_index );
/*!
* \brief 在索引区中搜索
*
* \param pindex_base --[in] 被哈希化的索引数组的指针
* \param phash_of_index --[in] 索引数组的哈希表
* \param szSecName --[in] 被查询的段名
* \param szItemName --[in] 被查询的项目名
*
* \retval 索引在索引数组中的序号 -- 成功的查找到指定的配置项目的索引
* \retval -1 -- 失败
*/
pgc32 profile_search_sequence ( SItemInCache **pindex_base,
TChainHash<SItemInCache> *phash_of_index,
pgcchar *szSecName,
pgcchar *szItemName);
/*!
* \brief 判断某行是否被注释。
*
* \param szLine --[in] 行字串
*
* \retval PGCTRUE 是注释行
* \retval PGCFALSE 不是注释行
*/
PGCBOOL LineIsMark(pgcchar *szLine);
/*!
* \brief 寻找段尾。
*
* \param szString --[in] 字串
*
* \retval 字船指针 段尾的位置指针
* \retval NULL 没找到段尾
*/
pgcchar* FindSecTail(pgcchar *szString);
/*!
* \brief 提取段名。
*
* \param szString --[in] 需要提取段名的字串。
* \param szRevBuffer --[out] 段名字串缓冲,返回的段名保存在此。
* \param iBufferLength --[in] 段名字串缓冲空间的长度。
*
* \retval PGCTRUE 提取段名成功
* \retval PGCFALSE 提取段名失败
*/
PGCBOOL DigSecName(const pgcchar *szString, pgcchar *szRevBuffer, pgc32 iBufferLength);
/*!
* \brief 提取项目名及项目值。
*
* \param szString --[in] 需要提取项目名及项目值的字串。
* \param szItemName --[in] 行字符串头指针。
* \param szItemVal --[out] 项目值字串缓冲,返回的项目值保存在此。
* \param iBufferLength --[in] 项目值字串空间的长度。
*
* \retval PGCTRUE 成功
* \retval PGCFALSE 失败
*/
PGCBOOL DigItemContent( pgcchar *szString, pgcchar *szItemName, pgcchar *szItemVal, pgc32 iBufferLength);
/*!
* \brief 添加一个节点到顺序链表中。
*
* \param psHead --[in] 顺序链表头节点的指针。
* \param iPos --[in] 该节点要保存的缓冲数组的偏移位置。
*
* \retval PGCTRUE 成功
* \retval PGCFALSE 失败
*/
PGCBOOL AddNode(SItemSequence * &psHead, pgc32 iPos);
/*!
* \brief 释放配置文件缓冲句柄。
*
* \param hProfile --[in] 配置文件缓冲句柄。
*/
void ReleaseProfileCache(HPROFILE hProfile);
/*!
* \brief 重写配置文件。
*
* \param hProfile --[in] 配置文件缓冲句柄。
*
* \retval SUCCESS 成功。
* \retval 其它 失败,错误代码。
*/
pgc32 ReWriteProfile(HPROFILE hProfile);
/*!
* \brief 创建文件句柄缓冲。
*
* \param hProfile --[in] 配置文件缓冲句柄。
*
* \retval SUCCESS 成功。
* \retval 其它 失败,错误代码。
*/
pgc32 ProcessCreateCache(HPROFILE hProfile);
//-----------------------------------------------------------------------------------------
/*!
*\verbatim
//以下为应用接口
******************************************************************************************
*
* 作者: m.j.y
*
* Pgc读配置文件--外部函数定义(供外部调用人员使用)
*
******************************************************************************************
*\endverbaim
*/
/*!
* \brief 建立配置文件缓冲。
*
* \param szProfileName --[in] 配置文件全路径名。
* \param phfile --[out] 如果函数执行成功,则返回一个句柄。
*
* \retval SUCCESS -- 成功建立配置文件缓冲。
* \retval 失败则返回具体的执行失败的代码。
* \retval ERROR_CONF_NOHANDLE -- 建立配置文件缓冲失败,原因:没有空闲的配置文件缓冲句柄分配给当前配置文件缓冲。
* \retval ERROR_FOPEN -- 打开文件失败。
* \retval ERROR_FREAD -- 读文件失败。
* \retval ERROR_CONF_CREATEHASH -- 建立哈希表失败。
* \retval ERROR_MEMORY_ALLOC -- 不能不能分配指定大小的内存。
*/
int create_profile_cache(pgcchar *szProfileName, int *phfile);
/*!
* \brief 关闭配置文件缓冲。
*
* 函数逻辑:根据在该配置文件缓冲句柄中记录的信息,释放资源.
*
* \param hProfile --[in] 配置文件缓冲句柄。
*
* \retval SUCCESS -- 成功。
* \retval 失败则返回具体的执行失败的代码。
* \retval ERROR_CONF_INVALIDHANDLE -- 输入了非法的配置文件缓冲句柄。
*/
int close_profile_handle(HPROFILE hProfile);
/*!
* \brief 根据段名,项目名获取项目值。
*
* 函数逻辑:调用者通过参数lpAppName lpKeyName传入要取出的项目值所在的段名和项目名
* 如果指定的段及项目名存在函数将取出的项目值拷贝到以lpReturnedString为首地址的
* 目标缓冲中(目标缓冲的长度通过指针pdwSize传入),随后函数会将取出的项目值
* 的长度(包括'\0'字符)写入地址指针pdwSize中 如果指定的段及项目名不存在,则执行缺省拷贝,即将
* lpDefault 所指向的字符串拷贝到目标缓冲区lpReturnedString中; 如果目标缓冲区的首地址
* lpReturnedString为空或传入的目标缓冲的长度小于1那么函数不会将任何字符串拷贝到
* 目标缓冲,但是仍会将取出的项目值的长度(包括'\0'字符)写入地址指针pdwSize中。
*
* \param lpAppName --[in] 段名。
* \param lpDefault --[in] 当获取指定的项目值失败时将该缓冲区的字符串写入lpReturnedString目标缓冲。
* \param lpReturnedString --[out] 目标缓冲区,用来存放取出的项目值。
* \param pdwSize --[in][out] 指向缓冲区的长度的指针,同时在调用结束后,将取出的项目字符串的长度(包括'\0'字符)写入该地址。
* \param hProfile --[in] 配置文件缓冲句柄。
*
* \retval SUCCESS -- 成功如果指定的段及项目名存在函数将取出的项目值拷贝到以lpReturnedString为首地址的
* 目标缓冲中如果取出的项目值的长度小于或等于目标缓冲区的长度那么整个项目值将被完全拷贝到目标缓冲中此时函数返回SUCCESS。
* \retval ERROR_CONF_REVBUFFER -- 如果指定的段及项目名存在,但是取出的项目值的长度大于目标缓冲区的长度,
* 那么取出的项目值将被截断为和目标缓冲区一样的大小然后再拷贝到目标缓区此时函数返回ERROR_CONF_REVBUFFER。
* \retval SUCCESS_CONF_DEFCOPY -- 如果指定的段及项目名不存在并且lpDefault指针不为空则函数将lpDefault所指向的字符串拷贝到目标缓冲区lpReturnedString
* 如果lpDefault指向的字符串的长度大于目标缓冲区的长度那么只从lpDefault开始拷贝 [目标缓冲区的长度 1]个字符到缓冲中。
* \retval ERROR_CONF_INVALIDHANDLE -- 输入了非法的配置文件缓冲句柄。
* \retval ERROR_FAIL -- 函数执行失败,即未拷贝任何字符到目标缓冲区。
*/
int get_pgcprofile_string(
const pgcchar * lpAppName, // points to section name
const pgcchar * lpKeyName, // point to key name
const pgcchar * lpDefault, // point to default string
pgcchar * lpReturnedString, // point to destination buffer
pgcu32 * pdwSize, // point to size of destination buffer
HPROFILE hProfile // point to initialization filename
);
/*!
* \brief 根据段名,项目名写项目值。
*
* 函数逻辑: 调用者通过参数lpAppName lpKeyName传入要写入的项目值所在的段名和项目名
* 如果指定的段及项目名存在函数将把lpString所指向的以空字符结尾的字符串拷贝到
* 以该段名,项目名对应的项目值缓冲中,然后再把整个配置文件缓冲的内容写入到文件中,
* 并返回SUCCESS;如果指定的段及项目名不存在函数会根据参数bInsertItem的值决定是否将输入的段名以及
* 项目名添加到配置文件中如果bInsertItem为真则添加该段名和项目名然后写入项目值
* 并返回SUCCESS; 如果bInsertItem为假函数返回ERROR_FAIL。
*
* \param lpAppName --[in] 段名
* \param lpKeyName --[in] 项目名
* \param lpString --[in] 要写入的字符串
* \param hProfile --[in] 配置文件缓冲句柄
* \param bInsertItem --[in] 当指定的段名或项目名不存在时是否添加该段或项目PGCTRUE-添加PGCFALSE-不添加(缺省)
*
* \retval SUCCESS(0) -- 如果指定的段及项目名存在函数将把lpString所指向的以空字符结尾的字符串拷贝到
* 以该段名,项目名对应的项目值缓冲中,然后再把整个配置文件缓冲的内容写入到文件中,并返回SUCCESS
* \retval ERROR_FWRITE -- 写文件错误
* \retval ERROR_CONF_INVALIDHANDLE -- 输入了非法的配置文件缓冲句柄
* \retval ERROR_FAIL -- 函数执行失败,即未将任何字符写到配置文件缓冲区以及文件
*/
int write_pgcprofile_string(
const pgcchar * lpAppName, // point to section name
const pgcchar * lpKeyName, // point to key name
const pgcchar * lpString, // point to string to add
HPROFILE hProfile, // handle to Profile Cache
PGCBOOL bInsertItem
);
/*!
* \brief 获取配置文件的所有段名。
*
* 函数逻辑将从配置文件中获取的段名按在文件中出现的先后次序写到pdwSize所指向的地址空间
* 每个段名以一个空字符作为结束标志,在最后一个段名的结尾处再多加一个空字符
* 作为所有全部段名的结束标志,即内存格式为 段名1\0段名2\0......最后一个段名\0\0
*
* \param lpszReturnBuffer --[out] 写入缓冲区。
* \param pdwSize --[in][out] 写入缓冲区的按字节长度。
* \param nSecNum --[out] 将获取的段总数写入该地址。
* \param hProfile --[in] handle to Profile Cache
*
* \retval SUCCESS -- 成功
* \retval 其它 -- 失败则返回具体的执行失败的代码
*/
int get_pgcprofile_secnames(
pgcchar * lpszReturnBuffer, // address of return buffer
pgcu32 * pdwSize, // size of return buffer
pgcu32 *nSecNum,
HPROFILE hProfile // handle to Profile Cache
);
/*!
* \brief 删除指定的项目。
*
* 函数逻辑:在缓冲中删除指定的项目,以及该项目上方的注释,然后以覆盖方式重写文件。
*
* \param lpAppName --[in] 段名
* \param lpKeyName --[in] 项目名
* \param hProfile --[in] 配置文件的缓冲句柄
*
* \retval SUCCESS -- 成功
* \retval 其它 -- 失败则返回具体的执行失败的代码
*/
int del_pgcprofile_key( const pgcchar * lpAppName, // point to section name
const pgcchar * lpKeyName, // point to key name
HPROFILE hProfile // point to initialization filename
);
/*!
* \brief 删除指定的段。
*
* 函数逻辑:在缓冲中删除指定的段,以及该段上方的注释,然后以覆盖方式重写文件;
* 在删除一个段的同时,该段下属的所有项目(包括项目上方的注释)将被删除。
*
* \param lpAppName --[in] 段名
* \param hProfile --[in] 配置文件的缓冲句柄
*
* \retval SUCCESS -- 成功
* \retval 其它 -- 失败则返回具体的执行失败的代码
*/
int del_pgcprofile_sec( const pgcchar * lpAppName,
HPROFILE hProfile
);
/*!
* \brief 时间比较, 并返回其差值的绝对值
*
* \param ptv1 --[in] 时间1
* \param ptv2 --[in] 时间2
* \param ptv_abs_delta --[out] 返回差值的绝对值, 如果该参数不为0.
*
* \retval 小于0 -- ptv1 小于(早于) ptv2
* \retval 等于0 -- ptv1 等于(等于) ptv2
* \retval 大于0 -- ptv1 大于(晚于) ptv2
*/
int timeval_compare (
const timeval * ptv1,
const timeval * ptv2,
timeval * ptv_abs_delta = 0 );
/*!
* \if by_group
* @}
* \endif
*/
#endif