windows-nt/Source/XPSP1/NT/net/rras/ras/autodial/rasauto/table.c
2020-09-26 16:20:57 +08:00

271 lines
5.1 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright(c) 1995 Microsoft Corporation
MODULE NAME
table.c
ABSTRACT
Generic hash table manipulation routines.
AUTHOR
Anthony Discolo (adiscolo) 28-Jul-1995
REVISION HISTORY
--*/
#define UNICODE
#define _UNICODE
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stdlib.h>
#include <windows.h>
#include <stdio.h>
#include <npapi.h>
#include <acd.h>
#include <debug.h>
#include "table.h"
#include "misc.h"
//
// Generic hash table entry.
//
typedef struct _HASH_ENTRY {
LIST_ENTRY ListEntry;
LPTSTR pszKey;
PVOID pData;
} HASH_ENTRY, *PHASH_ENTRY;
PHASH_TABLE
NewTable()
{
PHASH_TABLE pTable;
INT i;
pTable = LocalAlloc(LPTR, sizeof (HASH_TABLE));
if (pTable == NULL) {
RASAUTO_TRACE("NewTable: LocalAlloc failed");
return NULL;
}
for (i = 0; i < NBUCKETS; i++)
InitializeListHead(&pTable->ListEntry[i]);
pTable->ulSize = 0;
return pTable;
} // NewTable
VOID
FreeHashTableEntry(
IN PHASH_ENTRY pHashEntry
)
{
LocalFree(pHashEntry->pszKey);
if (pHashEntry->pData != NULL)
LocalFree(pHashEntry->pData);
LocalFree(pHashEntry);
} // FreeHashTableEntry
VOID
ClearTable(
IN PHASH_TABLE pTable
)
{
INT i;
PLIST_ENTRY pHead;
PHASH_ENTRY pHashEntry;
for (i = 0; i < NBUCKETS; i++) {
while (!IsListEmpty(&pTable->ListEntry[i])) {
pHead = RemoveHeadList(&pTable->ListEntry[i]);
pHashEntry = CONTAINING_RECORD(pHead, HASH_ENTRY, ListEntry);
FreeHashTableEntry(pHashEntry);
}
}
pTable->ulSize = 0;
} // ClearTable
VOID
EnumTable(
IN PHASH_TABLE pTable,
IN PHASH_TABLE_ENUM_PROC pProc,
IN PVOID pArg
)
{
INT i;
PLIST_ENTRY pEntry, pNextEntry;
PHASH_ENTRY pHashEntry;
for (i = 0; i < NBUCKETS; i++) {
pEntry = pTable->ListEntry[i].Flink;
while (pEntry != &pTable->ListEntry[i]) {
pHashEntry = CONTAINING_RECORD(pEntry, HASH_ENTRY, ListEntry);
//
// Get the next entry before calling
// the enumerator procedure to allow
// it to call DeleteTableEntry().
//
pNextEntry = pEntry->Flink;
//
// If the enumerator procedure
// returns FALSE, terminate the
// enumeration.
//
if (!pProc(pArg, pHashEntry->pszKey, pHashEntry->pData))
return;
pEntry = pNextEntry;
}
}
} // EnumTable
VOID
FreeTable(
IN PHASH_TABLE pTable
)
{
ClearTable(pTable);
LocalFree(pTable);
} // FreeTable
INT
HashString(
IN LPTSTR pszKey
)
{
CHAR ch;
DWORD dwHashValue = 0;
LPTSTR p = pszKey;
while (*p != L'\0') {
ch = (CHAR)tolower(*p);
dwHashValue += (INT)ch * (INT)ch;
p++;
}
return (INT)(dwHashValue % NBUCKETS);
} // HashString
PHASH_ENTRY
GetTableEntryCommon(
IN PHASH_TABLE pTable,
IN LPTSTR pszKey
)
{
INT nBucket = HashString(pszKey);
PLIST_ENTRY pEntry;
PHASH_ENTRY pHashEntry;
for (pEntry = pTable->ListEntry[nBucket].Flink;
pEntry != &pTable->ListEntry[nBucket];
pEntry = pEntry->Flink)
{
pHashEntry = CONTAINING_RECORD(pEntry, HASH_ENTRY, ListEntry);
if (!_wcsicmp(pHashEntry->pszKey, pszKey))
return pHashEntry;
}
return NULL;
} // GetTableEntryCommon
BOOLEAN
GetTableEntry(
IN PHASH_TABLE pTable,
IN LPTSTR pszKey,
OUT PVOID *pData
)
{
PHASH_ENTRY pHashEntry;
pHashEntry = GetTableEntryCommon(pTable, pszKey);
if (pHashEntry != NULL) {
if (pData != NULL)
*pData = pHashEntry->pData;
return TRUE;
}
return FALSE;
} // GetTableEntry
BOOLEAN
PutTableEntry(
IN PHASH_TABLE pTable,
IN LPTSTR pszKey,
IN PVOID pData
)
{
INT nBucket = HashString(pszKey);
PHASH_ENTRY pHashEntry;
pHashEntry = GetTableEntryCommon(pTable, pszKey);
if (pHashEntry == NULL) {
pHashEntry = LocalAlloc(LPTR, sizeof (HASH_ENTRY));
if (pHashEntry == NULL) {
RASAUTO_TRACE("PutTableEntry: LocalAlloc failed");
return FALSE;
}
pHashEntry->pszKey = CopyString(pszKey);
if (pHashEntry->pszKey == NULL) {
RASAUTO_TRACE("PutTableEntry: LocalAlloc failed");
LocalFree(pHashEntry);
return FALSE;
}
InsertHeadList(
&pTable->ListEntry[nBucket],
&pHashEntry->ListEntry);
pTable->ulSize++;
}
else {
if (pHashEntry->pData != pData)
LocalFree(pHashEntry->pData);
}
pHashEntry->pData = pData;
return TRUE;
} // PutTableEntry
BOOLEAN
DeleteTableEntry(
IN PHASH_TABLE pTable,
IN LPTSTR pszKey
)
{
PHASH_ENTRY pHashEntry;
pHashEntry = GetTableEntryCommon(pTable, pszKey);
if (pHashEntry != NULL) {
RemoveEntryList(&pHashEntry->ListEntry);
FreeHashTableEntry(pHashEntry);
pTable->ulSize--;
}
return (pHashEntry != NULL);
} // DeleteTableEntry