NT4/private/ole32/stg/docfile/ulist.cxx
2020-09-30 17:12:29 +02:00

398 lines
11 KiB
C++

//+--------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: ulist.cxx
//
// Contents: CUpdateList implementation and support routines
//
// History: 15-Jan-92 DrewB Created
//
//---------------------------------------------------------------
#include <dfhead.cxx>
#pragma hdrstop
//+--------------------------------------------------------------
//
// Member: CUpdate::CUpdate, public
//
// Synopsis: Constructor
//
// Arguments: [pdfnCurrentName] - Current name pointer
// [pdfnOriginalName] - Original name pointer
// [dlLUID] - LUID
// [dwFlags] - Flags
// [ptsm] - Entry object
//
// History: 15-Jan-92 DrewB Created
//
//---------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdate_CUpdate)
#endif
CUpdate::CUpdate(CDfName const *pdfnCurrent,
CDfName const *pdfnOriginal,
DFLUID dlLUID,
DWORD dwFlags,
PTSetMember *ptsm)
{
SetCurrentName(pdfnCurrent);
SetOriginalName(pdfnOriginal);
_dl = dlLUID;
_dwFlags = dwFlags;
_ptsm = P_TO_BP(CBasedTSetMemberPtr, ptsm);
_pudNext = _pudPrev = NULL;
if (_ptsm)
_ptsm->AddRef();
}
//+---------------------------------------------------------------------------
//
// Member: CUpdate::~CUpdate, public
//
// Synopsis: Destructor
//
// History: 05-Nov-92 DrewB Created
//
//----------------------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdate_1CUpdate) // inline?
#endif
CUpdate::~CUpdate(void)
{
if (_ptsm)
_ptsm->Release();
}
//+--------------------------------------------------------------
//
// Member: CUpdateList::Add, public
//
// Synopsis: Adds an element to an update list
//
// Arguments: [pdfnCurrent] - Current name
// [pdfnOriginal] - Original name
// [dlLUID] - LUID
// [dwFlags] - Flags
// [ptsm] - Entry object
//
// Returns: The new element or NULL
//
// History: 15-Jan-92 DrewB Created
//
// Notes: Caller must handle NULL
// Entries must be added in the list in the order of
// Add calls
//
//---------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdateList_Add)
#endif
CUpdate *CUpdateList::Add(IMalloc * const pMalloc,
CDfName const *pdfnCurrent,
CDfName const *pdfnOriginal,
DFLUID dlLUID,
DWORD dwFlags,
PTSetMember *ptsm)
{
CUpdate *pudNew;
olDebugOut((DEB_ITRACE, "In CUpdateList::Add:%p("
"%ws, %ws, %ld, %lX, %p)\n", this, pdfnCurrent->GetBuffer(),
pdfnOriginal->GetBuffer(), dlLUID, dwFlags, ptsm));
olAssert((dlLUID != DF_NOLUID || pdfnOriginal != NULL) &&
aMsg("Create update luid can't be DF_NOLUID"));
pudNew = new (pMalloc) CUpdate(pdfnCurrent, pdfnOriginal, dlLUID,
dwFlags, ptsm);
if (pudNew)
{
Append(pudNew);
}
olDebugOut((DEB_ITRACE, "Out CUpdateList::Add => %p\n", pudNew));
return pudNew;
}
//+---------------------------------------------------------------------------
//
// Member: CUpdateList::Append, public
//
// Synopsis: Appends an update to the list
//
// Arguments: [pud] - Update
//
// History: 25-Nov-92 DrewB Created
//
//----------------------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdateList_Append)
#endif
void CUpdateList::Append(CUpdate *pud)
{
olDebugOut((DEB_ITRACE, "In CUpdateList::Append:%p(%p)\n", this, pud));
if (_pudTail)
_pudTail->SetNext(pud);
else
_pudHead = P_TO_BP(CBasedUpdatePtr, pud);
pud->SetPrev(BP_TO_P(CUpdate *, _pudTail));
pud->SetNext(NULL);
_pudTail = P_TO_BP(CBasedUpdatePtr, pud);
olDebugOut((DEB_ITRACE, "Out CUpdateList::Append\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CUpdateList::Remove, public
//
// Synopsis: Removes an element from the list
//
// Arguments: [pud] - Element to remove
//
// History: 25-Nov-92 DrewB Created
//
//----------------------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdateList_Remove)
#endif
void CUpdateList::Remove(CUpdate *pud)
{
olDebugOut((DEB_ITRACE, "In CUpdateList::Remove:%p(%p)\n", this, pud));
olAssert(pud != NULL);
CUpdate *pudNext = pud->GetNext();
CUpdate *pudPrev = pud->GetPrev();
if (pud->GetNext())
pudNext->SetPrev(pudPrev);
if (pud->GetPrev())
pudPrev->SetNext(pudNext);
if (pud == _pudHead)
_pudHead = P_TO_BP(CBasedUpdatePtr, pudNext);
if (pud == _pudTail)
_pudTail = P_TO_BP(CBasedUpdatePtr, pudPrev);
pud->SetNext(NULL);
pud->SetPrev(NULL);
olDebugOut((DEB_ITRACE, "Out CUpdateList::Remove\n"));
}
//+--------------------------------------------------------------
//
// Member: CUpdateList::Empty, public
//
// Synopsis: Frees all elements in an update list
//
// History: 06-Jan-92 DrewB Created
//
//---------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdateList_Empty)
#endif
void CUpdateList::Empty(void)
{
CUpdate *pudTmp;
olDebugOut((DEB_ITRACE, "In CUpdateList::Empty()\n"));
while (_pudHead)
{
pudTmp = _pudHead->GetNext();
delete BP_TO_P(CUpdate *, _pudHead);
_pudHead = P_TO_BP(CBasedUpdatePtr, pudTmp);
}
_pudTail = NULL;
olDebugOut((DEB_ITRACE, "Out CUpdateList::Empty\n"));
}
//+---------------------------------------------------------------------------
//
// Member: CUpdateList::IsEntry, public
//
// Synopsis: Checks the update list to see if the given name represents
// and existing entry in the list
//
// Arguments: [pdfn] - Name
// [ppud] - Update entry return or NULL
//
// Returns: UIE_CURRENT - Found as a current name
// UIE_ORIGINAL - Found as an original name
// UIE_NOTFOUND
//
// Modifies: [ppud]
//
// History: 02-Nov-92 DrewB Created
//
//----------------------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdateList_IsEntry)
#endif
UlIsEntry CUpdateList::IsEntry(CDfName const *pdfn, CUpdate **ppud)
{
CUpdate *pud;
UlIsEntry ret = UIE_NOTFOUND;
olDebugOut((DEB_ITRACE, "In CUpdateList::IsEntry:%p(%ws, %p)\n", this,
pdfn->GetBuffer(), ppud));
olAssert(pdfn != NULL && pdfn->GetLength() > 0);
for (pud = BP_TO_P(CUpdate *, _pudTail); pud; pud = pud->GetPrev())
{
if (pdfn->IsEqual(pud->GetCurrentName()))
{
ret = UIE_CURRENT;
break;
}
else if (pdfn->IsEqual(pud->GetOriginalName()))
{
ret = UIE_ORIGINAL;
break;
}
}
olDebugOut((DEB_ITRACE, "Out CUpdateList::IsEntry\n"));
if (ppud)
*ppud = pud;
return ret;
}
//+---------------------------------------------------------------------------
//
// Member: CUpdateList::Concat, public
//
// Synopsis: Concatenates an update list onto the end of this one
//
// Arguments: [ul] - List to concatenate
//
// History: 02-Nov-92 DrewB Created
//
// Notes: [ul]'s head may be modified
//
//+---------------------------------------------------------------------------
#ifdef FUTURECODE
void CUpdateList::Concat(CUpdateList &ul)
{
olDebugOut((DEB_ITRACE, "In CUpdateList::Concat:%p(ul)\n", this));
if (_pudTail)
{
_pudTail->SetNext(ul.GetHead());
if (ul.GetHead())
{
ul.GetHead()->SetPrev(_pudTail);
olAssert(ul.GetTail() != NULL);
_pudTail = ul.GetTail();
}
}
else
{
olAssert(_pudHead == NULL);
_pudHead = ul.GetHead();
_pudTail = ul.GetTail();
}
olDebugOut((DEB_ITRACE, "Out CUpdateList::Concat\n"));
}
#endif
//+---------------------------------------------------------------------------
//
// Member: CUpdateList::Exists, public static
//
// Synopsis: Traverses an update list from a particular point
// and determines whether a given name exists or
// is renamed
//
// Arguments: [pud] - Update to look from
// [ppdfn] - Name in/out
// [fRename] - Perform renames or quit
//
// Returns: TRUE if exists
// FALSE if deleted
//
// History: 03-Nov-92 DrewB Created
//
//----------------------------------------------------------------------------
#ifdef FUTURECODE
BOOL CUpdateList::Exists(CUpdate *pud,
CDfName **ppdfn,
BOOL fRename)
{
for (; pud; pud = pud->GetNext())
{
if (pud->IsRename() &&
(*ppdfn)->IsEqual(pud->GetOriginalName()))
{
if (fRename)
*ppdfn = pud->GetCurrentName();
else
return FALSE;
}
else if (pud->IsDelete() &&
(*ppdfn)->IsEqual(pud->GetOriginalName()))
{
return FALSE;
}
}
return TRUE;
}
#endif
//+---------------------------------------------------------------------------
//
// Member: CUpdateList::FindBase, public static
//
// Synopsis: Searches backwards in an update list for the creation of
// a particular object, applying renames if necessary
//
// Arguments: [pud] - Update to start from
// [ppdfn] - Name in/out
//
// Returns: Pointer to update entry for creation or NULL if
// no creation entry. [ppdfn] is changed to point to
// the base name.
//
// Modifies: [ppdfn]
//
// History: 16-Apr-93 DrewB Created
//
// Notes: Does not kill the search on deletions; primarily
// intended to be used with names that represent existing
// entries, although it will work on any name
//
//----------------------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CUpdateList_FindBase)
#endif
CUpdate *CUpdateList::FindBase(CUpdate *pud, CDfName const **ppdfn)
{
for (; pud; pud = pud->GetPrev())
{
if (pud->IsRename() &&
(*ppdfn)->IsEqual(pud->GetCurrentName()))
{
*ppdfn = pud->GetOriginalName();
}
else if (pud->IsCreate() &&
(*ppdfn)->IsEqual(pud->GetCurrentName()))
{
return pud;
}
}
return NULL;
}