/****************************************************************************************** * * 作者: 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 #include #include #ifndef _WIN32 // #include #else #include #include #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 *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 ** 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 *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