|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: Stack.cpp
//
// History: 31-Mar-1997 pberkman created
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include "Stack.hxx"
Stack_::Stack_(CRITICAL_SECTION *pCS) { dwStackCount = 0; psBottom = NULL; ppsSorted = NULL; ppsGet = NULL; pSortCriticalSection = pCS; }
Stack_::~Stack_(void) { if (psBottom) { StackStruct_ *psCurrent;
for (;;) { psCurrent = psBottom->psNext;
delete psBottom->pvData; delete psBottom;
psBottom = psCurrent;
if (!(psBottom)) { break; } } }
DELETE_OBJECT(ppsSorted);
FlushGetStack(); }
BOOL Stack_::Add(DWORD cbData, void *pvData) { BYTE *pb;
if (pb = (BYTE *)this->Add(cbData)) { memcpy(pb, pvData, cbData); return(TRUE); }
return(FALSE); }
void *Stack_::Add(DWORD cbData) { StackStruct_ *psWork;
psWork = new StackStruct_;
if (!(psWork)) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return(NULL); }
psWork->psNext = psBottom;
psWork->pvData = new BYTE[cbData];
if (!(psWork->pvData)) { delete psWork;
SetLastError(ERROR_NOT_ENOUGH_MEMORY); return(FALSE); }
psWork->cbData = cbData;
psBottom = psWork;
dwStackCount++;
FlushGetStack();
return((void *)psWork->pvData); }
void *Stack_::Get(DWORD dwPosition, DWORD *cbData) { DWORD i; StackStruct_ *psRet;
if (!(psBottom)) { return(NULL); }
if (dwPosition > (dwStackCount - 1)) { return(NULL); }
if ( InitGetStackIfNecessary() == TRUE ) { DWORD Index = dwPosition;
if ( cbData != NULL ) { *cbData = ppsGet[ Index ]->cbData; }
return( ppsGet[ Index ]->pvData ); }
psRet = psBottom;
if (cbData) { *cbData = 0; }
for (i = 0; i < dwPosition; i++) { psRet = psRet->psNext; }
if ((psRet) && (psRet->pvData)) { if (cbData) { *cbData = psRet->cbData; }
return(psRet->pvData); }
return(NULL); }
void *Stack_::Get(DWORD cbStartIn_pvData, DWORD cbLengthIn_pvData, BYTE fbType, void *pvMemberOf_pvData) { DWORD dwEnd; DWORD dwMiddle; DWORD dwStart; DWORD dwHalf; DWORD dwCur; void *pv; int cmp;
dwStart = 0; dwEnd = this->Count(); dwHalf = dwMiddle = dwEnd / 2L; dwCur = 0;
for EVER { if (dwCur++ > this->Count()) { break; }
pv = this->Get(dwMiddle);
if (!(pv)) { break; }
switch (fbType) { case STACK_SORTTYPE_PWSZ: cmp = wcscmp(*(WCHAR **)((BYTE *)pv + cbStartIn_pvData), (WCHAR *)pvMemberOf_pvData); break;
case STACK_SORTTYPE_PSZ: cmp = strcmp(*(char **)((BYTE *)pv + cbStartIn_pvData), (char *)pvMemberOf_pvData); break;
case STACK_SORTTYPE_PWSZ_I: cmp = _wcsicmp(*(WCHAR **)((BYTE *)pv + cbStartIn_pvData), (WCHAR *)pvMemberOf_pvData); break;
case STACK_SORTTYPE_PSZ_I: cmp = _stricmp(*(char **)((BYTE *)pv + cbStartIn_pvData), (char *)pvMemberOf_pvData); break;
default: cmp = memcmp((BYTE *)pv + cbStartIn_pvData, (BYTE *)pvMemberOf_pvData, cbLengthIn_pvData); break; }
if (cmp == 0) { return(pv); }
if ((dwMiddle == 0) || (dwMiddle == this->Count()) || ((dwHalf == 0) && (dwMiddle == dwStart))) { break; }
if (cmp < 0) { dwEnd = dwMiddle; } else { dwStart = dwMiddle; }
dwHalf = (dwEnd - dwStart) / 2L; dwMiddle = dwStart + dwHalf; }
return(NULL); }
static DWORD cbSortOffset; static DWORD cbSortLength; static BYTE fbType;
int __cdecl Stack_compare(const void *arg1, const void *arg2) { StackStruct_ **p1 = (StackStruct_ **)arg1; StackStruct_ **p2 = (StackStruct_ **)arg2;
switch (fbType) { case STACK_SORTTYPE_PWSZ: return(wcscmp(*(WCHAR **)((BYTE *)(*p1)->pvData + cbSortOffset), *(WCHAR **)((BYTE *)(*p2)->pvData + cbSortOffset)));
case STACK_SORTTYPE_PSZ: return(strcmp(*(char **)((BYTE *)(*p1)->pvData + cbSortOffset), *(char **)((BYTE *)(*p2)->pvData + cbSortOffset)));
case STACK_SORTTYPE_PWSZ_I: return(_wcsicmp(*(WCHAR **)((BYTE *)(*p1)->pvData + cbSortOffset), *(WCHAR **)((BYTE *)(*p2)->pvData + cbSortOffset)));
case STACK_SORTTYPE_PSZ_I: return(_stricmp(*(char **)((BYTE *)(*p1)->pvData + cbSortOffset), *(char **)((BYTE *)(*p2)->pvData + cbSortOffset)));
case STACK_SORTTYPE_BINARY: default: break; }
return(memcmp((void **)((BYTE *)(*p1)->pvData + cbSortOffset), (void **)((BYTE *)(*p2)->pvData + cbSortOffset), cbSortLength)); }
void Stack_::Sort(DWORD cbOffset_pvData, DWORD cbLength_pvData, BYTE fbTypeIn) { int i;
if (!(psBottom)) { return; }
//
// assign out offset & length for compare function
//
DELETE_OBJECT(ppsSorted); // wipe the last one.
if (!(ppsSorted = new StackStruct_ * [this->Count()])) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); return; }
//
// assign the contiguous array to be sorted.
//
ppsSorted[0] = psBottom;
for (i = 1; i < (int)this->Count(); i++) { ppsSorted[i] = ppsSorted[i - 1]->psNext; }
//
// let's do the sort!
//
EnterCriticalSection(pSortCriticalSection);
cbSortOffset = cbOffset_pvData; cbSortLength = cbLength_pvData; fbType = fbTypeIn;
qsort( (void *)ppsSorted, (size_t)this->Count(), sizeof(StackStruct_ *), Stack_compare);
LeaveCriticalSection(pSortCriticalSection);
//
// now, we need to adjust out psNext's
//
for (i = 0; i < (int)(this->Count() - 1); i++) { ppsSorted[i]->psNext = ppsSorted[i + 1]; }
ppsSorted[i]->psNext = NULL;
psBottom = ppsSorted[0];
FlushGetStack(); }
BOOL Stack_::InitGetStackIfNecessary () { DWORD cCount; StackStruct_* psGet;
if ( ppsGet != NULL ) { return( TRUE ); }
ppsGet = new StackStruct_ * [ dwStackCount ];
if ( ppsGet == NULL ) { return( FALSE ); }
psGet = psBottom;
for ( cCount = 0; cCount < dwStackCount; cCount++ ) { ppsGet[ cCount ] = psGet; psGet = psGet->psNext; }
return( TRUE ); }
VOID Stack_::FlushGetStack () { delete ppsGet; ppsGet = NULL; }
|