|
|
/******************************************************************************
Header File: Utility Classes.CPP
These classes are generally useful classes which can be used for a variety of purposes. I created this separate file for quicker reuse later, and also to avoid having to include some very specific header file just to get these general-purpose classes.
Copyright (c) 1997 by Microsoft Corporation. All Rights Reserved.
A Pretty Penny Enterprises Production
Change History: 03-01-1997 Bob_Kjelgaard@Prodigy.Net Created it
******************************************************************************/
#include "StdAfx.H"
#if defined(LONG_NAMES)
#include "Utility Classes.H"
#else
#include "Utility.H"
#endif
/******************************************************************************
CMapWordToDWord class
This class uses CMapWordToPtr to do its dirty work. When the need arises, I will make it serializable
******************************************************************************/
BOOL CMapWordToDWord::Lookup(WORD wKey, DWORD& dwItem) const { union { void* pv; DWORD dw; };
if (!CMapWordToPtr::Lookup(wKey, pv)) return FALSE;
dwItem = dw; return TRUE; }
/******************************************************************************
CMapWordToDWord::GetNextAssoc
This is the map iteration method. We call the same method on the bas class, and update the DWORD parameter if the underlying method is successful.
******************************************************************************/
void CMapWordToDWord::GetNextAssoc(POSITION& pos, WORD& wKey, DWORD& dwItem) const { union { void* pv; DWORD dw; };
CMapWordToPtr::GetNextAssoc(pos, wKey, pv);
dwItem = dw; }
/******************************************************************************
CMapWordToDWord::Operator[]
This implements an l-value only operator usable for adding new associations or updating existing ones.
******************************************************************************/
DWORD& CMapWordToDWord::operator[](WORD wKey) { return (DWORD&) CMapWordToPtr::operator[](wKey); }
/******************************************************************************
CSafeObArray class implementation
This provides a "Safe" CObArray class which can't leak!
******************************************************************************/
IMPLEMENT_SERIAL(CSafeObArray, CObject, 0);
/******************************************************************************
CSafeObArray::~CSafeObArray
The class destructor will delete the object foreach non-NULL pointer in the array.
******************************************************************************/
CSafeObArray::~CSafeObArray() { for (unsigned u = 0; u < GetSize(); u++) if (m_coa[u]) delete m_coa[u]; }
/******************************************************************************
CSafeObArray::RemoveAll
Almost the same as the destructor, isn't it?
******************************************************************************/
void CSafeObArray::RemoveAll() { for (unsigned u = 0; u < GetSize(); u++) if (m_coa[u]) delete m_coa[u];
m_coa.RemoveAll(); }
/******************************************************************************
CSafeObArray::RemoveAt
This removes one element from the array- after deleting it, of course.
******************************************************************************/
void CSafeObArray::RemoveAt(int i) { if (m_coa[i]) delete m_coa[i]; m_coa.RemoveAt(i); }
/******************************************************************************
CSafeObArray::Copy
Copy the contents of one array to another.
******************************************************************************/
void CSafeObArray::Copy(CSafeObArray& csoa) { m_coa.Copy(*(csoa.GetCOA())) ; }
/******************************************************************************
CSafeObArray::Serialize
I call the CObject serializer to maintain the proper typ einformation, then let the CObArray serialize itself.
******************************************************************************/
void CSafeObArray::Serialize(CArchive& car) { if (car.IsLoading()) RemoveAll();
CObject::Serialize(car); m_coa.Serialize(car); }
/******************************************************************************
CSafeMapWordToOb implementation
Making the workd safe for maps.
******************************************************************************/
IMPLEMENT_SERIAL(CSafeMapWordToOb, CObject, 0)
/******************************************************************************
CSafeMapWordToOb::~CSafeMapWordToOb
The class destructor must ensure the underlying objects are deleted.
******************************************************************************/
CSafeMapWordToOb::~CSafeMapWordToOb() { WORD wKey; CObject *pco;
for (POSITION pos = m_cmw2o.GetStartPosition(); pos; ) { m_cmw2o.GetNextAssoc(pos, wKey, pco); if (pco) delete pco; } }
/******************************************************************************
CSafeMapWordToOb::operator[]
The problem here is that this is used only to put elements in the map- therefore, I intercept the call and delete any existing item. This could cause problems if the same pointer is re-inserted into the map, but for now, I'll take my chances.
******************************************************************************/
CObject*& CSafeMapWordToOb::operator[](WORD wKey) { CObject*& pco = m_cmw2o.operator[](wKey);
if (pco) delete pco; return pco; }
/******************************************************************************
CSafeMapWordToOb::RemoveKey
Pretty Obvious- if there was an object there, remove it.
******************************************************************************/
BOOL CSafeMapWordToOb::RemoveKey(WORD wKey) {
CObject *pco;
if (!m_cmw2o.Lookup(wKey, pco)) return FALSE;
if (pco) delete pco;
return m_cmw2o.RemoveKey(wKey); }
/******************************************************************************
CSafeMapWordToOb::RemoveAll
Again, this is pretty obvious- destroy anything that lives!
******************************************************************************/
void CSafeMapWordToOb::RemoveAll() { WORD wKey; CObject *pco;
for (POSITION pos = m_cmw2o.GetStartPosition(); pos; ) { GetNextAssoc(pos, wKey, pco); if (pco) delete pco; }
m_cmw2o.RemoveAll(); }
/******************************************************************************
CSafeMapWordToOb::Serialize
First, I depopulate the map if it is being loaded. Then I call the CObject serializer to handle run-time typing checks, and then serialize the underlying map.
******************************************************************************/
void CSafeMapWordToOb::Serialize(CArchive& car) { if (car.IsLoading()) RemoveAll();
CObject::Serialize(car); m_cmw2o.Serialize(car); }
|