/***************************************************************************** * * 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 #include #include #include #ifdef OS_WINDOWS #include #include #include #else //#include #include //#include // #include #include #include #include #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 ** pphash_of_index ) { pgc32 i = 0; TChainHash * phash_table = NULL; phash_table = new TChainHash(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 *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 *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 * 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 *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 *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 *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 *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; }