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
50 KiB
C++

2 years ago
/*****************************************************************************
*
* Copyright (C) 1999-2001 SCADA Technology Control Co., Ltd. All rights reserved.
*
*
2 years ago
*
* 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.
2 years ago
*
* 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
2 years ago
*
* 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
*
2 years ago
*
* Revision 1.13 2002/01/21 05:55:25 mhorse
*
2 years ago
*
* 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
2 years ago
*
* Revision 1.1.1.1 2001/12/18 06:42:11 mhorse
* CVS(2001/12/18)
2 years ago
*
*
******************************************************************************/
#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>
2 years ago
#endif
#include "Profile_Hash.h"
#include "confrw_errno.h"
//#include "util.h"
#include "common.h"
#include "basefunc.h"
2 years ago
//定义句柄记录数组
2 years ago
static SProfileHanleInfo g_pHandleIndex[MAX_PROFILEHANDLE_NUM];
//句柄记录数组是否经过初始化 PGCTRUE-已经被初始化
2 years ago
static PGCBOOL g_bHandleInit = PGCFALSE;
//定义行注释符
2 years ago
#define MARK_pgcchar_NUM 2
static pgcchar gs_szMarkpgcchar[MARK_pgcchar_NUM] = {';', '#'};
//行结尾字符为\n,不包括\r
2 years ago
//#define LINE_EXCLUDE_0A
// 函数名 : UpperCase
// 函数说明 : 将小写转为大写
// 返回值说明 : pgcchar -- 转换后的字符
// 参数说明 : cCh -- 源字符
2 years ago
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;
}
/*
*
2 years ago
*/
// 给出关键字, 求同义词序号
2 years ago
static u32 fnhash_index_of(const void * pKey, u32 hash_size);
// 求关键字
2 years ago
static void * fnhash_key_of(const SItemInCache * pindex);
// 比较关键字
2 years ago
static int fnhash_compare(const void * pKey1, const void * pKey2);
/*
* , .
2 years ago
*
*
* pindex --
* count -- pindex, pindex[0] -- pindex[count - 1]
*
* pphash_of_index -- pindex, ,
* , 使.
2 years ago
*
*
* SUCCESS --
* --
2 years ago
*
*/
#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;
}
/*
*
2 years ago
*
*
* pindex_base --
* phash_of_index --
* szSecName --
* szItemName -
2 years ago
*
*
* --
* -1 --
2 years ago
*/
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)
{
//以下执行大小写转换
2 years ago
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)index.szSecName, (LPCWSTR)szSecName, MAX_CHAR_LINE);
2 years ago
// 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);
2 years ago
// 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;
}
/*
*
2 years ago
*/
// 给出关键字, 求同义词序号
2 years ago
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
2 years ago
strupr(sindex.szSecName);
strupr(sindex.szItemName);
#else
UpperCase(sindex.szSecName);
UpperCase(sindex.szItemName);
#endif
//哈希转换
2 years ago
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);
}
// 求关键字
2 years ago
static void * fnhash_key_of(const SItemInCache * pindex)
{
return (void *)(pindex);
}
// 比较关键字
2 years ago
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*/
}
//判断某行是否被注释
2 years ago
PGCBOOL LineIsMark(pgcchar *szLine)
{
for (pgc32 i = 0; i < MARK_pgcchar_NUM; i++)
if (*szLine == gs_szMarkpgcchar[i])
return PGCTRUE;
return PGCFALSE;
}
//寻找段尾
2 years ago
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;
}
//提取段名
2 years ago
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;
}
//提取项目名及项目值
2 years ago
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;
//获取项目名
2 years ago
pcTemp = szString;
while ((pcTemp < pcBeval) && (iCount < (MAX_CHAR_LINE - 1)))
{
szTemp[iCount] = *pcTemp;
pcTemp++;
iCount++;
}
szTemp[iCount] = '\0';
//删除前面多余空格
2 years ago
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
//删除后面多余空格
2 years ago
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);
//获取项目值
2 years ago
memset(szTemp, 0, MAX_CHAR_LINE);
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)szTemp, (LPCWSTR)pcBeval + 1, MAX_CHAR_LINE);
2 years ago
#else
strncpy(szTemp ,pcBeval + 1, MAX_CHAR_LINE - 1);
#endif
//删除前面多余空格
2 years ago
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
//删除后面多余空格
2 years ago
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 --
2 years ago
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 --
2 years ago
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;
}
//添加一个节点到顺序链表尾部
2 years ago
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;
//删除该链表的所有节点
2 years ago
while (pSequence != NULL)
{
psPrior = pSequence;
pSequence = pSequence->NextNode;
delete []psPrior;
}
iCurItemCount = g_pHandleIndex[hProfile].CurUseItems;
psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry;
//首先释放注释节点
2 years ago
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;
}
//调整缓冲区大小
2 years ago
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;
//分离哈希表的所有数据项
2 years ago
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 --
2 years ago
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;
}
//将缓冲的数据重新写成文件
2 years ago
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)
{
//有注释吗?
2 years ago
psMemo = psTemp->memo;
while (psMemo != NULL)
{
//写一行注释
2 years ago
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;
}
//是段吗?
2 years ago
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 杨小波++++++++++++++++++++++++++++++++++++++++++++
2 years ago
#if 0
pgcu32 numwritten = (pgcu32)pcFileBuffer - (pgcu32)pcHead ;
#endif
pgcu32 numwritten = (pgcu32)(pcFileBuffer - pcHead) ;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifdef OS_WINDOWS
//windows下打开文件
2 years ago
/*if ((stream = fopen(g_pHandleIndex[hProfile].szPathName, "w+b")) == NULL)
{
free(pcHead);
return ERROR_FOPEN;
}*/
#else
//unix下打开文件
2 years ago
/*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会产生错误从而使文件无法定位结尾
2 years ago
pgc32 numwritted = (pgc32)fwrite(pcHead, sizeof( pgcchar ), numwritten , stream );
free(pcHead);
fclose(stream);
//记录下修改文件的时间
2 years ago
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 --
2 years ago
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空行
2 years ago
pgc32 iCurLineType = 0, iLines = 0, i = 0;
pgcchar szProfileName[MAX_PATH_NUM];
memset(szProfileName, 0, MAX_PATH_NUM);
//保存文件全路径名
#ifdef OS_WINDOWS
2 years ago
lstrcpyn((LPWSTR)szProfileName, (LPWSTR)g_pHandleIndex[hProfile].szPathName, MAX_PATH_NUM);
#else
2 years ago
strncpy(szProfileName, g_pHandleIndex[hProfile].szPathName, MAX_PATH_NUM - 1);
#endif
2 years ago
memset(&g_pHandleIndex[hProfile], 0, sizeof(SProfileHanleInfo));
//#ifdef OS_WINDOWS
//windows下打开文件
2 years ago
if ((fstream = fopen(szProfileName, "r+b")) == NULL)
{
return ERROR_FOPEN;
}
/*#else
//unix下打开文件
2 years ago
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;
}
//获取文件长度
2 years ago
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;
}
//将文件读入缓冲
2 years ago
if ((iCount = (pgc32)fread(pcTemp, sizeof( pgcchar ), lFileLength, fstream)) != lFileLength)
{
fclose(fstream);
return ERROR_FREAD;
}
//格式化流(去除每一行前面的多余空格)
2 years ago
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"标志)
2 years ago
pcStart = pcTemp;
while ((pcStart != NULL) && (pcStart < pcEnd))
{
if ((*pcStart == '\r') && (*(pcStart + 1) == '\n'))
{
*pcStart = 0;
pcStart +=2;
}
else
pcStart++;
}// end while
//统计行数
2 years ago
pcStart = pcTemp;
while ((pcStart != NULL) && (pcStart < pcEnd))
{
if (*pcStart == '\n')
{
iLines++;
}
pcStart++;
}// end while
iLines++;
g_pHandleIndex[hProfile].CurLines = iLines;
//重建文件缓冲
2 years ago
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;
//分配配置项缓冲
2 years ago
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;
//提取各段
2 years ago
pcStart = pcFileBuffer;
pcEnd = NULL;
while ((pcStart != NULL) && (pcStart < (pcFileBuffer + iPos)))
{
//寻找段尾
2 years ago
pcEnd = FindSecTail(pcStart + 1);
if (pcEnd != NULL)
*(pcEnd - 1) = '\0';
//检查行类型
2 years ago
while (pcStart != NULL)
{
//确定下一行的位置
2 years ago
if ((pcNextLine = strchr(pcStart, '\n')) != NULL)
{
//如果为空行
2 years ago
if (pcStart == pcNextLine)
iCurLineType = 4;
*pcNextLine = '\0';
pcNextLine++;
}
if (iCurLineType != 4)
{
//检查当前行是否为注释行
2 years ago
if (LineIsMark(pcStart))
{
iCurLineType = 1;
}
else
{
pcTemp = strchr(pcStart, '[');
pcTemp1 = strchr(pcStart, ']');
//如果当前行是段名,则提取段名
2 years ago
if ( pcTemp && pcTemp1 && (pcTemp1 > pcTemp))
{
DigSecName(pcStart, szSecName, MAX_CHAR_LINE);
iCurLineType = 2;
}
else
{
pcTemp = strchr(pcStart, '=');
//如果当前行是项目记录,则提取项目名及项目值
2 years ago
if (pcTemp != NULL)
{
DigItemContent(pcStart, CurItemName, CurItemVal, MAX_CHAR_LINE);
iCurLineType = 3;
}
else
iCurLineType = 0;
}
}// end else
}
switch (iCurLineType)
{
//如果是注释行,或空行
2 years ago
case 1:
case 4:
//将注释行添加入节点
2 years ago
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;
//如果是段名
2 years ago
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;
//如果是项目赋值
2 years ago
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;
//如果原先的缓冲区太小,则递增缓冲区
2 years ago
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;
//创建哈希表
2 years ago
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);
//保存文件全路径名
2 years ago
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)g_pHandleIndex[hProfile].szPathName, (LPCWSTR)szProfileName, MAX_PATH_NUM);
2 years ago
#else
strncpy(g_pHandleIndex[hProfile].szPathName, szProfileName, MAX_PATH_NUM - 1);
#endif
//记录下修改文件的时间
2 years ago
get_file_lastMTime(szProfileName, &g_pHandleIndex[hProfile].tLastModify);
return SUCCESS;
}
//以下为应用接口
2 years ago
//-----------------------------------------------------------------------------------------
// 函数名 : 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]如果函数执行成功,则返回一个句柄
2 years ago
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;
//检查句柄数组是否经过初始化
2 years ago
if (!g_bHandleInit)
{
memset(g_pHandleIndex, 0, MAX_PROFILEHANDLE_NUM * sizeof(SProfileHanleInfo));
g_bHandleInit = PGCTRUE;
}
//为当前缓冲寻找一个空闲句柄
2 years ago
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
2 years ago
lstrcpyn((LPWSTR)g_pHandleIndex[hCurCacher].szPathName, (LPWSTR)szProfileName, MAX_PATH_NUM);
#else
2 years ago
strncpy(g_pHandleIndex[hCurCacher].szPathName, szProfileName, MAX_PATH_NUM - 1);
#endif
2 years ago
pgc32 iExeRev = 0;
if ((iExeRev = ProcessCreateCache(hCurCacher)) != SUCCESS)
return iExeRev;
*phfile = hCurCacher;
return SUCCESS;
}
// 函数名 : CloseProfileHandle
// 函数说明 : 关闭配置文件缓冲
// 函数逻辑 : 根据在该配置文件缓冲句柄中记录的信息,释放资源
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
2 years ago
// 返回值 说明
// SUCCESS 成功关闭配置文件缓冲
// ERROR_CONF_INVALIDHANDLE 输入了非法的配置文件缓冲句柄
2 years ago
// 参数说明 : hProfile --[in]配置文件缓冲句柄
2 years ago
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所指向的地址中。
2 years ago
//
//
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
2 years ago
// 返回值 说明
// SUCCESS 如果指定的段及项目名存在函数将取出的项目值拷贝到以lpReturnedString为首地址的
// 目标缓冲中,如果取出的项目值的长度小于或等于目标缓冲区的长度,那么整个项目值将
// 被完全拷贝到目标缓冲中此时函数返回SUCCESS
2 years ago
// ERROR_CONF_REVBUFFER 如果指定的段及项目名存在,但是取出的项目值的长度大于目标缓冲
// 区的长度, 那么取出的项目值将被截断为和目标缓冲区一样的大小,然后再拷贝到目标缓
// 区此时函数返回ERROR_CONF_REVBUFFER
2 years ago
//
// SUCCESS_CONF_DEFCOPY 如果指定的段及项目名不存在并且lpDefault指针不为空则函数将lpDefault
// 所指向的字符串拷贝到目标缓冲区lpReturnedString如果lpDefault指向的字符串
// 的长度大于目标缓冲区的长度那么只从lpDefault开始拷贝 [目标缓冲区的长度 1]
// 个字符到缓冲中。
2 years ago
// ERROR_CONF_INVALIDHANDLE 输入了非法的配置文件缓冲句柄
2 years ago
// ERROR_FAIL 函数执行失败,即未拷贝任何字符到目标缓冲区
2 years ago
// 参数说明 : lpAppName --[in]段名
// 参数说明 : lpKeyName --[in]项目名
// 参数说明 : lpDefault --[in] 当获取指定的项目值失败时将该缓冲区的字符串写入lpReturnedString目标缓冲
// 参数说明 : lpReturnedString --[out] 目标缓冲区,用来存放取出的项目值
// 参数说明 : pdwSize -- [in][out]指向缓冲区的长度的指针,同时在调用结束后,将取出的项目字符串的长度(包括'\0'字符)写入该地址
// 参数说明 : hProfile --[in] 配置文件缓冲句柄
2 years ago
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表示接收缓冲区足够大
2 years ago
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
{
//执行缺省拷贝
2 years ago
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 杨小波++++++++++++++++++++++++++++++++++++++++++++
2 years ago
#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。
2 years ago
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
2 years ago
// 返回值 说明
// SUCCESS 如果指定的段及项目名存在函数将把lpString所指向的以空字符结尾的字符串拷贝到
// 以该段名,项目名对应的项目值缓冲中,然后再把整个配置文件缓冲的内容写入到文件中,
// 并返回SUCCESS
// ERROR_FWRITE 写文件错误
// ERROR_CONF_INVALIDHANDLE 输入了非法的配置文件缓冲句柄
// ERROR_CONF_INPUTSTRING_TOOLARGE 输入的段名,项目名,项目值的字符串长度超长
// ERROR_FAIL 函数执行失败,即未将任何字符写到配置文件缓冲区以及文件
2 years ago
// 参数说明 : lpAppName[in] -- 段名
// 参数说明 : lpKeyName[in] -- 项目名
// 参数说明 : lpString[in] -- 要写入的字符串
// 参数说明 : hProfile[in] -- 配置文件缓冲句柄
// 参数说明 : bInsertItem[in] -- 当指定的段名或项目名不存在时是否添加该段或项目PGCTRUE-添加PGCFALSE-不添加(缺省)
2 years ago
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 ;/*写入的字符串是否被截断*/
2 years ago
//输入句柄合法性检查
2 years ago
if ((hProfile < 1) || (hProfile >= MAX_PROFILEHANDLE_NUM))
return ERROR_CONF_INVALIDHANDLE;
//输入段名及项目名合法性检查
2 years ago
if ((lpAppName == NULL) || ( lpKeyName == NULL))
return ERROR_FAIL;
//判断输入字符串是否超长
2 years ago
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;
//如果配置文件被其它进程修改,则重构缓冲
2 years ago
ReCreateCache(hProfile);
//哈希表合法性检查
2 years ago
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))
{
//检查该段名是否已经存在
2 years ago
profile_search_sequence(&psSec, phash_table, lpAppName, NULL);
if (psSec != NULL)
{
pgcu32 a1, a2;
//2002/03/05 杨小波++++++++++++++++++++++++++++++++++++++++++++
2 years ago
#if 0
a1 = (pgcu32)psSec - (pgcu32)psCacheEntry;
#endif
a1 = (pgcu32)(psSec - psCacheEntry);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
a2 = (pgcu32)sizeof(SItemInCache);
iSecPos = a1 / a2;
bSecExist = PGCTRUE;
psSec->valid = PGCTRUE;
}
//重构缓冲区大小
2 years ago
AdjustCache(hProfile, 2);
psCacheEntry = g_pHandleIndex[hProfile].pCacheEntry;
iCurItem = g_pHandleIndex[hProfile].CurUseItems;
//应该插入新段名吗?
2 years ago
if (!bSecExist)
{
psTemp = &psCacheEntry[iCurItem];
#ifdef OS_WINDOWS
lstrcpyn((LPWSTR)psTemp->szSecName, (LPCWSTR)lpAppName, MAX_CHAR_LINE);
2 years ago
#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++;
}
//插入新项目名及项目值
2 years ago
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);
2 years ago
#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;
//如果指定段的项目存在则
2 years ago
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
2 years ago
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 参数说明 : LPTSTR lpszReturnBuffer --[out] 写入缓冲区
// 参数说明 : pgcu32 *pdwSize -- [in][out]写入缓冲区的按字节长度
// 参数说明 : pgcu32 *nSecNum --[out]将获取的段总数写入该地址
// 参数说明 : hProfile-- [in] handle to Profile Cache
2 years ago
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';
}
//求所有段名的字符个数总和以及段个数
2 years ago
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
// 函数说明 : 删除指定的项目
// 函数逻辑 :在缓冲中删除指定的项目,以及该项目上方的注释,然后以覆盖方式重写文件。
2 years ago
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 参数说明 : lpAppName --[in] 段名
// 参数说明 : lpKeyName -- [in]项目名
// 参数说明 : HPROFILE hProfile -[in]配置文件的缓冲句柄
2 years ago
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
// 函数说明 : 删除指定的段
// 函数逻辑 :在缓冲中删除指定的段,以及该段上方的注释,然后以覆盖方式重写文件;
// 在删除一个段的同时,该段下属的所有项目(包括项目上方的注释)将被删除
2 years ago
// 返回值说明 : int -- 成功则返回SUCCESS,失败则返回具体的执行失败的代码
// 参数说明 : lpAppName --[in] 段名
// 参数说明 : HPROFILE hProfile -[in]配置文件的缓冲句柄
2 years ago
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 杨小波++++++++++++++++++++++++++++++++++++++++++++
2 years ago
#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;
}