Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

405 lines
7.1 KiB

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corp., 1995 **/
/**********************************************************************/
/*
FILE HISTORY:
*/
#include "stdafx.h"
#include "comprop.h"
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
CObjHelper :: CObjHelper ()
: m_ctor_err( 0 ),
m_api_err( 0 ),
m_b_dirty( FALSE ),
m_time_created( ::GetCurrentTime() )
{
}
void
CObjHelper :: ReportError (
LONG errInConstruction
)
{
TRACEEOLID( _T("CObjectPlus construction failure, error = ")
<< errInConstruction );
m_ctor_err = errInConstruction;
}
LONG
CObjHelper :: SetApiErr (
LONG errApi
)
{
return m_api_err = errApi;
}
void
CObjHelper :: AssertValid () const
{
ASSERT(QueryError() == 0);
}
BOOL
CObjHelper :: IsValid () const
{
return QueryError() == 0;
}
DWORD
CObjHelper :: QueryAge () const
{
DWORD dwTime = ::GetCurrentTime(),
dwDiff ;
if ( dwTime < m_time_created )
{
dwDiff = dwTime + (((DWORD) -1) - (m_time_created - 1));
}
else
{
dwDiff = dwTime - m_time_created;
}
return dwDiff;
}
//
// Constructor of extended object
//
CObjectPlus :: CObjectPlus ()
{
}
//
// Compare one object with another: default implementation
// orders objects by creation time. Return -1, 0 or 1.
//
int
CObjectPlus :: Compare (
const CObjectPlus * pob
) const
{
return QueryCreationTime() < pob->QueryCreationTime()
? -1
: QueryCreationTime() != pob->QueryCreationTime();
}
CObListIter :: CObListIter (
const CObOwnedList & obList
)
: m_obList( obList )
{
Reset();
}
void
CObListIter :: Reset ()
{
m_pos = m_obList.GetCount()
? m_obList.GetHeadPosition()
: NULL;
}
CObject * CObListIter :: Next ()
{
return m_pos == NULL
? NULL
: m_obList.GetNext(m_pos);
}
//
// Subclass of CObList whose default behavior is to destroy
// its contents during its own destruction
//
CObOwnedList :: CObOwnedList (
int nBlockSize
)
: CObList( nBlockSize ),
m_b_owned( TRUE )
{
}
CObOwnedList :: ~ CObOwnedList ()
{
RemoveAll() ;
}
void
CObOwnedList :: RemoveAll ()
{
if ( m_b_owned )
{
//
// Remove and discard all the objects
//
while ( ! IsEmpty() )
{
CObject * pob = RemoveHead() ;
delete pob ;
}
}
else
{
//
// Just remove the object pointers
//
CObList::RemoveAll() ;
}
}
CObject *
CObOwnedList :: Index (
int index
)
{
CObListIter oli( *this ) ;
CObject * pob ;
for (int i = 0 ; (pob = oli.Next()) && i++ < index ; );
return pob;
}
CObject *
CObOwnedList :: RemoveIndex (
int index
)
{
POSITION pos ;
CObListIter oli( *this ) ;
int i ;
CObject * pob ;
for ( i = 0, pos = oli.QueryPosition() ;
(pob = oli.Next()) && i < index ;
i++, pos = oli.QueryPosition() );
if ( pob && i == index )
{
RemoveAt(pos);
}
else
{
pob = NULL;
}
return pob;
}
//
// Remove the first (and hopefully only) occurrence of an object
// pointer from this list.
//
BOOL
CObOwnedList :: Remove (
CObject * pob
)
{
POSITION pos = Find( pob ) ;
if (pos == NULL)
{
return FALSE;
}
RemoveAt(pos);
return TRUE;
}
//
// Set all elements to dirty or clean. Return TRUE if
// any element was dirty.
//
BOOL
CObOwnedList :: SetAll (
BOOL bDirty
)
{
int cDirtyItems = 0 ;
CObListIter oli( *this ) ;
CObjectPlus * pob ;
while ( pob = (CObjectPlus *) oli.Next() )
{
cDirtyItems += pob->IsDirty();
pob->SetDirty( bDirty );
}
SetDirty(bDirty);
return cDirtyItems > 0;
}
int
CObOwnedList :: FindElement (
CObject * pobSought
) const
{
CObListIter oli( *this ) ;
CObject * pob ;
for ( int i = 0 ;
(pob = oli.Next()) && pob != pobSought;
i++ );
return pob
? i
: -1;
}
//
// Override of CObList::AddTail() to control exception handling.
// Returns NULL if addition fails.
//
POSITION
CObOwnedList :: AddTail (
CObjectPlus * pobj,
BOOL bThrowException
)
{
POSITION pos = NULL ;
//
// Catch only memory exceptions.
//
TRY
{
pos = CObList::AddTail( pobj ) ;
}
CATCH( CMemoryException, e )
{
pos = NULL ;
}
END_CATCH
if ( pos == NULL && bThrowException )
{
//
// CObList::AddTail() threw an exception. Echo it.
//
::AfxThrowMemoryException() ;
}
return pos ;
}
typedef struct
{
CObjectPlus * pObj ; // Pointer to object to be sorted
CObjectPlus::PCOBJPLUS_ORDER_FUNC pFunc ; // Pointer to ordering function
} CBOWNEDLIST_SORT_HELPER ;
//
// This static member function is used to quick sort an array of structures
// as declared above. Each element contains the object pointer and a
// pointer to the object's member function to be invoked for comparison.
//
//
int _cdecl
CObOwnedList :: SortHelper (
const void * pa,
const void * pb
)
{
CBOWNEDLIST_SORT_HELPER
* pHelp1 = (CBOWNEDLIST_SORT_HELPER *) pa,
* pHelp2 = (CBOWNEDLIST_SORT_HELPER *) pb ;
return (pHelp1->pObj->*pHelp1->pFunc)( pHelp2->pObj );
}
//
// Sort the list by recreating it entirely.
//
LONG
CObOwnedList :: Sort (
CObjectPlus::PCOBJPLUS_ORDER_FUNC pOrderFunc
)
{
LONG err = 0 ;
int cItems = GetCount() ;
if ( cItems < 2 )
{
return NO_ERROR ;
}
CObListIter obli( *this ) ;
CObjectPlus * pObNext ;
BOOL bOwned = SetOwnership( FALSE ) ;
int i ;
CBOWNEDLIST_SORT_HELPER * paSortHelpers = NULL ;
CATCH_MEM_EXCEPTION
{
//
// Allocate the helper array
//
paSortHelpers = new CBOWNEDLIST_SORT_HELPER[ cItems ] ;
//
// Fill the helper array.
//
for ( i = 0 ; pObNext = (CObjectPlus *) obli.Next() ; i++ )
{
paSortHelpers[i].pFunc = pOrderFunc ;
paSortHelpers[i].pObj = pObNext ;
}
//
// Release all object pointer references. Note that we
// forced "owned" to FALSE above.
//
RemoveAll() ;
ASSERT( GetCount() == 0 ) ;
//
// Sort the helper array
//
::qsort( (void *) paSortHelpers,
cItems,
sizeof paSortHelpers[0],
SortHelper
);
//
// Refill the list from the helper array.
//
for ( i = 0 ; i < cItems ; i++ )
{
AddTail( paSortHelpers[i].pObj ) ;
}
ASSERT( GetCount() == cItems ) ;
}
END_MEM_EXCEPTION(err)
//
// Delete the working array
//
delete [] paSortHelpers;
//
// Restore the object ownership state
//
SetOwnership(bOwned);
return err;
}