// // The developer of the original code and/or files is Tripwire, Inc. // Portions created by Tripwire, Inc. are copyright (C) 2000 Tripwire, // Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights // reserved. // // This program is free software. The contents of this file are subject // to the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. You may redistribute it and/or modify it // only in compliance with the GNU General Public License. // // This program is distributed in the hope that it will be useful. // However, this program is distributed AS-IS WITHOUT ANY // WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS // FOR A PARTICULAR PURPOSE. Please see the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // Nothing in the GNU General Public License or any other license to use // the code or files shall permit you to use Tripwire's trademarks, // service marks, or other intellectual property without Tripwire's // prior written consent. // // If you have any questions, please contact Tripwire, Inc. at either // info@tripwire.org or www.tripwire.org. // /////////////////////////////////////////////////////////////////////////////// // fcospeclist.cpp // // cFCOSpecList -- a list of iFCOSpec's with in a well defined order. /////////////////////////////////////////////////////////////////////////////// #include "stdfco.h" #include "fcospeclist.h" #include "fcospecutil.h" #include "core/serializer.h" #include "core/debug.h" #include "core/errorutil.h" /////////////////////////////////////////////////////////////////////////////// // class cFCOSpecList-- a list of iFCOSpec's with a well defined order. /////////////////////////////////////////////////////////////////////////////// IMPLEMENT_TYPEDSERIALIZABLE(cFCOSpecList, _T("cFCOSpecList"), 0, 1) cFCOSpecList::cFCOSpecList() { } cFCOSpecList::~cFCOSpecList() { Clear(); } void cFCOSpecList::Clear() { std::list::iterator itr; for (itr = mAddedList.begin(); itr != mAddedList.end(); itr++) { itr->first->Release(); itr->second->Release(); } mCanonicalList.clear(); mAddedList.clear(); } bool cFCOSpecList::IsEmpty() const { return mAddedList.empty(); } int cFCOSpecList::Size() const { return mAddedList.size(); } const cFCOSpecList& cFCOSpecList::operator = (const cFCOSpecList& rhs) { Clear(); cFCOSpecListAddedIter itr(rhs); for (itr.SeekBegin(); !itr.Done(); itr.Next()) { Add(itr.Spec(), itr.Attr()); } return *this; } void cFCOSpecList::Add(iFCOSpec* pSpec, cFCOSpecAttr* pAttr) { std::list::iterator itr; pSpec->AddRef(); if(pAttr == 0) pAttr = new cFCOSpecAttr; else pAttr->AddRef(); for (itr = mCanonicalList.begin(); ; ++itr) { if (itr == mCanonicalList.end() || iFCOSpecUtil::FCOSpecLessThan(*pSpec, *itr->first)) { mCanonicalList.insert(itr, PairType(pSpec, pAttr)); mAddedList.push_back(PairType(pSpec, pAttr)); break; } } } iFCOSpec* cFCOSpecList::Lookup(iFCOSpec* pSpec) const { std::list::iterator itr; for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr) if (itr->first == pSpec) { pSpec->AddRef(); return itr->first; } for (itr = mCanonicalList.begin(); itr != mCanonicalList.end(); ++itr) if (iFCOSpecUtil::FCOSpecEqual(*pSpec, *itr->first)) { itr->first->AddRef(); return itr->first; } return NULL; } void cFCOSpecList::Read(iSerializer* pSerializer, int32 version) { if (version > Version()) ThrowAndAssert(eSerializerVersionMismatch(_T("FCO Spec List"))); Clear(); int i; int32 size; pSerializer->ReadInt32(size); for (i = 0; i < size; ++i) { iFCOSpec* pReadInSpec = static_cast (pSerializer->ReadObjectDynCreate()); cFCOSpecAttr* pSpecAttr = static_cast(pSerializer->ReadObjectDynCreate()); Add(pReadInSpec, pSpecAttr); pReadInSpec->Release(); // Add() will increase the ref count by 1 pSpecAttr->Release(); } } void cFCOSpecList::Write(iSerializer* pSerializer) const { pSerializer->WriteInt32(Size()); cFCOSpecListAddedIter itr(*this); for (itr.SeekBegin(); !itr.Done(); itr.Next()) { pSerializer->WriteObjectDynCreate(itr.Spec()); pSerializer->WriteObjectDynCreate(itr.Attr()); } } /////////////////////////////////////////////////////////////////////////////// // class cFCOSpecListAddedIter -- iterate using the order in which items were // added to this list. /////////////////////////////////////////////////////////////////////////////// cFCOSpecListAddedIter::cFCOSpecListAddedIter(const cFCOSpecList& list) { mpSpecList = (cFCOSpecList*)&list; mIter = mpSpecList->mAddedList.begin(); } cFCOSpecListAddedIter::~cFCOSpecListAddedIter() { } void cFCOSpecListAddedIter::SeekBegin() const { mIter = mpSpecList->mAddedList.begin(); } bool cFCOSpecListAddedIter::Done() const { return mIter == mpSpecList->mAddedList.end(); } bool cFCOSpecListAddedIter::IsEmpty() const { return mpSpecList->mAddedList.empty(); } void cFCOSpecListAddedIter::Next() const { ++mIter; } const iFCOSpec* cFCOSpecListAddedIter::Spec() const { return mIter->first; } iFCOSpec* cFCOSpecListAddedIter::Spec() { return mIter->first; } const cFCOSpecAttr* cFCOSpecListAddedIter::Attr() const { return mIter->second; } cFCOSpecAttr* cFCOSpecListAddedIter::Attr() { return mIter->second; } void cFCOSpecListAddedIter::Remove() { ASSERT(! Done()); // the tricky part is finding the spec in the other list... std::list::iterator i; for(i = mpSpecList->mCanonicalList.begin(); i != mpSpecList->mCanonicalList.end(); i++) { if(i->first == mIter->first) break; } ASSERT(i != mpSpecList->mCanonicalList.end()); // now to do the deleteing! mIter = mpSpecList->mAddedList.erase(mIter); mpSpecList->mCanonicalList.erase(i); } /////////////////////////////////////////////////////////////////////////////// // class cFCOSpecListCanonicalIter -- iterate using the order in which items were // added to this list. /////////////////////////////////////////////////////////////////////////////// cFCOSpecListCanonicalIter::cFCOSpecListCanonicalIter(const cFCOSpecList& list) { mpSpecList = (cFCOSpecList*)&list; mIter = mpSpecList->mCanonicalList.begin(); } cFCOSpecListCanonicalIter::~cFCOSpecListCanonicalIter() { } void cFCOSpecListCanonicalIter::SeekBegin() const { mIter = mpSpecList->mCanonicalList.begin(); } bool cFCOSpecListCanonicalIter::Done() const { return mIter == mpSpecList->mCanonicalList.end(); } bool cFCOSpecListCanonicalIter::IsEmpty() const { return mpSpecList->mCanonicalList.empty(); } void cFCOSpecListCanonicalIter::Next() const { ++mIter; } const iFCOSpec* cFCOSpecListCanonicalIter::Spec() const { return mIter->first; } iFCOSpec* cFCOSpecListCanonicalIter::Spec() { return mIter->first; } const cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr() const { return mIter->second; } cFCOSpecAttr* cFCOSpecListCanonicalIter::Attr() { return mIter->second; }