home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
opendc12.zip
/
od124os2.exe
/
od12osr1.exe
/
src
/
DocPriv.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-21
|
36KB
|
1,196 lines
/* @(#)Z 1.9 com/src/bento/DocPriv.cpp, odstorage, od96os2, odos29712d 97/03/21 17:19:17 (96/10/29 09:11:49) */
//====START_GENERATED_PROLOG======================================
//
//
// COMPONENT_NAME: odstorage
//
// CLASSES: none
//
// ORIGINS: 82,27
//
//
// (C) COPYRIGHT International Business Machines Corp. 1995,1996
// All Rights Reserved
// Licensed Materials - Property of IBM
// US Government Users Restricted Rights - Use, duplication or
// disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//
// IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
// ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
// USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
// OR PERFORMANCE OF THIS SOFTWARE.
//
//====END_GENERATED_PROLOG========================================
//
/*
File: DocPriv.cpp
Contains: Implementation for Private class for CMDocument.
Owned by: Vincent Lo
Copyright: ⌐ 1993-1995 by Apple Computer, Inc., all rights reserved.
Change History (most recent first):
<21> 8/21/95 VL 1278330, 1278315: Error code cleanup.
<20> 5/26/95 VL 1251403: Multithreading naming support.
<19> 5/25/95 jpa List.h --> LinkList.h [1253324] Fixed
misuse of ODDebug [1253321]
<18> 4/14/95 EL 1239463: Remove Change should not reduce
version id to 0.
<17> 3/31/95 EL 1234685: ExportTo has extra parameter so we
can skip top draft. Dirty flag no longer
needed because version list only
externalized on close or flush.
<16> 3/29/95 DM make standard format little endian
<15> 3/24/95 EL 1209355: dirty flag for version list. Temp
fix: remove duplicate drafts when version
list is read.
<14> 3/23/95 VL 1228003: Added Print.
<13> 3/9/95 VL 1226089: Introduced fHighestDraftID to
prevent DraftID from being reused in a
session.
<12> 2/15/95 EL 1182275: Add GetSameVersionDraftID to get
the lowest draft that has the same version
as the latest draft.
<11> 1/31/95 EL 1213321: Do not output tomstoned versions
during externalization.
<10> 1/11/95 VL 1185688: Made storage more robust in terms
of error handling. Also did some code
review cleanup.
<9> 11/14/94 VL 1188257: Use Bento errors in BenotDef.h.
<8> 9/5/94 VL 1184871: Remove dependency on default heap
by calling ODRecoverHeapID>
<7> 8/26/94 VL 1183174: Use updated GetSTorageUnitRef
which takes ID.
<6> 7/11/94 VL Added Exists calls.
<5> 7/7/94 VL Commented out use of ODRecoverHeapID.
<4> 6/28/94 VL ODRecoverHeap to ODRecoverHeapID.
<3> 6/20/94 CC ODMemoryHeap* changed to ODMemoryHeapID.
<2> 6/15/94 RR ODHeap -> ODMemoryHeap
<1> 5/27/94 VL first checked in
To Do:
1) Get rid of tombstoned versions.
In Progress:
*/
#ifndef _DOCPRIV_
#include "DocPriv.h"
#endif
#ifndef _FLIPEND_
#include "FlipEnd.h"
#endif
#ifndef SOM_CMDocument_xh
#include "CMDoc.xh"
#endif
#ifndef _LINKLIST_
#include "LinkList.h"
#endif
#ifndef _EXCEPT_
#include "Except.h"
#endif
#ifndef _ODDEBUG_
#include "ODDebug.h"
#endif
#ifndef _ODMEMORY_
#include "ODMemory.h"
#endif
#ifndef _ODNEW_
#include "ODNew.h"
#endif
#ifndef SOM_CMDraft_xh
#include "CMDraft.xh"
#endif
#ifndef _BENTODEF_
#include "BentoDef.h"
#endif
#if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
#ifndef _ODUTILS_
#include "ODUtils.h"
#endif
#endif
#ifndef som_xh
#include "som.xh"
#endif
#pragma segment Document
//==============================================================================
// Scalar Types
//==============================================================================
#if ODDebug
// #define DebugStorage 1
#endif
#ifdef DebugStorage
#define MyDebug3Str(f,p1,p2,p3) somPrintf(f, p1, p2, p3)
#else
#define MyDebug3Str(f,p1,p2,p3)
#endif
typedef struct {
ODDraftID draftID;
ODVersionID versionID;
} VersionRecord;
#ifdef STORAGE_TEST
inline void BREAK_AND_THROW(ODError e)
{
Debugger();
THROW(e);
}
#else
#define BREAK_AND_THROW(e) THROW(e)
#endif
//==============================================================================
// DraftList
//==============================================================================
//------------------------------------------------------------------------------
// DraftList::DraftList
//------------------------------------------------------------------------------
DraftList::DraftList()
{
fHeap = kODNULL;
}
//------------------------------------------------------------------------------
// DraftList::~DraftList
//------------------------------------------------------------------------------
DraftList::~DraftList()
{
Link* link;
link = fLinkedList->RemoveFirst();
while (link != kODNULL) {
delete link;
link = fLinkedList->RemoveFirst();
}
delete fLinkedList;
}
//------------------------------------------------------------------------------
// DraftList::Initialize
//------------------------------------------------------------------------------
void DraftList::Initialize()
{
fHeap = ODRecoverHeapID(this);
#ifdef _PLATFORM_MACINTOSH_
fLinkedList = new(GetHeap()) LinkedList;
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
fLinkedList = new LinkedList;
#endif
}
//------------------------------------------------------------------------------
// DraftList::Get
//------------------------------------------------------------------------------
CMDraft* DraftList::Get(ODDraftID draftID)
{
CMDraft* retDraft = kODNULL;
DraftLink* link = this->GetLink(draftID);
if (link != kODNULL)
retDraft = link->GetDraft();
return retDraft;
}
//------------------------------------------------------------------------------
// DraftList::Add
//------------------------------------------------------------------------------
void DraftList::Add(ODDraftID draftID, CMDraft* draft)
{
Environment* ev = somGetGlobalEnvironment();
CMDraft* existingDraft = kODNULL;
DraftLink* link = kODNULL;
try
{
if ((existingDraft = this->Get(draftID)) == kODNULL) {
#ifdef _PLATFORM_MACINTOSH_
link = new(GetHeap()) DraftLink(draftID, draft);
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
link = new DraftLink(draftID, draft);
#endif
fLinkedList->AddLast(link);
}
else {
if (draftID != existingDraft->GetID(ev))
BREAK_AND_THROW(kODErrDraftExistsWithDifferentID);
}
}
catch (ODException _exception)
{
ODDeleteObject(link);
throw;
}
}
//------------------------------------------------------------------------------
// DraftList::Remove
//------------------------------------------------------------------------------
void DraftList::Remove(ODDraftID draftID)
{
DraftLink* link = this->GetLink(draftID);
if (link == kODNULL)
BREAK_AND_THROW(kODErrDraftDoesNotExist);
else {
fLinkedList->Remove(*link);
delete link;
}
}
//------------------------------------------------------------------------------
// DraftList::Count
//------------------------------------------------------------------------------
ODULong DraftList::Count()
{
return fLinkedList->Count();
}
//------------------------------------------------------------------------------
// DraftList::GetLink
//------------------------------------------------------------------------------
DraftLink* DraftList::GetLink(ODDraftID draftID)
{
LinkedListIterator iter(fLinkedList);
DraftLink *link = (DraftLink*) iter.Last();
while ((link != kODNULL) && (link->GetDraftID() != draftID)) {
link = (DraftLink*) iter.Previous();
}
return link;
}
//------------------------------------------------------------------------------
// DraftList::GetHeap
//------------------------------------------------------------------------------
ODMemoryHeapID DraftList::GetHeap()
{
return fHeap;
}
//------------------------------------------------------------------------------
// DraftList::GetLinkedList
//------------------------------------------------------------------------------
LinkedList* DraftList::GetLinkedList()
{
return fLinkedList;
}
//==============================================================================
// DraftListIterator
//==============================================================================
//------------------------------------------------------------------------------
// DraftListIterator::DraftListIterator
//------------------------------------------------------------------------------
DraftListIterator::DraftListIterator(DraftList* draftList)
{
fDraftList = draftList;
}
//------------------------------------------------------------------------------
// DraftListIterator::~DraftListIterator
//------------------------------------------------------------------------------
DraftListIterator::~DraftListIterator()
{
delete fIterator;
}
//------------------------------------------------------------------------------
// DraftListIterator::Initialize
//------------------------------------------------------------------------------
void DraftListIterator::Initialize()
{
#ifdef _PLATFORM_MACINTOSH_
fIterator = new(fDraftList->GetHeap()) LinkedListIterator(fDraftList->GetLinkedList());
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
fIterator = new LinkedListIterator(fDraftList->GetLinkedList());
#endif
}
//------------------------------------------------------------------------------
// DraftListIterator::Last
//------------------------------------------------------------------------------
CMDraft* DraftListIterator::Last()
{
CMDraft* retDraft = kODNULL;
DraftLink* link = (DraftLink*) fIterator->Last();
if (link != kODNULL)
retDraft = link->GetDraft();
return retDraft;
}
//------------------------------------------------------------------------------
// DraftListIterator::Previous
//------------------------------------------------------------------------------
CMDraft* DraftListIterator::Previous()
{
CMDraft* retDraft = kODNULL;
DraftLink* link = (DraftLink*) fIterator->Previous();
if (link != kODNULL)
retDraft = link->GetDraft();
return retDraft;
}
//------------------------------------------------------------------------------
// DraftListIterator::IsNotComplete
//------------------------------------------------------------------------------
ODBoolean DraftListIterator::IsNotComplete()
{
return (fIterator->IsNotComplete());
}
//==============================================================================
// VersionLink
//==============================================================================
//------------------------------------------------------------------------------
// VersionLink::VersionLink
//------------------------------------------------------------------------------
VersionLink::VersionLink(ODDraftID draftID, ODVersionID versionID)
: Link()
{
fDraftID = draftID;
fVersionID = versionID;
}
//==============================================================================
// VersionList
//==============================================================================
//------------------------------------------------------------------------------
// VersionList::VersionList
//------------------------------------------------------------------------------
VersionList::VersionList()
{
fHighestDraftID = 0;
fLatestVersionID = 0;
fLinkedList = kODNULL;
fHeap = kODNULL;
}
//------------------------------------------------------------------------------
// VersionList::~VersionList
//------------------------------------------------------------------------------
VersionList::~VersionList()
{
this->Clear();
delete fLinkedList;
}
//------------------------------------------------------------------------------
// VersionList::Initialize
//------------------------------------------------------------------------------
void VersionList::Initialize()
{
fHeap = ODRecoverHeapID(this);
#ifdef _PLATFORM_MACINTOSH_
fLinkedList = new(GetHeap()) LinkedList;
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
fLinkedList = new LinkedList;
#endif
}
//------------------------------------------------------------------------------
// VersionList::Initialize
//------------------------------------------------------------------------------
void VersionList::Initialize(ODPtr buffer, ODULong size)
{
VersionRecord* versionList;
ODULong numVersionRecords;
ODULong i;
VersionLink* link = kODNULL;
Environment* ev = somGetGlobalEnvironment();
try
{
// Note that I am assuming that VersionRecord contains just ODULong's
// without any additional padding:
ConvertODULongArrayFromStd((ODULong*) buffer, size / sizeof(ODULong));
ASSERTMSG(size>0, kODErrIllegalNullInput,
"VersionList is empty.", 0);
fLatestVersionID = *((ODULong*) buffer);
versionList = (VersionRecord*) (((ODSByte*) buffer) + sizeof(ODULong));
numVersionRecords = (size - sizeof(ODULong)) / sizeof(VersionRecord);
#ifdef _PLATFORM_MACINTOSH_
fLinkedList = new(GetHeap()) LinkedList;
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
fLinkedList = new LinkedList;
#endif
ODVersionID prevVersionID = kODTombstonedVersion;
for (i = 0; i < numVersionRecords; i++) {
MyDebug3Str("Import %x: DraftID %d VersionID %d\n", this, versionList[i].draftID, versionList[i].versionID);
#if TestFlushContainer
if (versionList[i].versionID != prevVersionID) {
#endif
prevVersionID = versionList[i].versionID;
#ifdef _PLATFORM_MACINTOSH_
link = new(GetHeap()) VersionLink(versionList[i].draftID, prevVersionID);
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
link = new VersionLink(versionList[i].draftID, prevVersionID);
#endif
fLinkedList->AddLast(link);
#if TestFlushContainer
}
#endif
}
}
catch (ODException _exception)
{
ODDeleteObject(fLinkedList);
ODDeleteObject(link);
throw;
}
}
//------------------------------------------------------------------------------
// VersionList::ExportTo
//------------------------------------------------------------------------------
void VersionList::ExportTo(ODPtr* buffer, ODULong* size, ODBoolean ignoreTopDraft)
{
Environment* ev = somGetGlobalEnvironment();
try
{
LinkedListIterator iter(fLinkedList);
ODULong count = 0;
ODULong i = 0;
VersionRecord* versionList;
ODVersionID thisVersionID;
*buffer = kODNULL;
Link* link = iter.First();
while (link != kODNULL) {
thisVersionID = ((VersionLink*) link)->GetVersionID();
// Ignore tombstone
if (thisVersionID != kODTombstonedVersion)
count++;
link = iter.Next();
}
*size = sizeof(ODULong) + count * sizeof(VersionRecord);
*buffer = ODNewPtr(*size, GetHeap());
if (ignoreTopDraft != kODFalse)
*size -= sizeof(VersionRecord);
*((ODULong*) *buffer) = ConvertODULongToStd(fLatestVersionID);
versionList = (VersionRecord*) (((ODSByte*) *buffer) + sizeof(ODULong));
link = iter.First();
while (link != kODNULL) {
thisVersionID = ((VersionLink*) link)->GetVersionID();
// Ignore tombstone
if (thisVersionID != kODTombstonedVersion) {
versionList[i].draftID = ConvertODULongToStd(((VersionLink*) link)->GetDraftID());
versionList[i].versionID = ConvertODULongToStd(thisVersionID);
MyDebug3Str("Export %x: DraftID %d VersionID %d\n", this, versionList[i].draftID, versionList[i].versionID);
i++;
}
link = iter.Next();
}
}
catch (ODException _exception)
{
ODDisposePtr(*buffer);
throw;
}
}
//------------------------------------------------------------------------------
// VersionList::Reinitialize
//------------------------------------------------------------------------------
void VersionList::Reinitialize(ODPtr buffer, ODULong size)
{
this->Clear();
this->Initialize(buffer, size);
}
//------------------------------------------------------------------------------
// VersionList::CreateDraft
//------------------------------------------------------------------------------
ODDraftID VersionList::CreateDraft()
{
Environment* ev = somGetGlobalEnvironment();
VersionLink* link = kODNULL;
try
{
ODVersionID versionID;
VersionLink* prevLink = (VersionLink*) fLinkedList->Last();
if (prevLink == kODNULL) {
fHighestDraftID = 1;
versionID = 0;
}
else {
ODDraftID draftID = prevLink->GetDraftID();
if (draftID > fHighestDraftID)
fHighestDraftID = draftID;
fHighestDraftID++;
ODDraftID prevDraftID = this->GetLatestDraftID();
versionID = this->GetDraft(prevDraftID);
}
#ifdef _PLATFORM_MACINTOSH_
VersionLink* link = new(GetHeap()) VersionLink(fHighestDraftID, versionID);
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
VersionLink* link = new VersionLink(fHighestDraftID, versionID);
#endif
fLinkedList->AddLast(link);
}
catch (ODException _exception)
{
ODDeleteObject(link);
throw;
}
return fHighestDraftID;
}
//------------------------------------------------------------------------------
// VersionList::RemoveDraft
//------------------------------------------------------------------------------
void VersionList::RemoveDraft(ODDraftID draftID)
{
VersionLink* link = this->GetLink(draftID);
if (link == kODNULL)
BREAK_AND_THROW(kODErrDraftDoesNotExist);
else {
fLinkedList->Remove(*link);
delete link;
}
}
//------------------------------------------------------------------------------
// VersionList::GetDraft
//------------------------------------------------------------------------------
ODVersionID VersionList::GetDraft(ODDraftID draftID)
{
ODVersionID verID = kODTombstonedVersion;
VersionLink* link = this->GetLink(draftID);
if (link)
verID = link->GetVersionID();
return verID;
}
//------------------------------------------------------------------------------
// VersionList::CreateVersion
//------------------------------------------------------------------------------
ODVersionID VersionList::CreateVersion(ODDraftID draftID)
{
VersionLink* link;
ODDraftID latestDraftID = this->GetLatestDraftID();
if (latestDraftID != draftID)
BREAK_AND_THROW(kODErrIllegalNonTopmostDraft);
link = this->GetLink(draftID);
if (link == kODNULL)
BREAK_AND_THROW(kODErrDraftDoesNotExist);
fLatestVersionID++;
link->SetVersionID(fLatestVersionID);
return fLatestVersionID;
}
//------------------------------------------------------------------------------
// VersionList::GetCurrentVersion
//------------------------------------------------------------------------------
ODVersionID VersionList::GetCurrentVersion(ODDraftID draftID)
{
ODVersionID VerID = kODTombstonedVersion;
VersionLink* link = this->GetLink(draftID);
if (link == kODNULL)
BREAK_AND_THROW(kODErrDraftDoesNotExist);
VerID = link->GetVersionID();
return VerID;
}
//------------------------------------------------------------------------------
// VersionList::Exists
//------------------------------------------------------------------------------
ODBoolean VersionList::Exists(ODDraftID draftID)
{
ODBoolean exists = kODFalse;
VersionLink* link = this->GetLink(draftID);
if ((link == kODNULL) || (link->GetVersionID() == kODTombstonedVersion))
exists = kODFalse;
else
exists = kODTrue;
return exists;
}
//------------------------------------------------------------------------------
// VersionList::CollapseDrafts
//------------------------------------------------------------------------------
void VersionList::CollapseDrafts(ODDraftID fromID, ODDraftID toID)
{
VersionListIterator* iter = kODNULL;
try
{
ODVersionID fromVersionID;
VersionLink* versionLink;
ODVersionID prevVersionID;
// Check the Draft Topology
#ifdef _PLATFORM_MACINTOSH_
iter = new(GetHeap()) VersionListIterator(this);
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
iter = new VersionListIterator(this);
#endif
iter->Initialize();
versionLink = iter->Last();
while ((versionLink != kODNULL) && (versionLink->GetDraftID() != fromID)) {
versionLink = iter->Previous();
}
fromVersionID = this->GetDraft(fromID);
versionLink = iter->Previous();
while ((versionLink != kODNULL) && (versionLink->GetDraftID() >= toID)) {
prevVersionID = versionLink->GetVersionID();
if ((prevVersionID != kODTombstonedVersion) && (fromVersionID != prevVersionID))
BREAK_AND_THROW(kODErrNonEmptyDraft);
versionLink = iter->Previous();
}
// Do the actual updating
versionLink = iter->Last();
while ((versionLink != kODNULL) && (versionLink->GetDraftID() != fromID)) {
versionLink = iter->Previous();
}
while ((versionLink != kODNULL) && (versionLink->GetDraftID() > toID)) {
versionLink->SetVersionID(kODTombstonedVersion);
versionLink = iter->Previous();
}
delete iter;
}
catch (ODException _exception)
{
ODDeleteObject(iter);
throw;
}
}
//------------------------------------------------------------------------------
// VersionList::SaveToAPrevDraft
//------------------------------------------------------------------------------
void VersionList::SaveToAPrevDraft(ODDraftID fromID, ODDraftID toID)
{
VersionListIterator* iter = kODNULL;
try
{
ODVersionID fromVersionID;
VersionLink* versionLink;
fromVersionID = this->GetDraft(fromID);
// Find the from draft
#ifdef _PLATFORM_MACINTOSH_
iter = new(GetHeap()) VersionListIterator(this);
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
iter = new VersionListIterator(this);
#endif
iter->Initialize();
versionLink = iter->Last();
while ((versionLink != kODNULL) && (versionLink->GetDraftID() != fromID)) {
versionLink = iter->Previous();
}
// Do the actual update of the Version List
versionLink = iter->Previous();
while ((versionLink != kODNULL) && (versionLink->GetDraftID() >= toID)) {
if (versionLink->GetVersionID() != kODTombstonedVersion)
versionLink->SetVersionID(fromVersionID);
versionLink = iter->Previous();
}
delete iter;
}
catch (ODException _exception)
{
ODDeleteObject(iter);
throw;
}
}
//------------------------------------------------------------------------------
// VersionList::RemoveChanges
//------------------------------------------------------------------------------
ODVersionID VersionList::RemoveChanges(ODDraftID draftID)
{
ODVersionID prevVersionID;
ODDraftID prevDraftID;
VersionLink* link = kODNULL;
link = this->GetLink(draftID);
if (link == kODNULL)
BREAK_AND_THROW(kODErrDraftDoesNotExist);
if (draftID > 1) {
prevDraftID = this->GetPreviousDraftID(draftID);
prevVersionID = this->GetDraft(prevDraftID);
}
else {
#if TestFlushContainer
prevVersionID = link->GetVersionID() - 1;
if (prevVersionID == 0)
prevVersionID = 1;
else
fLatestVersionID--;
#else
prevVersionID = 0;
#endif
}
link->SetVersionID(prevVersionID);
return prevVersionID;
}
//------------------------------------------------------------------------------
// VersionList::ChangedFromPrev
//------------------------------------------------------------------------------
ODBoolean VersionList::ChangedFromPrev(ODDraftID draftID)
{
ODBoolean changedfromprev = kODFalse;
ODDraftID prevDraftID;
ODVersionID versionID;
ODVersionID prevVersionID;
ODDraftID baseDraftID = this->GetBaseDraftID();
if (draftID == baseDraftID)
changedfromprev = kODFalse;
else
{
versionID = this->GetDraft(draftID);
prevDraftID = this->GetPreviousDraftID(draftID);
prevVersionID = this->GetDraft(prevDraftID);
if (versionID == prevVersionID)
changedfromprev = kODFalse;
else
changedfromprev = kODTrue;
}
return changedfromprev;
}
//------------------------------------------------------------------------------
// VersionList::GetBaseDraftID
//------------------------------------------------------------------------------
ODDraftID VersionList::GetBaseDraftID()
{
ODDraftID retDraftID = 1;
VersionLink* link = (VersionLink*) fLinkedList->First();
if (link != kODNULL)
retDraftID = link->GetDraftID();
return retDraftID;
}
//------------------------------------------------------------------------------
// VersionList::GetLatestDraftID
//------------------------------------------------------------------------------
ODDraftID VersionList::GetLatestDraftID()
{
ODDraftID retDraftID = 0;
VersionLink* versionLink;
versionLink = (VersionLink*) fLinkedList->Last();
while ((versionLink != kODNULL) &&
(versionLink->GetVersionID() == kODTombstonedVersion)) {
versionLink = (VersionLink*) fLinkedList->Before(*versionLink);
}
if (versionLink == kODNULL)
retDraftID = this->GetBaseDraftID();
else
retDraftID = versionLink->GetDraftID();
return retDraftID;
}
//------------------------------------------------------------------------------
// VersionList::GetPreviousDraftID
//------------------------------------------------------------------------------
ODDraftID VersionList::GetPreviousDraftID(ODDraftID curDraftID)
{
VersionLink* curVersionLink;
ODDraftID baseDraftID = this->GetBaseDraftID();
VersionLink* versionLink;
if (baseDraftID == curDraftID)
BREAK_AND_THROW(kODErrNoPreviousDraft);
if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
versionLink = (VersionLink*) fLinkedList->Before(*curVersionLink);
while (versionLink != kODNULL) {
if (versionLink->GetVersionID() != kODTombstonedVersion)
return versionLink->GetDraftID();
versionLink = (VersionLink*) fLinkedList->Before(*versionLink);
}
}
BREAK_AND_THROW(kODErrDraftDoesNotExist);
return 0; // To avoid unnecessary warning from the compiler.
}
//------------------------------------------------------------------------------
// VersionList::GetSameVersionDraftID
//------------------------------------------------------------------------------
ODDraftID VersionList::GetSameVersionDraftID(ODDraftID curDraftID)
{
ODDraftID sameVersionDraftID = 0;
ODDraftID baseDraftID = this->GetBaseDraftID(), draftID;
ODVersionID latestVersion;
sameVersionDraftID = curDraftID;
latestVersion = this->GetCurrentVersion(sameVersionDraftID);
if (sameVersionDraftID != baseDraftID) {
draftID = this->GetPreviousDraftID(sameVersionDraftID);
while (draftID >= baseDraftID) {
if (latestVersion == this->GetCurrentVersion(draftID)) {
sameVersionDraftID = draftID;
if (draftID != baseDraftID)
draftID = this->GetPreviousDraftID(draftID);
else
draftID = 0;
}
else
draftID = 0;
};
}
return sameVersionDraftID;
}
//------------------------------------------------------------------------------
// VersionList::PreviousDraftExists
//------------------------------------------------------------------------------
ODBoolean VersionList::PreviousDraftExists(ODDraftID curDraftID)
{
ODBoolean prevDraftexists = kODFalse;
VersionLink* curVersionLink;
ODDraftID baseDraftID = this->GetBaseDraftID();
VersionLink* versionLink;
if (baseDraftID == curDraftID)
prevDraftexists = kODFalse;
else{
if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
versionLink = (VersionLink*) fLinkedList->Before(*curVersionLink);
while (versionLink != kODNULL) {
if (versionLink->GetVersionID() != kODTombstonedVersion)
return kODTrue;
versionLink = (VersionLink*) fLinkedList->Before(*versionLink);
}
}
}
return prevDraftexists;
}
//------------------------------------------------------------------------------
// VersionList::GetNextDraftID
//------------------------------------------------------------------------------
ODDraftID VersionList::GetNextDraftID(ODDraftID curDraftID)
{
VersionLink* curVersionLink;
VersionLink* versionLink;
if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
versionLink = (VersionLink*) fLinkedList->After(*curVersionLink);
while (versionLink != kODNULL) {
if (versionLink->GetVersionID() != kODTombstonedVersion)
return versionLink->GetDraftID();
versionLink = (VersionLink*) fLinkedList->After(*versionLink);
}
}
BREAK_AND_THROW(kODErrDraftDoesNotExist);
return 0; // To avoid unnecessary warning from the compiler.
}
//------------------------------------------------------------------------------
// VersionList::NextDraftExists
//------------------------------------------------------------------------------
ODBoolean VersionList::NextDraftExists(ODDraftID curDraftID)
{
VersionLink* curVersionLink;
VersionLink* versionLink;
if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
versionLink = (VersionLink*) fLinkedList->After(*curVersionLink);
while (versionLink != kODNULL) {
if (versionLink->GetVersionID() != kODTombstonedVersion)
return kODTrue;
versionLink = (VersionLink*) fLinkedList->After(*versionLink);
}
}
return kODFalse;;
}
//------------------------------------------------------------------------------
// VersionList::IsAbove
//------------------------------------------------------------------------------
ODBoolean VersionList::IsAbove(ODDraftID draftID1, ODDraftID draftID2)
{
return (draftID1 > draftID2);
}
//------------------------------------------------------------------------------
// VersionList::IsBelow
//------------------------------------------------------------------------------
ODBoolean VersionList::IsBelow(ODDraftID draftID1, ODDraftID draftID2)
{
return (draftID1 < draftID2);
}
//------------------------------------------------------------------------------
// VersionList::GetLink
//------------------------------------------------------------------------------
VersionLink* VersionList::GetLink(ODDraftID draftID)
{
VersionLink* link = kODNULL;
LinkedListIterator iter(fLinkedList);
link = (VersionLink*) iter.Last();
while ((link != kODNULL) && (link->GetDraftID() != draftID)) {
link = (VersionLink*) iter.Previous();
}
return link;
}
//------------------------------------------------------------------------------
// VersionList::Clear
//------------------------------------------------------------------------------
void VersionList::Clear()
{
Link* link;
link = fLinkedList->RemoveFirst();
while (link != kODNULL) {
delete link;
link = fLinkedList->RemoveFirst();
}
}
//------------------------------------------------------------------------------
// VersionList::GetHeap
//------------------------------------------------------------------------------
ODMemoryHeapID VersionList::GetHeap()
{
return fHeap;
}
//------------------------------------------------------------------------------
// VersionList::GetLinkedList
//------------------------------------------------------------------------------
LinkedList* VersionList::GetLinkedList()
{
return fLinkedList;
}
//------------------------------------------------------------------------------
// VersionList::Print
//------------------------------------------------------------------------------
void VersionList::Print(char* string)
{
#if ODDebug
VersionListIterator* versionList = new VersionListIterator(this);
versionList->Initialize();
for (VersionLink* link = versionList->Last(); versionList->IsNotComplete(); link = versionList->Previous()) {
somPrintf("%s: draftID %d versionID %d\n", string, link->GetDraftID(), link->GetVersionID());
}
delete versionList;
#endif
}
//==============================================================================
// VersionListIterator
//==============================================================================
//------------------------------------------------------------------------------
// VersionListIterator::VersionListIterator
//------------------------------------------------------------------------------
VersionListIterator::VersionListIterator(VersionList* versionList)
{
fVersionList = versionList;
fIterator = kODNULL;
}
//------------------------------------------------------------------------------
// VersionListIterator::~VersionListIterator
//------------------------------------------------------------------------------
VersionListIterator::~VersionListIterator()
{
delete fIterator;
}
//------------------------------------------------------------------------------
// VersionListIterator::Initialize
//------------------------------------------------------------------------------
void VersionListIterator::Initialize()
{
#ifdef _PLATFORM_MACINTOSH_
fIterator = new(fVersionList->GetHeap()) LinkedListIterator(fVersionList->GetLinkedList());
#endif
#if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
// The use of heap is not implemented in Windows platform
fIterator = new LinkedListIterator(fVersionList->GetLinkedList());
#endif
}
//------------------------------------------------------------------------------
// VersionListIterator::Last
//------------------------------------------------------------------------------
VersionLink* VersionListIterator::Last()
{
return((VersionLink*) fIterator->Last());
}
//------------------------------------------------------------------------------
// VersionListIterator::Previous
//------------------------------------------------------------------------------
VersionLink* VersionListIterator::Previous()
{
return((VersionLink*) fIterator->Previous());
}
//------------------------------------------------------------------------------
// VersionListIterator::IsNotComplete
//------------------------------------------------------------------------------
ODBoolean VersionListIterator::IsNotComplete()
{
return(fIterator->IsNotComplete());
}