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.

1873 lines
47 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.

/*****************************************************************************
*
* Copyright (C) 1999-2001 SCADA Technology Control Co., Ltd. All rights reserved.
*
* 配置文件处理与哈希索引处理的有关的头文件
*
* m.j.y 2001/12/07
*
*
*
* $Name: $
*
* $Revision: 1.2 $
*
* $Date: 2006/08/04 03:37:33 $
*
* $State: Exp $
*
* $Log: Profile_Hash.cpp,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.5 2003/07/14 02:22:38 scada
* 使用def文件导出函数,而不是使用SCADA_API.
*
* Revision 1.4 2003/01/02 03:14:50 scada
* trim substitution line
*
* Revision 1.3 2002/12/04 07:47:09 scada
* for NT
*
* Revision 1.2 2002/09/24 05:58:34 harold
* take acount __OS_SOLARIS__ where __OS__ occur, set errno to 0 before use it
*
* Revision 1.1.1.1 2002/08/21 07:16:39 harold
* temporarily import
*
* Revision 1.21 2002/06/03 10:06:27 mhorse
* 更改了AddNode函数
*
* Revision 1.20 2002/03/20 03:40:21 harold
* no message
*
* Revision 1.1.1.1 2002/03/15 13:43:21 harold
* no message
*
* Revision 1.1.1.1 2002/03/15 08:17:11 harold
* no message
*
* Revision 1.19 2002/03/06 01:27:52 harold
* *** empty log message ***
*
* Revision 1.18 2002/02/25 07:30:21 harold
* no message
*
* Revision 1.17 2002/01/25 09:11:19 harold
* no message
*
* Revision 1.16 2002/01/23 02:38:06 harold
* test_function
*
* Revision 1.15 2002/01/22 08:51:42 harold
* modify2002-01-22-16:46
*
* Revision 1.14 2002/01/21 06:15:49 harold
* 修改了函数返回值及参数
*
* Revision 1.13 2002/01/21 05:55:25 mhorse
* 修改了函数返回值及参数
*
* Revision 1.11 2002/01/18 12:57:15 harold
* revise errno
*
* Revision 1.10 1997/03/29 12:48:33 harold
* revise bug in read/write/listsec function
*
* Revision 1.9 2002/01/18 01:09:33 harold
* revise bugs in write/close/listsec function
*
* Revision 1.8 2002/01/09 11:37:11 harold
* no message
*
*
* Revision 1.2 2001/12/19 02:19:22 mhorse
* 第2次修改
*
* Revision 1.1.1.1 2001/12/18 06:42:11 mhorse
* 马健莹第一次把配置文件读写库模块加入CVS(2001/12/18)
*
*
******************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#ifdef OS_WINDOWS
#include <winsock2.h>
#include <windows.h>
#include <io.h>
#else
//#include <curses.h>
#include <sys/types.h>
//#include <global_errno.h>
// #include <sys/uswitch.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#endif
#include "Profile_Hash.h"
#include "confrw_errno.h"
//#include "util.h"
#include "common.h"
#include "basefunc.h"
//定义句柄记录数组
static SProfileHanleInfo g_pHandleIndex[MAX_PROFILEHANDLE_NUM];
//句柄记录数组是否经过初始化 PGCTRUE-已经被初始化
static PGCBOOL g_bHandleInit = PGCFALSE;
//定义行注释符
#define MARK_pgcchar_NUM 2
static pgcchar gs_szMarkpgcchar[MARK_pgcchar_NUM] = {';', '#'};
//行结尾字符为\n,不包括\r
//#define LINE_EXCLUDE_0A
// 函数名 : UpperCase
// 函数说明 : 将小写转为大写
// 返回值说明 : pgcchar -- 转换后的字符
// 参数说明 : cCh -- 源字符
pgcchar* UpperCase(pgcchar *szSource)
{
pgcchar* pcTemp = szSource, *pcFirst = szSource;
if (pcTemp == NULL)
return NULL;
while (*pcTemp != '\0')
{
if ((*pcTemp >= 'a') && (*pcTemp <= 'z'))
*pcTemp = (pgcchar)(*pcTemp - ('a' - 'A')) ;
pcTemp++;
}
return pcFirst;
}
/*
* 哈希函数
*/
// 给出关键字, 求同义词序号
static u32 fnhash_index_of(const void * pKey, u32 hash_size);
// 求关键字
static void * fnhash_key_of(const SItemInCache * pindex);
// 比较关键字
static int fnhash_compare(const void * pKey1, const void * pKey2);
/*
* 根据已知的历史数据库索引数组, 为其建立一个哈希表.
*
* 参数
* pindex -- 索引数组的指针
* count -- pindex索引数组中索引的个数, pindex[0] -- pindex[count - 1]为
* 索引
* pphash_of_index -- 将pindex所指向的数组哈希化, 这样, 在随后的索引搜索
* 时, 使用该哈希索引.
*
* 返回值
* SUCCESS -- 成功
* 其它 -- 失败代码
*
*/
#define INDEX_HASH_TABLE_SIZE_FACTOR 20
pgc32 profile_build_hash_index ( SItemInCache * pindex,
pgc32 count,
TChainHash<SItemInCache> ** pphash_of_index )
{
pgc32 i = 0;
TChainHash<SItemInCache> * phash_table = NULL;
phash_table = new TChainHash<SItemInCache>(count * INDEX_HASH_TABLE_SIZE_FACTOR,
fnhash_index_of,
fnhash_key_of,
fnhash_compare,
NULL/*fnhash_create_item*/,
NULL/*fnhash_free_item*/,
NULL/*fnhash_copy_item*/,
NULL/*fnhash_alloc*/,
NULL/*fnhash_dealloc*/);
if (phash_table == NULL)
return ERROR_MEMORY_ALLOC;
for(i = 0; i < count; i++)
phash_table->insertItem(pindex + i);
*pphash_of_index = phash_table;
return SUCCESS;
}
/*
* 在索引区中搜索
*
* 参数
* pindex_base -- 被哈希化的索引数组的指针
* phash_of_index -- 索引数组的哈希表
* szSecName -- 被查询的段名
* szItemName - 被查询的项目名
*
* 返回值
* 索引在索引数组中的序号 -- 成功的查找到指定的配置项目的索引
* -1 -- 失败
*/
pgc32 profile_search_sequence ( SItemInCache **pindex_base,
TChainHash<SItemInCache> *phash_of_index,
const pgcchar *szSecName,
const pgcchar *szItemName)
{
SItemInCache *p = NULL, index;
memset(&index, 0, sizeof(SItemInCache));
if (szSecName != NULL)
{
//以下执行大小写转换
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)index.szSecName, (LPCWSTR)szSecName, MAX_CHAR_LINE);
// strupr(index.szSecName);
#else
strncpy(index.szSecName, szSecName, MAX_CHAR_LINE - 1);
// UpperCase(index.szSecName);
#endif
}
if (szItemName != NULL)
{
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)index.szItemName, (LPCWSTR)szItemName, MAX_CHAR_LINE);
// strupr(index.szItemName);
#else
strncpy(index.szItemName, szItemName, MAX_CHAR_LINE - 1);
// UpperCase(index.szItemName);
#endif
}
p = phash_of_index->searchItem((void *)&index);
if(NULL == p)
return -1;
*pindex_base = p;
return 0;
}
/*
* 哈希函数
*/
// 给出关键字, 求同义词序号
static u32 fnhash_index_of(const void * pKey, u32 hash_size)
{
long index = 0;
u_char *pbString = NULL;
int iX = 0, iY = 0, i = 0;
SItemInCache * pindex = (SItemInCache *)pKey, sindex;
memcpy(&sindex, pindex, sizeof(SItemInCache));
//以下执行大小写转换
#ifndef OS_WINDOWS
strupr(sindex.szSecName);
strupr(sindex.szItemName);
#else
UpperCase(sindex.szSecName);
UpperCase(sindex.szItemName);
#endif
//哈希转换
pbString = (u_char*)sindex.szSecName;
for (i = 0; i < MAX_CHAR_LINE; i++)
{
iX = iX + pbString[i];
}
iX = iX % MAX_SEC_NUM;
pbString = (u_char*)sindex.szItemName;
for ( i = 0; i < MAX_CHAR_LINE; i++)
{
iY = iY + pbString[i];
}
iY = iY % MAX_ITEM_NUM;
index = iX * MAX_ITEM_NUM + iY;
return (u32)(index % hash_size);
}
// 求关键字
static void * fnhash_key_of(const SItemInCache * pindex)
{
return (void *)(pindex);
}
// 比较关键字
static int fnhash_compare(const void * pKey1, const void * pKey2)
{
SItemInCache * pindex1 = (SItemInCache *)pKey1;
SItemInCache * pindex2 = (SItemInCache *)pKey2;
if (pKey1 == NULL)
return 1;
//#ifdef OS_WINDOWS
if (pKey2 == NULL)
{
if (_stricmp(pindex1->szSecName, pindex2->szSecName) == 0)
return 0;
else
return 1;
}
else
{
if ((_stricmp(pindex1->szSecName, pindex2->szSecName) == 0)
&& (_stricmp(pindex1->szItemName, pindex2->szItemName) == 0))
return 0;
else
return 1;
}
/*#else
if (pKey2 == NULL)
{
if (strcasecmp(pindex1->szSecName, pindex2->szSecName) == 0)
return 0;
else
return 1;
}
else
{
if ((strcasecmp(pindex1->szSecName, pindex2->szSecName) == 0)
&& (strcasecmp(pindex1->szItemName, pindex2->szItemName) == 0))
return 0;
else
return 1;
}
#endif*/
}
//判断某行是否被注释
PGCBOOL LineIsMark(pgcchar *szLine)
{
for (pgc32 i = 0; i < MARK_pgcchar_NUM; i++)
if (*szLine == gs_szMarkpgcchar[i])
return PGCTRUE;
return PGCFALSE;
}
//寻找段尾
pgcchar* FindSecTail(pgcchar *szString)
{
pgcchar *szStart = NULL, *szTemp = NULL;
if ((szStart = strchr(szString, '\n')) == NULL)
{
return NULL;
}
while (szStart != NULL)
{
szStart = strchr(szStart, '[');
if ((szStart != NULL) && (*(szStart - 1) == '\n'))
break;
if (szStart != NULL) szStart++;
}
if (szStart != NULL)
{
szTemp = szStart;
while ((*szTemp != '\n') && (*szTemp != '\0'))
{
if (*szTemp == ']')
return szStart;
szTemp ++;
}
}
return NULL;
}
//提取段名
PGCBOOL DigSecName(const pgcchar *szString, pgcchar *szRevBuffer, pgc32 iBufferLength)
{
pgcchar *szStart = NULL, *szTemp = NULL;
PGCBOOL bSecNameExist = PGCFALSE;
pgc32 iLength = iBufferLength - 1;
if ((szStart = (pgcchar *)strchr((const char*)szString, '[')) != NULL)
{
szTemp = szStart;
while ((*szTemp != '\n') && (*szTemp != '\0'))
{
if (*szTemp == ']')
{
bSecNameExist = PGCTRUE;
break;
}
szTemp ++;
}
if (bSecNameExist)
{
iLength = (pgc32)(szTemp - szStart) - 1;
if (iLength >= iBufferLength)
iLength = iBufferLength - 1;
for (pgc32 i = 0; i < iLength; i++)
szRevBuffer[i] = *(szStart + 1 + i);
szRevBuffer[iLength] = '\0';
/*
#ifndef __unix__
strupr(szRevBuffer);
#else
UpperCase(szRevBuffer);
#endif
*/
return PGCTRUE;
}
}
return PGCFALSE;
}
//提取项目名及项目值
PGCBOOL DigItemContent( pgcchar *szString, pgcchar *szItemName, pgcchar *szItemVal, pgc32 iBufferLength)
{
pgcchar *pcBeval = NULL, *pcTemp = NULL, szTemp[MAX_CHAR_LINE];
pgc32 iCount = 0, i = 0;
if ((pcBeval = strchr(szString, '=')) == NULL)
return PGCFALSE;
//获取项目名
pcTemp = szString;
while ((pcTemp < pcBeval) && (iCount < (MAX_CHAR_LINE - 1)))
{
szTemp[iCount] = *pcTemp;
pcTemp++;
iCount++;
}
szTemp[iCount] = '\0';
//删除前面多余空格
for ( i = 0; i < MAX_CHAR_LINE; i++)
{
if (szTemp[i] != ' ')
{
for (pgc32 j = i; j < MAX_CHAR_LINE; j++)
{
szTemp[j - i] = szTemp[j];
}// end for
break;
}// end if
}// end for
//删除后面多余空格
for (i = iCount - 1; i >= 0; i--)
{
if (szTemp[i] != ' ')
break;
szTemp[i] = '\0';
}// end for
/*#ifndef __unix__
strupr(szTemp);
#else
UpperCase(szTemp);
#endif*/
strcpy(szItemName, szTemp);
//获取项目值
memset(szTemp, 0, MAX_CHAR_LINE);
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)szTemp, (LPCWSTR)pcBeval + 1, MAX_CHAR_LINE);
#else
strncpy(szTemp ,pcBeval + 1, MAX_CHAR_LINE - 1);
#endif
//删除前面多余空格
for (i = 0; i < MAX_CHAR_LINE; i++)
{
if (szTemp[i] != ' ')
{
for (pgc32 j = i; j < MAX_CHAR_LINE; j++)
{
szTemp[j - i] = szTemp[j];
}// end for
break;
}// end if
}// end for
//删除后面多余空格
for ( i = (pgc32)strlen(szTemp) - 1 ; i >= 0; i--)
{
if (szTemp[i] != ' ')
break;
szTemp[i] = '\0';
}// end for
strcpy(szItemVal, szTemp);
return PGCTRUE;
}
// 函数名 : InsertNode
// 函数说明 : 在指定的段添加新项目
// 返回值说明 : PGCBOOL --
// 参数说明 : psHead --
// 参数说明 : iPos --
// 参数说明 : psCacheEntry --
// 参数说明 : iSecPos --
PGCBOOL InsertNode(SItemSequence * &psHead, pgc32 iPos, SItemInCache *psCacheEntry, pgc32 iSecPos)
{
SItemSequence *psTemp = NULL, *psNewNode = NULL, *psPrior = NULL;
if ((psHead == NULL) || (psCacheEntry == NULL))
return PGCFALSE;
psNewNode = new SItemSequence[1];
psNewNode->iPos = iPos;
psNewNode->NextNode = NULL;
psTemp = psHead;
while (psTemp != NULL)
{
if (psTemp->iPos == iSecPos)
break;
psTemp = psTemp->NextNode;
}
while (psTemp != NULL)
{
psPrior = psTemp;
psTemp = psTemp->NextNode;
if ((psTemp == NULL) || psCacheEntry[psTemp->iPos].bIsSecName)
{
psPrior->NextNode = psNewNode;
psNewNode->NextNode = psTemp;
return PGCTRUE;
}
}
delete []psNewNode;
return PGCFALSE;
}
// 函数名 : DisableSec
// 函数说明 : 使指定的段及其下属的各个项目无效
// 返回值说明 : PGCBOOL --
// 参数说明 : psHead --
// 参数说明 : iSecPos --
// 参数说明 : psCacheEntry --
PGCBOOL DisableSec(SItemSequence * &psHead, pgc32 iSecPos, SItemInCache *psCacheEntry)
{
SItemSequence *psTemp = NULL;
if (psHead == NULL)
return PGCFALSE;
psTemp = psHead;
while (psTemp != NULL)
{
if (psTemp->iPos == iSecPos)
break;
psTemp = psTemp->NextNode;
}
while (psTemp != NULL)
{
psCacheEntry[psTemp->iPos].valid = PGCFALSE;
psTemp = psTemp->NextNode;
if ((psTemp == NULL) || (psCacheEntry[psTemp->iPos].bIsSecName))
{
return PGCTRUE;
}
}
return PGCFALSE;
}
//添加一个节点到顺序链表尾部
PGCBOOL AddNode(SItemSequence * &psHead, SItemSequence * &pCurSeq, pgc32 iPos)
{
SItemSequence *psNewNode = NULL;
psNewNode = new SItemSequence[1];
psNewNode->iPos = iPos;
psNewNode->NextNode = NULL;
if (psHead == NULL)
{
psHead = psNewNode;
pCurSeq = psHead;
}
else
{
if (pCurSeq)
{
pCurSeq->NextNode = psNewNode;
pCurSeq = psNewNode;
}
}
return PGCTRUE;
}
void ReleaseProfileCache(HPROFILE hProfile)
{
FILE *fstream = NULL;
TChainHash<SItemInCache> *pHashTable = NULL;
SItemSequence *pSequence = NULL, *psPrior = NULL;
SItemInCache *psCacheEntry = NULL;
SMemoChain *psMemo = NULL, *psMemoPrior = NULL;
pgc32 iCurItemCount = 0;
fstream = g_pHandleIndex[hProfile].fstream ;
if (fstream != NULL)
fclose(fstream);
pHashTable = g_pHandleIndex[hProfile].pHashTable;
if (pHashTable != NULL)
delete pHashTable;
pSequence = g_pHandleIndex[hProfile].pSequence;
//删除该链表的所有节点
while (pSequence != NULL)
{
psPrior = pSequence;
pSequence = pSequence->NextNode;
delete []psPrior;
}
iCurItemCount = g_pHandleIndex[hProfile].CurUseItems;
psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry;
//首先释放注释节点
if (psCacheEntry != NULL)
{
for (pgc32 i = 0; i < iCurItemCount; i++)
{
psMemo = psCacheEntry[i].memo;
while (psMemo != NULL)
{
psMemoPrior = psMemo;
psMemo = psMemo->NextNode;
delete []psMemoPrior->szMemo;
delete []psMemoPrior;
}
}
free(psCacheEntry);
}
return;
}
//调整缓冲区大小
pgcu32 AdjustCache(HPROFILE hCacher, pgc32 iNewItem)
{
pgc32 iOldSize = g_pHandleIndex[hCacher].CurItemCount, iNewSize = 0;
pgc32 iOldUse = g_pHandleIndex[hCacher].CurUseItems;
SItemInCache *pCacheEntry = NULL;
if ((g_pHandleIndex[hCacher].CurUseItems + iNewItem ) >= iOldSize)
{
iNewSize = iOldSize + RESIZE_ITEM_NUM;
pCacheEntry = (SItemInCache*)malloc(iNewSize * sizeof(SItemInCache));
if (pCacheEntry == NULL)
return ERROR_MEMORY_ALLOC;
memset(pCacheEntry, 0, iNewSize * sizeof(SItemInCache));
memmove(pCacheEntry, g_pHandleIndex[hCacher].pCacheEntry, iOldSize * sizeof(SItemInCache));
free(g_pHandleIndex[hCacher].pCacheEntry);
g_pHandleIndex[hCacher].CurItemCount = iNewSize;
g_pHandleIndex[hCacher].pCacheEntry = pCacheEntry;
//分离哈希表的所有数据项
g_pHandleIndex[hCacher].pHashTable->detachItems();
for (pgc32 i = 0; i < iOldUse; i++)
g_pHandleIndex[hCacher].pHashTable->insertItem(pCacheEntry + i);
return SUCCESS;
}
return ERROR_FAIL;
}
// 函数名 : get_file_lastMTime
// 函数说明 : 获取文件上一次被修改的时间
// 返回值说明 : void --
// 参数说明 : pszfname --
// 参数说明 : pt --
pgc32 get_file_lastMTime(char * pszfname, timeval *pt)
{
int ret = 0;
struct stat buf;
memset((void *)&buf, 0, sizeof(buf));
ret = stat(pszfname, &buf);
if(-1 == ret)
return ERROR_FAIL;
pt->tv_sec = buf.st_mtime;
pt->tv_usec = 0;
return SUCCESS;
}
//将缓冲的数据重新写成文件
pgc32 ReWriteProfile(HPROFILE hProfile)
{
pgc32 iSize = 0;
pgcchar *pcFileBuffer = NULL, *pcTemp = NULL;
pgcchar *pcHead = NULL;
PGCBOOL bSecExist = PGCFALSE;
SItemSequence * psSeq = g_pHandleIndex[hProfile].pSequence ;
SItemInCache *psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry, *psTemp = NULL;
SMemoChain *psMemo = NULL;
FILE *stream = /*g_pHandleIndex[hProfile].fstream*/0;
iSize = (g_pHandleIndex[hProfile].CurLines + 2) * (MAX_CHAR_LINE + 2);
if (( pcHead = (pgcchar*)malloc(iSize)) != NULL)
{
pcFileBuffer = pcHead;
memset(pcFileBuffer, 0, iSize);
while (psSeq != NULL)
{
psTemp = psCacheEntry + psSeq->iPos;
if (psTemp->valid)
{
//有注释吗?
psMemo = psTemp->memo;
while (psMemo != NULL)
{
//写一行注释
pcTemp = psMemo->szMemo;
while (*pcTemp != '\0')
{
*pcFileBuffer = *pcTemp;
pcFileBuffer++;
pcTemp++;
}
#ifdef LINE_EXCLUDE_0A
*pcFileBuffer = '\n';
pcFileBuffer += 1;
#else
*pcFileBuffer = '\r';
*(pcFileBuffer + 1) = '\n';
pcFileBuffer += 2;
#endif
psMemo = psMemo->NextNode;
}
//是段吗?
if (psTemp->bIsSecName)
{
if (bSecExist)
{
#ifdef LINE_EXCLUDE_0A
*pcFileBuffer = '\n';
pcFileBuffer += 1;
#else
*pcFileBuffer = '\r';
*(pcFileBuffer + 1) = '\n';
pcFileBuffer += 2;
#endif
}
else
bSecExist = PGCTRUE;
*pcFileBuffer = '[';
pcFileBuffer++;
pcTemp = psTemp->szSecName;
while (*pcTemp != '\0')
{
*pcFileBuffer = *pcTemp;
pcFileBuffer++;
pcTemp++;
}
*pcFileBuffer = ']';
#ifdef LINE_EXCLUDE_0A
*(pcFileBuffer + 1) = '\n';
pcFileBuffer += 2;
#else
*(pcFileBuffer + 1) = '\r';
*(pcFileBuffer + 2) = '\n';
pcFileBuffer += 3;
#endif
}
else
{
pcTemp = psTemp->szItemName;
while (*pcTemp != '\0')
{
*pcFileBuffer = *pcTemp;
pcFileBuffer++;
pcTemp++;
}
*pcFileBuffer = '=';
pcFileBuffer++;
pcTemp = psTemp->szItemVal;
while (*pcTemp != '\0')
{
*pcFileBuffer = *pcTemp;
pcFileBuffer++;
pcTemp++;
}
#ifdef LINE_EXCLUDE_0A
*pcFileBuffer = '\n';
pcFileBuffer += 1;
#else
*pcFileBuffer = '\r';
*(pcFileBuffer + 1) = '\n';
pcFileBuffer += 2;
#endif
}// end else
}// end if "valid"
psSeq = psSeq->NextNode;
}// end while
//2002/03/05 杨小波++++++++++++++++++++++++++++++++++++++++++++
#if 0
pgcu32 numwritten = (pgcu32)pcFileBuffer - (pgcu32)pcHead ;
#endif
pgcu32 numwritten = (pgcu32)(pcFileBuffer - pcHead) ;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifdef OS_WINDOWS
//windows下打开文件
/*if ((stream = fopen(g_pHandleIndex[hProfile].szPathName, "w+b")) == NULL)
{
free(pcHead);
return ERROR_FOPEN;
}*/
#else
//unix下打开文件
/*PGCBOOL bOpenOK = PGCFALSE;
do
{
errno = 0;
if ((stream = fopen(g_pHandleIndex[hProfile].szPathName, "w+b")) != NULL)
{
bOpenOK = PGCTRUE;
break;
}
}
while (errno == EINTR);
if (!bOpenOK)
{
free(pcHead);
return ERROR_FOPEN;
}*/
//ghConfig = DSOpenFile("g_pHandleIndex[hProfile].szPathName");
#endif
fseek(stream, 0, SEEK_SET);
//函数fwrite在写数据到文件时如遇字符NULL会产生错误从而使文件无法定位结尾
pgc32 numwritted = (pgc32)fwrite(pcHead, sizeof( pgcchar ), numwritten , stream );
free(pcHead);
fclose(stream);
//记录下修改文件的时间
get_file_lastMTime(g_pHandleIndex[hProfile].szPathName, &g_pHandleIndex[hProfile].tLastModify);
if (numwritted != numwritten)
{
return ERROR_FWRITE;
}
return SUCCESS;
}// end if
return ERROR_FAIL;
}
int timeval_compare(timeval * ptv1, timeval * ptv2)
{
int del_sec = ptv1->tv_sec - ptv2->tv_sec;
int del_usec = ptv1->tv_usec - ptv2->tv_usec;
return (del_sec != 0) ? del_sec : del_usec;
}
// 函数名 : ReCreateCache
// 函数说明 : 当有当前进程以外的进程修改配置文件后,需要调用此函数重建配置文件缓冲
// 返回值说明 : void --
// 参数说明 : hProfile --
void ReCreateCache(HPROFILE hProfile)
{
timeval tLastModify, *ptRecModify = NULL;
pgcchar *szProfileName = g_pHandleIndex[hProfile].szPathName;
ptRecModify = &g_pHandleIndex[hProfile].tLastModify;
if (szProfileName == 0)
return;
if (get_file_lastMTime(szProfileName, &tLastModify) == SUCCESS)
{
if (timeval_compare(&tLastModify, ptRecModify) > 0)
{
ReleaseProfileCache(hProfile);
ProcessCreateCache(hProfile);
}
}
return;
}
pgc32 ProcessCreateCache(HPROFILE hProfile)
{
pgcchar *pcFileBuffer = NULL, *pcTemp = NULL, *pcStart = NULL, *pcEnd = NULL;
pgcchar *pcNextLine = NULL, *pcTemp1 = NULL ;
pgcchar szSecName[MAX_CHAR_LINE], CurItemName[MAX_CHAR_LINE], CurItemVal[MAX_CHAR_LINE];
SItemInCache *psTemp = NULL;
SMemoChain *psMemoTep = NULL, *psMemo = NULL;
TChainHash<SItemInCache> * phash_table = NULL;
PGCBOOL bSecNameExist = PGCFALSE;
FILE *fstream = NULL;
long lFileLength = 0;
SItemInCache *psCacheEntry = NULL, *psCacheTep = NULL;
pgc32 iCount = 0, iPos = 0, iCurSec = 0, iCurItem = 0, iCurItemCount = 0;
//iCurLineType:当前行类型 0不能确定 1注释行 2段名 3项目内容4空行
pgc32 iCurLineType = 0, iLines = 0, i = 0;
pgcchar szProfileName[MAX_PATH_NUM];
memset(szProfileName, 0, MAX_PATH_NUM);
//保存文件全路径名
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)szProfileName, (LPWSTR)g_pHandleIndex[hProfile].szPathName, MAX_PATH_NUM);
#else
strncpy(szProfileName, g_pHandleIndex[hProfile].szPathName, MAX_PATH_NUM - 1);
#endif
memset(&g_pHandleIndex[hProfile], 0, sizeof(SProfileHanleInfo));
//#ifdef OS_WINDOWS
//windows下打开文件
if ((fstream = fopen(szProfileName, "r+b")) == NULL)
{
return ERROR_FOPEN;
}
/*#else
//unix下打开文件
PGCBOOL bOpenOK = PGCFALSE;
do
{
errno = 0;
if ((fstream = fopen(szProfileName, "r+b")) != NULL)
{
bOpenOK = PGCTRUE;
break;
}
}
while (errno == EINTR);
if (!bOpenOK)
return ERROR_FOPEN;
#endif*/
if (fseek(fstream, 0, SEEK_END) != 0)
{
fclose(fstream);
return 0;
}
//获取文件长度
lFileLength = ftell(fstream);
pcTemp = new pgcchar[lFileLength + 1];
if (pcTemp == NULL)
{
fclose(fstream);
return 0;
}
memset(pcTemp, 0, lFileLength + 1);
if (fseek(fstream, 0, SEEK_SET) != 0)
{
fclose(fstream);
return 0;
}
//将文件读入缓冲
if ((iCount = (pgc32)fread(pcTemp, sizeof( pgcchar ), lFileLength, fstream)) != lFileLength)
{
fclose(fstream);
return ERROR_FREAD;
}
//格式化流(去除每一行前面的多余空格)
pcStart = pcTemp;
pcEnd = pcTemp + iCount;
while ((pcStart != NULL) && (pcStart < pcEnd))
{
if (*pcStart == ' ')
{
*pcStart = 0;
pcStart ++;
}
else
{
if (*pcStart == '\n')
pcStart ++;
else
{
if ((pcStart = strchr(pcStart, '\n')) == NULL) break;
pcStart ++;
}
}
}// end while
//格式化流(去除每一行结束标志"\r\n"中的"\r"标志,仅保留"\n"标志)
pcStart = pcTemp;
while ((pcStart != NULL) && (pcStart < pcEnd))
{
if ((*pcStart == '\r') && (*(pcStart + 1) == '\n'))
{
*pcStart = 0;
pcStart +=2;
}
else
pcStart++;
}// end while
//统计行数
pcStart = pcTemp;
while ((pcStart != NULL) && (pcStart < pcEnd))
{
if (*pcStart == '\n')
{
iLines++;
}
pcStart++;
}// end while
iLines++;
g_pHandleIndex[hProfile].CurLines = iLines;
//重建文件缓冲
pcFileBuffer = new pgcchar[iCount + 1];
memset(pcFileBuffer, 0, iCount + 1);
for ( i = 0; i < iCount; i++)
{
if (pcTemp[i] != 0)
{
pcFileBuffer[iPos] = pcTemp[i];
iPos++;
}
}
delete []pcTemp;
//分配配置项缓冲
psCacheEntry = (SItemInCache *)malloc(INITCACHE_ITEM_NUM * sizeof(SItemInCache));
if (psCacheEntry == NULL)
{
if (pcFileBuffer != NULL)
delete []pcFileBuffer;
fclose(fstream);
return ERROR_MEMORY_ALLOC;
}
memset(psCacheEntry, 0, INITCACHE_ITEM_NUM * sizeof(SItemInCache));
iCurItemCount = INITCACHE_ITEM_NUM;
g_pHandleIndex[hProfile].fstream = fstream;
g_pHandleIndex[hProfile].pHashTable = NULL;
g_pHandleIndex[hProfile].pSequence = NULL;
g_pHandleIndex[hProfile].pCurSeq = NULL;
g_pHandleIndex[hProfile].CurItemCount = iCurItemCount;
g_pHandleIndex[hProfile].pCacheEntry = psCacheEntry;
//提取各段
pcStart = pcFileBuffer;
pcEnd = NULL;
while ((pcStart != NULL) && (pcStart < (pcFileBuffer + iPos)))
{
//寻找段尾
pcEnd = FindSecTail(pcStart + 1);
if (pcEnd != NULL)
*(pcEnd - 1) = '\0';
//检查行类型
while (pcStart != NULL)
{
//确定下一行的位置
if ((pcNextLine = strchr(pcStart, '\n')) != NULL)
{
//如果为空行
if (pcStart == pcNextLine)
iCurLineType = 4;
*pcNextLine = '\0';
pcNextLine++;
}
if (iCurLineType != 4)
{
//检查当前行是否为注释行
if (LineIsMark(pcStart))
{
iCurLineType = 1;
}
else
{
pcTemp = strchr(pcStart, '[');
pcTemp1 = strchr(pcStart, ']');
//如果当前行是段名,则提取段名
if ( pcTemp && pcTemp1 && (pcTemp1 > pcTemp))
{
DigSecName(pcStart, szSecName, MAX_CHAR_LINE);
iCurLineType = 2;
}
else
{
pcTemp = strchr(pcStart, '=');
//如果当前行是项目记录,则提取项目名及项目值
if (pcTemp != NULL)
{
DigItemContent(pcStart, CurItemName, CurItemVal, MAX_CHAR_LINE);
iCurLineType = 3;
}
else
iCurLineType = 0;
}
}// end else
}
switch (iCurLineType)
{
//如果是注释行,或空行
case 1:
case 4:
//将注释行添加入节点
psMemoTep = psMemo;
if (psMemoTep != NULL)
{
while (psMemoTep->NextNode != NULL)
{
psMemoTep = psMemoTep->NextNode;
}// end while
psMemoTep->NextNode = new SMemoChain[1];
if (iCurLineType == 1)
{
psMemoTep->NextNode->szMemo = new pgcchar[strlen(pcStart) + 1];
strcpy(psMemoTep->NextNode->szMemo, pcStart);
}
else if (iCurLineType == 4)
{
#ifdef LINE_EXCLUDE_0A
psMemoTep->NextNode->szMemo = new pgcchar[2];
psMemoTep->NextNode->szMemo[0] = '\0';
psMemoTep->NextNode->szMemo[1] = '\0';
#else
psMemoTep->NextNode->szMemo = new pgcchar[3];
psMemoTep->NextNode->szMemo[0] = '\0';
psMemoTep->NextNode->szMemo[1] = '\n';
psMemoTep->NextNode->szMemo[2] = '\0';
#endif
}
psMemoTep->NextNode->NextNode = NULL;
}// end if
else
{
psMemo = new SMemoChain[1];
if (iCurLineType == 1)
{
psMemo->szMemo = new pgcchar[strlen(pcStart) + 1];
strcpy(psMemo->szMemo, pcStart);
}
else if (iCurLineType == 4)
{
#ifdef LINE_EXCLUDE_0A
psMemo->szMemo = new pgcchar[2];
psMemo->szMemo[0] = '\0';
psMemo->szMemo[1] = '\0';
#else
psMemo->szMemo = new pgcchar[3];
psMemo->szMemo[0] = '\0';
psMemo->szMemo[1] = '\n';
psMemo->szMemo[2] = '\0';
#endif
}
psMemo->NextNode = NULL;
}// end else
break;
//如果是段名
case 2:
psTemp = &psCacheEntry[iCurItem];
strcpy(psTemp->szSecName, szSecName);
psTemp->valid = PGCTRUE;
psTemp->bIsSecName = PGCTRUE;
psTemp->memo = psMemo;
AddNode(g_pHandleIndex[hProfile].pSequence, g_pHandleIndex[hProfile].pCurSeq, iCurItem);
bSecNameExist = PGCTRUE;
iCurItem ++;
psMemo = NULL;
break;
//如果是项目赋值
case 3:
if (bSecNameExist)
{
psTemp = &psCacheEntry[iCurItem];
strcpy(psTemp->szSecName, szSecName);
strcpy(psTemp->szItemName, CurItemName);
strcpy(psTemp->szItemVal, CurItemVal);
psTemp->valid = PGCTRUE;
psTemp->bIsSecName = PGCFALSE;
psTemp->memo = psMemo;
AddNode(g_pHandleIndex[hProfile].pSequence, g_pHandleIndex[hProfile].pCurSeq, iCurItem);
iCurItem ++;
psMemo = NULL;
}//end if
break;
//default:
}// end switch
iCurLineType = 0;
//如果原先的缓冲区太小,则递增缓冲区
if (iCurItem >= iCurItemCount)
{
psCacheTep = (SItemInCache*)malloc((iCurItemCount + RESIZE_ITEM_NUM) * sizeof(SItemInCache));
if (psCacheTep == NULL)
{
ReleaseProfileCache(hProfile);
return ERROR_MEMORY_ALLOC;
}
memset(psCacheTep, 0, (iCurItemCount + RESIZE_ITEM_NUM) * sizeof(SItemInCache));
memmove(psCacheTep, psCacheEntry, sizeof(SItemInCache) * iCurItemCount);
free(psCacheEntry);
psCacheEntry = psCacheTep;
iCurItemCount = iCurItemCount + RESIZE_ITEM_NUM;
g_pHandleIndex[hProfile].CurItemCount = iCurItemCount;
g_pHandleIndex[hProfile].pCacheEntry = psCacheEntry;
}// end if
pcStart = pcNextLine;
}// end while
bSecNameExist = PGCFALSE;
pcStart = pcEnd;
}// end while
if (pcFileBuffer != NULL)
delete []pcFileBuffer;
pgc32 iRev = -1;
//创建哈希表
iRev = profile_build_hash_index(psCacheEntry, iCurItem , &phash_table);
if (iRev != SUCCESS)
{
ReleaseProfileCache(hProfile);
return ERROR_CONF_CREATEHASH ;
}
g_pHandleIndex[hProfile].pHashTable = phash_table;
g_pHandleIndex[hProfile].CurUseItems = iCurItem ;
g_pHandleIndex[hProfile].CurSecNum = iCurSec;
fstream = g_pHandleIndex[hProfile].fstream;
g_pHandleIndex[hProfile].fstream = 0;
fclose(fstream);
//保存文件全路径名
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)g_pHandleIndex[hProfile].szPathName, (LPCWSTR)szProfileName, MAX_PATH_NUM);
#else
strncpy(g_pHandleIndex[hProfile].szPathName, szProfileName, MAX_PATH_NUM - 1);
#endif
//记录下修改文件的时间
get_file_lastMTime(szProfileName, &g_pHandleIndex[hProfile].tLastModify);
return SUCCESS;
}
//以下为应用接口
//-----------------------------------------------------------------------------------------
// 函数名 : create_profile_cache
// 函数说明 : 建立配置文件缓冲
// 返回值说明 : HPROFILE -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 返回值 说明
// SUCCESS 成功建立配置文件缓冲
// ERROR_CONF_NOHANDLE 建立配置文件缓冲失败,原因:没有空闲的配置文件缓冲句柄分配给当前配置文件缓冲
// ERROR_FOPEN 打开文件失败
// ERROR_FREAD 读文件失败
// ERROR_CONF_CREATEHASH 建立哈希表失败
// ERROR_MEMORY_ALLOC 申请分配指定大小的内存失败
// ERROR_CONF_NULL_HANDEPTR 输入了一个空的句柄指针作参数
// 参数说明 : szProfileName --[in] 配置文件全路径名
// 参数说明 : phfile --[out]如果函数执行成功,则返回一个句柄
int create_profile_cache(pgcchar *szProfileName, int *phfile)
{
HPROFILE hCurCacher = 0;
if (szProfileName == NULL)
return ERROR_FOPEN ;
if (phfile == NULL)
return ERROR_CONF_NULL_HANDEPTR;
//检查句柄数组是否经过初始化
if (!g_bHandleInit)
{
memset(g_pHandleIndex, 0, MAX_PROFILEHANDLE_NUM * sizeof(SProfileHanleInfo));
g_bHandleInit = PGCTRUE;
}
//为当前缓冲寻找一个空闲句柄
for (int i = 1; i < MAX_PROFILEHANDLE_NUM; i++)
if (g_pHandleIndex[i].pCacheEntry == NULL)
{
hCurCacher = i;
break;
}
if ( hCurCacher < 1)
{
return ERROR_CONF_NOHANDLE;
}
//保存文件全路径名
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)g_pHandleIndex[hCurCacher].szPathName, (LPWSTR)szProfileName, MAX_PATH_NUM);
#else
strncpy(g_pHandleIndex[hCurCacher].szPathName, szProfileName, MAX_PATH_NUM - 1);
#endif
pgc32 iExeRev = 0;
if ((iExeRev = ProcessCreateCache(hCurCacher)) != SUCCESS)
return iExeRev;
*phfile = hCurCacher;
return SUCCESS;
}
// 函数名 : CloseProfileHandle
// 函数说明 : 关闭配置文件缓冲
// 函数逻辑 : 根据在该配置文件缓冲句柄中记录的信息,释放资源
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 返回值 说明
// SUCCESS 成功关闭配置文件缓冲
// ERROR_CONF_INVALIDHANDLE 输入了非法的配置文件缓冲句柄
// 参数说明 : hProfile --[in]配置文件缓冲句柄
int close_profile_handle(HPROFILE hProfile)
{
if ((hProfile < 1) || (hProfile >= MAX_PROFILEHANDLE_NUM))
return ERROR_CONF_INVALIDHANDLE;
ReleaseProfileCache(hProfile);
memset(&g_pHandleIndex[hProfile], 0, sizeof(SProfileHanleInfo));
return SUCCESS;
}
// 函数名 : GetPgcProfileString
// 函数说明 : 根据段名,项目名获取项目值
// 函数逻辑 : 调用者通过参数lpAppName lpKeyName传入要取出的项目值所在的段名和项目名
// 如果指定的段及项目名存在函数将取出的项目值拷贝到以lpReturnedString为首地址的
// 目标缓冲中(目标缓冲的长度通过指针pdwSize传入),随后函数会将取出的项目值
// 的长度(包括'\0'字符)写入地址指针pdwSize中 如果指定的段及项目名不存在,则执行缺省拷贝,即将
// lpDefault 所指向的字符串拷贝到目标缓冲区lpReturnedString中; 如果目标缓冲区的首地址
// lpReturnedString为空或传入的目标缓冲的长度小于1那么函数不会将任何字符串拷贝到
// 目标缓冲,但是仍会将取出的项目值的长度(包括'\0'字符)写入到指针pdwSize所指向的地址中。
//
//
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 返回值 说明
// SUCCESS 如果指定的段及项目名存在函数将取出的项目值拷贝到以lpReturnedString为首地址的
// 目标缓冲中,如果取出的项目值的长度小于或等于目标缓冲区的长度,那么整个项目值将
// 被完全拷贝到目标缓冲中此时函数返回SUCCESS
// ERROR_CONF_REVBUFFER 如果指定的段及项目名存在,但是取出的项目值的长度大于目标缓冲
// 区的长度, 那么取出的项目值将被截断为和目标缓冲区一样的大小,然后再拷贝到目标缓
// 区此时函数返回ERROR_CONF_REVBUFFER
//
// SUCCESS_CONF_DEFCOPY 如果指定的段及项目名不存在并且lpDefault指针不为空则函数将lpDefault
// 所指向的字符串拷贝到目标缓冲区lpReturnedString如果lpDefault指向的字符串
// 的长度大于目标缓冲区的长度那么只从lpDefault开始拷贝 [目标缓冲区的长度 1]
// 个字符到缓冲中。
// ERROR_CONF_INVALIDHANDLE 输入了非法的配置文件缓冲句柄
// ERROR_FAIL 函数执行失败,即未拷贝任何字符到目标缓冲区
// 参数说明 : lpAppName --[in]段名
// 参数说明 : lpKeyName --[in]项目名
// 参数说明 : lpDefault --[in] 当获取指定的项目值失败时将该缓冲区的字符串写入lpReturnedString目标缓冲
// 参数说明 : lpReturnedString --[out] 目标缓冲区,用来存放取出的项目值
// 参数说明 : pdwSize -- [in][out]指向缓冲区的长度的指针,同时在调用结束后,将取出的项目字符串的长度(包括'\0'字符)写入该地址
// 参数说明 : hProfile --[in] 配置文件缓冲句柄
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
)
{
SItemInCache *psTemp = NULL;
TChainHash<SItemInCache> *phash_table = NULL;
pgcu32 dwBuffer = 0, dwCount = 0, dwNeed = 0;
//bRevBuffer - PGCTRUE表示接收缓冲区足够大
PGCBOOL bRevBuffer = PGCTRUE;
if ((hProfile < 1) || (hProfile >= MAX_PROFILEHANDLE_NUM))
return ERROR_CONF_INVALIDHANDLE;
if ((lpAppName == NULL) || ( lpKeyName == NULL))
return ERROR_FAIL;
ReCreateCache(hProfile);
phash_table = g_pHandleIndex[hProfile].pHashTable;
if (phash_table == NULL)
return ERROR_CONF_INVALIDHANDLE;
profile_search_sequence(&psTemp, phash_table, lpAppName, lpKeyName);
if ((psTemp != NULL) && (psTemp->valid) && (pdwSize != NULL))
{
dwBuffer = (pgcu32)strlen(psTemp->szItemVal) + 1;
dwNeed = dwBuffer;
if (dwBuffer > *pdwSize)
{
dwBuffer = *pdwSize;
bRevBuffer = PGCFALSE;
}
if ((lpReturnedString != NULL) && (dwBuffer > 0))
{
for (dwCount = 0; dwCount < dwBuffer - 1; dwCount++)
lpReturnedString[dwCount] = psTemp->szItemVal[dwCount];
lpReturnedString[dwCount] = '\0';
}
}
else
{
//执行缺省拷贝
if ((lpDefault != NULL) && (pdwSize != NULL))
{
dwBuffer = (pgcu32)strlen(lpDefault) + 1;
dwNeed = dwBuffer;
if (dwBuffer > *pdwSize)
{
dwBuffer = *pdwSize;
bRevBuffer = PGCFALSE;
}
if ((dwBuffer > 0) && (lpReturnedString != NULL))
{
//2002/03/05 杨小波++++++++++++++++++++++++++++++++++++++++++++
#if 0
for (pgcu32 dwCount = 0; dwCount < dwBuffer - 1; dwCount++)
#endif
for (dwCount = 0; dwCount < dwBuffer - 1; dwCount++)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lpReturnedString[dwCount] = lpDefault[dwCount];
lpReturnedString[dwCount] = '\0';
}
}
else
dwBuffer = 0;
}
*pdwSize = dwNeed;
if (dwBuffer == 0)
return ERROR_FAIL;
if (!bRevBuffer)
return ERROR_CONF_REVBUFFER;
return SUCCESS;
}
// 函数名 : WritePgcProfileString
// 函数说明 : 根据段名,项目名写项目值
// 函数逻辑 : 调用者通过参数lpAppName lpKeyName传入要写入的项目值所在的段名和项目名
// 如果指定的段及项目名存在函数将把lpString所指向的以空字符结尾的字符串拷贝到
// 以该段名,项目名对应的项目值缓冲中,然后再把整个配置文件缓冲的内容写入到文件中,
// 并返回SUCCESS;如果指定的段及项目名不存在函数会根据参数bInsertItem的值决定是否将输入的段名以及
// 项目名添加到配置文件中如果bInsertItem为真则添加该段名和项目名然后写入项目值
// 并返回SUCCESS; 如果bInsertItem为假函数返回ERROR_FAIL。
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 返回值 说明
// SUCCESS 如果指定的段及项目名存在函数将把lpString所指向的以空字符结尾的字符串拷贝到
// 以该段名,项目名对应的项目值缓冲中,然后再把整个配置文件缓冲的内容写入到文件中,
// 并返回SUCCESS
// ERROR_FWRITE 写文件错误
// ERROR_CONF_INVALIDHANDLE 输入了非法的配置文件缓冲句柄
// ERROR_CONF_INPUTSTRING_TOOLARGE 输入的段名,项目名,项目值的字符串长度超长
// ERROR_FAIL 函数执行失败,即未将任何字符写到配置文件缓冲区以及文件
// 参数说明 : lpAppName[in] -- 段名
// 参数说明 : lpKeyName[in] -- 项目名
// 参数说明 : lpString[in] -- 要写入的字符串
// 参数说明 : hProfile[in] -- 配置文件缓冲句柄
// 参数说明 : bInsertItem[in] -- 当指定的段名或项目名不存在时是否添加该段或项目PGCTRUE-添加PGCFALSE-不添加(缺省)
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
)
{
SItemInCache *psTemp = NULL, *psCacheEntry = NULL, *psSec = NULL;
TChainHash<SItemInCache> *phash_table = NULL;
pgc32 iBuffer = 0, iCurItem = 0, iSecPos = 0, i = 0, iWriteSuccess = 0;
PGCBOOL bSecExist = PGCFALSE;
PGCBOOL bTrunc = PGCFALSE ;/*写入的字符串是否被截断*/
//输入句柄合法性检查
if ((hProfile < 1) || (hProfile >= MAX_PROFILEHANDLE_NUM))
return ERROR_CONF_INVALIDHANDLE;
//输入段名及项目名合法性检查
if ((lpAppName == NULL) || ( lpKeyName == NULL))
return ERROR_FAIL;
//判断输入字符串是否超长
if (strlen(lpAppName) >= MAX_CHAR_LINE)
bTrunc = PGCTRUE;
if (strlen(lpKeyName) >= MAX_CHAR_LINE)
bTrunc = PGCTRUE;
if ( (lpString != NULL) && (strlen(lpString) >= MAX_CHAR_LINE))
bTrunc = PGCTRUE;
if (bTrunc)
return ERROR_CONF_INPUTSTRING_TOOLARGE;
//如果配置文件被其它进程修改,则重构缓冲
ReCreateCache(hProfile);
//哈希表合法性检查
phash_table = g_pHandleIndex[hProfile].pHashTable;
if (phash_table == NULL)
return ERROR_CONF_INVALIDHANDLE;
psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry;
psTemp = NULL;
profile_search_sequence(&psTemp, phash_table, lpAppName, lpKeyName);
if ((psTemp == NULL) && (bInsertItem))
{
//检查该段名是否已经存在
profile_search_sequence(&psSec, phash_table, lpAppName, NULL);
if (psSec != NULL)
{
pgcu32 a1, a2;
//2002/03/05 杨小波++++++++++++++++++++++++++++++++++++++++++++
#if 0
a1 = (pgcu32)psSec - (pgcu32)psCacheEntry;
#endif
a1 = (pgcu32)(psSec - psCacheEntry);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
a2 = (pgcu32)sizeof(SItemInCache);
iSecPos = a1 / a2;
bSecExist = PGCTRUE;
psSec->valid = PGCTRUE;
}
//重构缓冲区大小
AdjustCache(hProfile, 2);
psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry;
iCurItem = g_pHandleIndex[hProfile].CurUseItems;
//应该插入新段名吗?
if (!bSecExist)
{
psTemp = &psCacheEntry[iCurItem];
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)psTemp->szSecName, (LPCWSTR)lpAppName, MAX_CHAR_LINE);
#else
memset(psTemp->szSecName, 0, MAX_CHAR_LINE);
strncpy(psTemp->szSecName, lpAppName, MAX_CHAR_LINE - 1);
#endif
psTemp->valid = PGCTRUE;
psTemp->bIsSecName = PGCTRUE;
psTemp->memo = NULL;
phash_table->insertItem(psTemp);
AddNode(g_pHandleIndex[hProfile].pSequence, g_pHandleIndex[hProfile].pCurSeq, iCurItem);
iSecPos = iCurItem;
iCurItem++;
g_pHandleIndex[hProfile].CurLines++;
}
//插入新项目名及项目值
psTemp = &psCacheEntry[iCurItem];
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)psTemp->szSecName, (LPCWSTR)lpAppName, MAX_CHAR_LINE);
lstrcpyn((LPWSTR)psTemp->szItemName, (LPCWSTR)lpKeyName, MAX_CHAR_LINE);
lstrcpyn((LPWSTR)psTemp->szItemVal, (LPCWSTR)lpString, MAX_CHAR_LINE);
#else
memset(psTemp, 0, sizeof(SItemInCache));
strncpy(psTemp->szSecName, lpAppName, MAX_CHAR_LINE - 1);
strncpy(psTemp->szItemName, lpKeyName, MAX_CHAR_LINE - 1);
strncpy(psTemp->szItemVal, lpString, MAX_CHAR_LINE - 1);
#endif
psTemp->valid = PGCTRUE;
psTemp->bIsSecName = PGCFALSE;
psTemp->memo = NULL;
phash_table->insertItem(psTemp);
InsertNode(g_pHandleIndex[hProfile].pSequence, iCurItem, psCacheEntry, iSecPos);
iCurItem++;
g_pHandleIndex[hProfile].CurUseItems = iCurItem;
g_pHandleIndex[hProfile].CurLines++;
iBuffer = (pgc32)strlen(psTemp->szItemVal);
psTemp = NULL;
if ((iWriteSuccess = ReWriteProfile(hProfile)) != SUCCESS)
return iWriteSuccess;
}
if ((psTemp == NULL) && (!bInsertItem))
return ERROR_CONF_NOTEXIST;
//如果指定段的项目存在则
if ((psTemp != NULL) && (lpString != NULL))
{
if ((psTemp->valid) || (bInsertItem))
{
iBuffer = (pgc32)strlen(lpString);
if (iBuffer >= MAX_CHAR_LINE)
iBuffer = MAX_CHAR_LINE - 1;
for (i = 0; i < iBuffer; i++)
psTemp->szItemVal[i] = lpString[i];
psTemp->szItemVal[i] = '\0';
psTemp->valid = PGCTRUE;
if ((iWriteSuccess = ReWriteProfile(hProfile)) != SUCCESS)
return iWriteSuccess;
}
}
return SUCCESS;
}
// 函数名 : GetPgcProfileSectionNames
// 函数说明 : 获取配置文件的所有段名
// 函数逻辑 将从配置文件中获取的段名按在文件中出现的先后次序写到pdwSize所指向的地址空间
// 每个段名以一个空字符作为结束标志,在最后一个段名的结尾处再多加一个空字符
// 作为所有段名的结束标志,即内存格式为 段名1\0段名2\0......最后一个段名\0\0
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 参数说明 : LPTSTR lpszReturnBuffer --[out] 写入缓冲区
// 参数说明 : pgcu32 *pdwSize -- [in][out]写入缓冲区的按字节长度
// 参数说明 : pgcu32 *nSecNum --[out]将获取的段总数写入该地址
// 参数说明 : hProfile-- [in] handle to Profile Cache
int get_pgcprofile_secnames( pgcchar * lpszReturnBuffer, // address of return buffer
pgcu32 * pdwSize, // size of return buffer
pgcu32 *nSecNum,
HPROFILE hProfile // handle to Profile Cache
)
{
pgc32 iCount = g_pHandleIndex[hProfile].CurUseItems , iSecNum = 0, i = -1;
pgcu32 dwWrite = 0, dwSize = 0, dwNeed = 0;
SItemInCache *psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry;
pgcchar *szSec = NULL;
if ((hProfile < 1) || (hProfile >= MAX_PROFILEHANDLE_NUM))
return ERROR_CONF_INVALIDHANDLE;
ReCreateCache(hProfile);
if ((pdwSize != NULL) && (*pdwSize > 2))
dwSize = *pdwSize - 2;
if ((dwSize > 2) && (lpszReturnBuffer != NULL))
{
for (i = 0; i < iCount; i++)
{
if ((psCacheEntry[i].bIsSecName) && (psCacheEntry[i].valid))
{
szSec = psCacheEntry[i].szSecName;
dwNeed = dwNeed + (pgcu32)strlen(szSec) + 1;
iSecNum++;
while ((dwWrite < dwSize ) && (*szSec != '\0'))
{
*lpszReturnBuffer = *szSec;
dwWrite++;
lpszReturnBuffer++;
szSec++;
}
*lpszReturnBuffer = '\0';
lpszReturnBuffer++;
dwWrite++;
if (dwWrite >= dwSize)
break;
}// endif
}// end for
*lpszReturnBuffer = '\0';
}
//求所有段名的字符个数总和以及段个数
for (pgc32 iStart = i + 1; iStart < iCount; iStart++)
{
if ((psCacheEntry[iStart].bIsSecName) && (psCacheEntry[iStart].valid))
{
iSecNum++;
szSec = psCacheEntry[iStart].szSecName;
if (szSec != NULL)
{
dwNeed = dwNeed + (pgcu32)strlen(szSec) + 1;
}
}
}
if (pdwSize)
*pdwSize = dwNeed;
if (nSecNum)
*nSecNum = iSecNum;
return SUCCESS;
}
// 函数名 : del_pgcprofile_key
// 函数说明 : 删除指定的项目
// 函数逻辑 :在缓冲中删除指定的项目,以及该项目上方的注释,然后以覆盖方式重写文件。
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 参数说明 : lpAppName --[in] 段名
// 参数说明 : lpKeyName -- [in]项目名
// 参数说明 : HPROFILE hProfile -[in]配置文件的缓冲句柄
int del_pgcprofile_key( const pgcchar * lpAppName, // point to section name
const pgcchar * lpKeyName, // point to key name
HPROFILE hProfile // point to initialization filename
)
{
SItemInCache *psTemp = NULL;
TChainHash<SItemInCache> *phash_table = NULL;
pgc32 iWriteSuccess = 0;
if ((hProfile < 1) || (hProfile >= MAX_PROFILEHANDLE_NUM))
return ERROR_CONF_INVALIDHANDLE;
if ((lpAppName == NULL) || ( lpKeyName == NULL))
return ERROR_FAIL;
ReCreateCache(hProfile);
phash_table = g_pHandleIndex[hProfile].pHashTable;
if (phash_table == NULL)
return ERROR_CONF_INVALIDHANDLE;
profile_search_sequence(&psTemp, phash_table, lpAppName, lpKeyName);
if (psTemp != NULL)
{
psTemp->valid = PGCFALSE;
if ((iWriteSuccess = ReWriteProfile(hProfile)) != SUCCESS)
return iWriteSuccess;
return SUCCESS;
}
return ERROR_CONF_NOTEXIST;
}
// 函数名 : del_pgcprofile_sec
// 函数说明 : 删除指定的段
// 函数逻辑 :在缓冲中删除指定的段,以及该段上方的注释,然后以覆盖方式重写文件;
// 在删除一个段的同时,该段下属的所有项目(包括项目上方的注释)将被删除
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 参数说明 : lpAppName --[in] 段名
// 参数说明 : HPROFILE hProfile -[in]配置文件的缓冲句柄
int del_pgcprofile_sec( const pgcchar * lpAppName,
HPROFILE hProfile
)
{
SItemInCache *psSec = NULL, *psCacheEntry = NULL;
TChainHash<SItemInCache> *phash_table = NULL;
pgc32 iSecPos = 0;
if ((hProfile < 1) || (hProfile >= MAX_PROFILEHANDLE_NUM))
return ERROR_CONF_INVALIDHANDLE;
if (lpAppName == NULL)
return ERROR_FAIL;
psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry;
if (psCacheEntry == NULL)
return ERROR_CONF_INVALIDHANDLE;
ReCreateCache(hProfile);
phash_table = g_pHandleIndex[hProfile].pHashTable;
if (phash_table == NULL)
return ERROR_CONF_INVALIDHANDLE;
profile_search_sequence(&psSec, phash_table, lpAppName, NULL);
if (psSec != NULL)
{
pgcu32 a1, a2;
//2002/03/05 杨小波++++++++++++++++++++++++++++++++++++++++++++
#if 0
a1 = (pgcu32)psSec - (pgcu32)psCacheEntry;
#endif
a1 = (pgcu32)(psSec - psCacheEntry);
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
a2 = (pgcu32)sizeof(SItemInCache);
iSecPos = a1 / a2;
if (DisableSec(g_pHandleIndex[hProfile].pSequence, iSecPos, psCacheEntry))
{
return ReWriteProfile(hProfile);
}
}
return ERROR_CONF_NOTEXIST;
}