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 >
C/C++ Source or Header  |  1997-03-21  |  36KB  |  1,196 lines

  1. /* @(#)Z 1.9 com/src/bento/DocPriv.cpp, odstorage, od96os2, odos29712d 97/03/21 17:19:17 (96/10/29 09:11:49) */
  2. //====START_GENERATED_PROLOG======================================
  3. //
  4. //
  5. //   COMPONENT_NAME: odstorage
  6. //
  7. //   CLASSES: none
  8. //
  9. //   ORIGINS: 82,27
  10. //
  11. //
  12. //   (C) COPYRIGHT International Business Machines Corp. 1995,1996
  13. //   All Rights Reserved
  14. //   Licensed Materials - Property of IBM
  15. //   US Government Users Restricted Rights - Use, duplication or
  16. //   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  17. //       
  18. //   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  19. //   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  20. //   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  21. //   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  22. //   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  23. //   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
  24. //   OR PERFORMANCE OF THIS SOFTWARE.
  25. //
  26. //====END_GENERATED_PROLOG========================================
  27. //
  28.  
  29. /*
  30.     File:        DocPriv.cpp
  31.  
  32.     Contains:    Implementation for Private class for CMDocument.
  33.  
  34.     Owned by:    Vincent Lo
  35.  
  36.     Copyright:    ⌐ 1993-1995 by Apple Computer, Inc., all rights reserved.
  37.  
  38.     Change History (most recent first):
  39.  
  40.         <21>     8/21/95    VL        1278330, 1278315: Error code cleanup.
  41.         <20>     5/26/95    VL        1251403: Multithreading naming support.
  42.         <19>     5/25/95    jpa        List.h --> LinkList.h [1253324] Fixed
  43.                                     misuse of ODDebug [1253321]
  44.         <18>     4/14/95    EL        1239463: Remove Change should not reduce
  45.                                     version id to 0.
  46.         <17>     3/31/95    EL        1234685: ExportTo has extra parameter so we
  47.                                     can skip top draft. Dirty flag no longer
  48.                                     needed because version list only
  49.                                     externalized on close or flush.
  50.         <16>     3/29/95    DM        make standard format little endian
  51.         <15>     3/24/95    EL        1209355: dirty flag for version list. Temp
  52.                                     fix: remove duplicate drafts when version
  53.                                     list is read.
  54.         <14>     3/23/95    VL        1228003: Added Print.
  55.         <13>      3/9/95    VL        1226089: Introduced fHighestDraftID to
  56.                                     prevent DraftID from being reused in a
  57.                                     session.
  58.         <12>     2/15/95    EL        1182275: Add GetSameVersionDraftID to get
  59.                                     the lowest draft that has the same version
  60.                                     as the latest draft.
  61.         <11>     1/31/95    EL        1213321: Do not output tomstoned versions
  62.                                     during externalization.
  63.         <10>     1/11/95    VL        1185688: Made storage more robust in terms
  64.                                     of error handling. Also did some code
  65.                                     review cleanup.
  66.          <9>    11/14/94    VL        1188257: Use Bento errors in BenotDef.h.
  67.          <8>      9/5/94    VL        1184871: Remove dependency on default heap
  68.                                     by calling ODRecoverHeapID>
  69.          <7>     8/26/94    VL        1183174: Use updated GetSTorageUnitRef
  70.                                     which takes ID.
  71.          <6>     7/11/94    VL        Added Exists calls.
  72.          <5>      7/7/94    VL        Commented out use of ODRecoverHeapID.
  73.          <4>     6/28/94    VL        ODRecoverHeap to ODRecoverHeapID.
  74.          <3>     6/20/94    CC        ODMemoryHeap* changed to ODMemoryHeapID.
  75.          <2>     6/15/94    RR        ODHeap -> ODMemoryHeap
  76.          <1>     5/27/94    VL        first checked in
  77.  
  78.     To Do:
  79.         1) Get rid of tombstoned versions.
  80.     In Progress:
  81. */
  82.  
  83. #ifndef _DOCPRIV_
  84. #include "DocPriv.h"
  85. #endif
  86.  
  87. #ifndef _FLIPEND_
  88. #include "FlipEnd.h"
  89. #endif
  90.  
  91. #ifndef SOM_CMDocument_xh
  92. #include "CMDoc.xh"
  93. #endif
  94.  
  95. #ifndef _LINKLIST_
  96. #include "LinkList.h"
  97. #endif
  98.  
  99. #ifndef _EXCEPT_
  100. #include "Except.h"
  101. #endif
  102.  
  103. #ifndef _ODDEBUG_
  104. #include "ODDebug.h"
  105. #endif
  106.  
  107. #ifndef _ODMEMORY_
  108. #include "ODMemory.h"
  109. #endif
  110.  
  111. #ifndef _ODNEW_
  112. #include "ODNew.h"
  113. #endif
  114.  
  115. #ifndef SOM_CMDraft_xh
  116. #include "CMDraft.xh"
  117. #endif
  118.  
  119. #ifndef _BENTODEF_
  120. #include "BentoDef.h"
  121. #endif
  122.  
  123. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  124. #ifndef _ODUTILS_
  125. #include "ODUtils.h"
  126. #endif
  127. #endif
  128.  
  129.  
  130. #ifndef som_xh
  131. #include "som.xh"
  132. #endif
  133.  
  134. #pragma segment Document
  135.  
  136. //==============================================================================
  137. // Scalar Types
  138. //==============================================================================
  139.  
  140. #if ODDebug
  141. // #define DebugStorage 1
  142. #endif
  143.  
  144. #ifdef DebugStorage
  145. #define MyDebug3Str(f,p1,p2,p3) somPrintf(f, p1, p2, p3)
  146. #else
  147. #define MyDebug3Str(f,p1,p2,p3)
  148. #endif
  149.  
  150. typedef struct {
  151.     ODDraftID        draftID;
  152.     ODVersionID    versionID;
  153. } VersionRecord;
  154.  
  155. #ifdef STORAGE_TEST
  156. inline void BREAK_AND_THROW(ODError e)
  157. {
  158.     Debugger();
  159.     THROW(e);
  160. }
  161. #else
  162.  
  163. #define BREAK_AND_THROW(e)    THROW(e)
  164.  
  165. #endif
  166.  
  167.  
  168. //==============================================================================
  169. // DraftList
  170. //==============================================================================
  171.  
  172. //------------------------------------------------------------------------------
  173. // DraftList::DraftList
  174. //------------------------------------------------------------------------------
  175.  
  176. DraftList::DraftList()
  177. {
  178.     fHeap = kODNULL;
  179. }
  180.  
  181. //------------------------------------------------------------------------------
  182. // DraftList::~DraftList
  183. //------------------------------------------------------------------------------
  184.  
  185. DraftList::~DraftList()
  186. {
  187.     Link*    link;
  188.     
  189.     link = fLinkedList->RemoveFirst();
  190.     while (link != kODNULL) {
  191.         delete link;
  192.         link = fLinkedList->RemoveFirst();
  193.     }
  194.     delete fLinkedList;
  195. }
  196.  
  197. //------------------------------------------------------------------------------
  198. // DraftList::Initialize
  199. //------------------------------------------------------------------------------
  200.  
  201. void DraftList::Initialize()
  202. {
  203.     fHeap = ODRecoverHeapID(this);
  204.     
  205. #ifdef _PLATFORM_MACINTOSH_
  206.     fLinkedList = new(GetHeap()) LinkedList;
  207. #endif
  208. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  209. //    The use of heap is not implemented in Windows platform
  210.     fLinkedList = new LinkedList;
  211. #endif
  212. }
  213.  
  214.  
  215. //------------------------------------------------------------------------------
  216. // DraftList::Get
  217. //------------------------------------------------------------------------------
  218.  
  219. CMDraft* DraftList::Get(ODDraftID draftID)
  220. {    
  221.   
  222.    CMDraft* retDraft = kODNULL;
  223.    DraftLink* link = this->GetLink(draftID);
  224.     
  225.    if (link != kODNULL)
  226.       retDraft =  link->GetDraft();
  227.  
  228.    return retDraft;
  229. }
  230.  
  231. //------------------------------------------------------------------------------
  232. // DraftList::Add
  233. //------------------------------------------------------------------------------
  234.  
  235. void DraftList::Add(ODDraftID draftID, CMDraft* draft)
  236. {    
  237.         Environment* ev = somGetGlobalEnvironment();
  238.     CMDraft* existingDraft = kODNULL;
  239.     DraftLink* link  = kODNULL;
  240.     
  241.   try
  242.   {
  243.     if ((existingDraft = this->Get(draftID)) == kODNULL) {
  244. #ifdef _PLATFORM_MACINTOSH_
  245.         link = new(GetHeap()) DraftLink(draftID, draft);
  246. #endif
  247. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  248. //        The use of heap is not implemented in Windows platform
  249.         link = new DraftLink(draftID, draft);
  250. #endif
  251.         fLinkedList->AddLast(link);
  252.     }
  253.     else {
  254.         if (draftID != existingDraft->GetID(ev))
  255.             BREAK_AND_THROW(kODErrDraftExistsWithDifferentID);
  256.     }
  257.   }
  258.   catch (ODException _exception)
  259.   {
  260.       ODDeleteObject(link);
  261.       throw;
  262.   }
  263. }
  264.         
  265. //------------------------------------------------------------------------------
  266. // DraftList::Remove
  267. //------------------------------------------------------------------------------
  268.  
  269. void DraftList::Remove(ODDraftID draftID)
  270. {
  271.  
  272.     DraftLink* link = this->GetLink(draftID);
  273.     
  274.     if (link == kODNULL)
  275.         BREAK_AND_THROW(kODErrDraftDoesNotExist);
  276.     else {
  277.         fLinkedList->Remove(*link);
  278.         delete link;
  279.     }
  280.  
  281. }
  282.  
  283. //------------------------------------------------------------------------------
  284. // DraftList::Count
  285. //------------------------------------------------------------------------------
  286.  
  287. ODULong DraftList::Count()
  288. {
  289.     return fLinkedList->Count();
  290. }
  291.  
  292. //------------------------------------------------------------------------------
  293. // DraftList::GetLink
  294. //------------------------------------------------------------------------------
  295.  
  296. DraftLink* DraftList::GetLink(ODDraftID draftID)
  297. {
  298.     LinkedListIterator    iter(fLinkedList);
  299.     
  300.     DraftLink *link = (DraftLink*) iter.Last();
  301.     while ((link != kODNULL) && (link->GetDraftID() != draftID)) {
  302.         link = (DraftLink*) iter.Previous();
  303.     }
  304.     return link;
  305. }
  306.  
  307. //------------------------------------------------------------------------------
  308. // DraftList::GetHeap
  309. //------------------------------------------------------------------------------
  310.  
  311. ODMemoryHeapID DraftList::GetHeap()
  312. {
  313.     return fHeap;
  314. }
  315.  
  316. //------------------------------------------------------------------------------
  317. // DraftList::GetLinkedList
  318. //------------------------------------------------------------------------------
  319.  
  320. LinkedList* DraftList::GetLinkedList()
  321. {
  322.     return fLinkedList;
  323. }
  324.  
  325. //==============================================================================
  326. // DraftListIterator
  327. //==============================================================================
  328.  
  329. //------------------------------------------------------------------------------
  330. // DraftListIterator::DraftListIterator
  331. //------------------------------------------------------------------------------
  332.  
  333. DraftListIterator::DraftListIterator(DraftList* draftList)
  334. {
  335.     fDraftList = draftList;
  336. }
  337.     
  338. //------------------------------------------------------------------------------
  339. // DraftListIterator::~DraftListIterator
  340. //------------------------------------------------------------------------------
  341.  
  342. DraftListIterator::~DraftListIterator()
  343. {
  344.     delete fIterator;
  345. }
  346.  
  347. //------------------------------------------------------------------------------
  348. // DraftListIterator::Initialize
  349. //------------------------------------------------------------------------------
  350.  
  351. void DraftListIterator::Initialize()
  352. {
  353. #ifdef _PLATFORM_MACINTOSH_
  354.     fIterator = new(fDraftList->GetHeap()) LinkedListIterator(fDraftList->GetLinkedList());
  355. #endif
  356. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  357. //    The use of heap is not implemented in Windows platform
  358.     fIterator = new LinkedListIterator(fDraftList->GetLinkedList());
  359. #endif
  360. }
  361.     
  362.  
  363. //------------------------------------------------------------------------------
  364. // DraftListIterator::Last
  365. //------------------------------------------------------------------------------
  366.  
  367. CMDraft* DraftListIterator::Last()
  368. {
  369.    CMDraft* retDraft = kODNULL;
  370.    DraftLink* link  = (DraftLink*) fIterator->Last();
  371.    if (link != kODNULL)
  372.       retDraft =  link->GetDraft();
  373.    return retDraft;
  374. }
  375.  
  376. //------------------------------------------------------------------------------
  377. // DraftListIterator::Previous
  378. //------------------------------------------------------------------------------
  379.  
  380. CMDraft* DraftListIterator::Previous()
  381. {
  382.    CMDraft* retDraft = kODNULL;
  383.    DraftLink* link = (DraftLink*) fIterator->Previous();
  384.    if (link != kODNULL)
  385.       retDraft =  link->GetDraft();
  386.    return retDraft;
  387. }
  388.         
  389. //------------------------------------------------------------------------------
  390. // DraftListIterator::IsNotComplete
  391. //------------------------------------------------------------------------------
  392.  
  393. ODBoolean DraftListIterator::IsNotComplete()
  394. {
  395.    return (fIterator->IsNotComplete());
  396.    
  397. }
  398.  
  399. //==============================================================================
  400. // VersionLink
  401. //==============================================================================
  402.  
  403. //------------------------------------------------------------------------------
  404. // VersionLink::VersionLink
  405. //------------------------------------------------------------------------------
  406.  
  407. VersionLink::VersionLink(ODDraftID draftID, ODVersionID versionID)
  408.     : Link()
  409. {
  410.     fDraftID = draftID;
  411.     fVersionID = versionID;
  412. }
  413.  
  414. //==============================================================================
  415. // VersionList
  416. //==============================================================================
  417.  
  418. //------------------------------------------------------------------------------
  419. // VersionList::VersionList
  420. //------------------------------------------------------------------------------
  421.  
  422. VersionList::VersionList()
  423. {
  424.     fHighestDraftID = 0;
  425.     fLatestVersionID = 0;
  426.     fLinkedList = kODNULL;
  427.     fHeap = kODNULL;
  428. }
  429.  
  430. //------------------------------------------------------------------------------
  431. // VersionList::~VersionList
  432. //------------------------------------------------------------------------------
  433.  
  434. VersionList::~VersionList()
  435. {
  436.     this->Clear();
  437.     delete fLinkedList;
  438. }
  439.  
  440. //------------------------------------------------------------------------------
  441. // VersionList::Initialize
  442. //------------------------------------------------------------------------------
  443.  
  444. void VersionList::Initialize()
  445. {
  446.     fHeap = ODRecoverHeapID(this);
  447.  
  448. #ifdef _PLATFORM_MACINTOSH_
  449.     fLinkedList = new(GetHeap()) LinkedList;
  450. #endif
  451. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  452. //    The use of heap is not implemented in Windows platform
  453.     fLinkedList = new LinkedList;
  454. #endif
  455. }
  456.  
  457. //------------------------------------------------------------------------------
  458. // VersionList::Initialize
  459. //------------------------------------------------------------------------------
  460.  
  461. void VersionList::Initialize(ODPtr buffer, ODULong size)
  462. {
  463.     VersionRecord*    versionList;
  464.     ODULong        numVersionRecords;
  465.     ODULong        i;
  466.     VersionLink*    link  = kODNULL;
  467.  
  468.       Environment* ev = somGetGlobalEnvironment();
  469.   try
  470.   {
  471.     // Note that I am assuming that VersionRecord contains just ODULong's
  472.     // without any additional padding:
  473.     ConvertODULongArrayFromStd((ODULong*) buffer, size / sizeof(ODULong));
  474.     
  475.     ASSERTMSG(size>0, kODErrIllegalNullInput, 
  476.         "VersionList is empty.", 0);
  477.     
  478.     fLatestVersionID = *((ODULong*) buffer);
  479.     
  480.     versionList = (VersionRecord*) (((ODSByte*) buffer) + sizeof(ODULong));
  481.     numVersionRecords = (size - sizeof(ODULong)) / sizeof(VersionRecord);
  482.     
  483. #ifdef _PLATFORM_MACINTOSH_
  484.     fLinkedList = new(GetHeap()) LinkedList;
  485. #endif
  486. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  487. //    The use of heap is not implemented in Windows platform
  488.     fLinkedList = new LinkedList;
  489. #endif
  490.     
  491.     ODVersionID        prevVersionID = kODTombstonedVersion;
  492.     
  493.     for (i = 0; i < numVersionRecords; i++) {
  494.         MyDebug3Str("Import %x: DraftID %d VersionID %d\n", this, versionList[i].draftID, versionList[i].versionID);
  495. #if TestFlushContainer
  496.         if (versionList[i].versionID != prevVersionID) {
  497. #endif
  498.         prevVersionID = versionList[i].versionID;
  499. #ifdef _PLATFORM_MACINTOSH_
  500.         link = new(GetHeap()) VersionLink(versionList[i].draftID, prevVersionID);
  501. #endif
  502. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  503. //        The use of heap is not implemented in Windows platform
  504.         link = new VersionLink(versionList[i].draftID, prevVersionID);
  505. #endif
  506.         fLinkedList->AddLast(link);
  507. #if TestFlushContainer
  508.         }
  509. #endif
  510.     }
  511.   }
  512.   catch (ODException _exception)
  513.   {
  514.        ODDeleteObject(fLinkedList);
  515.        ODDeleteObject(link);
  516.        throw;
  517.   }
  518. }
  519.  
  520. //------------------------------------------------------------------------------
  521. // VersionList::ExportTo
  522. //------------------------------------------------------------------------------
  523.  
  524. void VersionList::ExportTo(ODPtr* buffer, ODULong* size, ODBoolean ignoreTopDraft)
  525. {
  526.       Environment* ev = somGetGlobalEnvironment();
  527.   try
  528.   {
  529.     LinkedListIterator    iter(fLinkedList);
  530.     ODULong            count = 0;
  531.     ODULong            i = 0;
  532.     VersionRecord*        versionList;
  533.     ODVersionID        thisVersionID;
  534.     
  535.         *buffer = kODNULL;
  536.  
  537.     Link*    link = iter.First();
  538.     while (link != kODNULL) {
  539.         thisVersionID = ((VersionLink*) link)->GetVersionID();
  540.         // Ignore tombstone
  541.         if (thisVersionID != kODTombstonedVersion)
  542.             count++;
  543.         link = iter.Next();
  544.     }
  545.     
  546.     *size = sizeof(ODULong) + count * sizeof(VersionRecord);
  547.     *buffer = ODNewPtr(*size, GetHeap());
  548.  
  549.     if (ignoreTopDraft != kODFalse)
  550.         *size -= sizeof(VersionRecord);
  551.  
  552.     *((ODULong*) *buffer) = ConvertODULongToStd(fLatestVersionID);
  553.     
  554.     versionList = (VersionRecord*) (((ODSByte*) *buffer) + sizeof(ODULong));
  555.     
  556.     link = iter.First();
  557.     while (link != kODNULL) {
  558.         thisVersionID = ((VersionLink*) link)->GetVersionID();
  559.         // Ignore tombstone
  560.         if (thisVersionID != kODTombstonedVersion) {
  561.             versionList[i].draftID = ConvertODULongToStd(((VersionLink*) link)->GetDraftID());
  562.             versionList[i].versionID = ConvertODULongToStd(thisVersionID);
  563.             MyDebug3Str("Export %x: DraftID %d VersionID %d\n", this, versionList[i].draftID, versionList[i].versionID);
  564.             i++;
  565.         }
  566.         link = iter.Next();
  567.     }
  568.    }
  569.    catch (ODException _exception)
  570.    {
  571.         ODDisposePtr(*buffer);
  572.         throw;
  573.    }
  574. }
  575.  
  576. //------------------------------------------------------------------------------
  577. // VersionList::Reinitialize
  578. //------------------------------------------------------------------------------
  579.  
  580. void VersionList::Reinitialize(ODPtr buffer, ODULong size)
  581. {
  582.     this->Clear();
  583.     this->Initialize(buffer, size);
  584. }
  585.  
  586. //------------------------------------------------------------------------------
  587. // VersionList::CreateDraft
  588. //------------------------------------------------------------------------------
  589.  
  590. ODDraftID VersionList::CreateDraft()
  591. {
  592.       Environment* ev = somGetGlobalEnvironment();
  593.       VersionLink* link = kODNULL;
  594.   try
  595.   {
  596.  
  597.     ODVersionID    versionID;
  598.     
  599.     VersionLink* prevLink = (VersionLink*) fLinkedList->Last();
  600.     if (prevLink == kODNULL) {
  601.         fHighestDraftID = 1;
  602.         versionID = 0;
  603.     }
  604.     else {
  605.         ODDraftID draftID = prevLink->GetDraftID();
  606.         if (draftID > fHighestDraftID)
  607.             fHighestDraftID = draftID;
  608.         fHighestDraftID++;
  609.         ODDraftID prevDraftID = this->GetLatestDraftID();
  610.         versionID = this->GetDraft(prevDraftID);
  611.     }
  612.     
  613. #ifdef _PLATFORM_MACINTOSH_
  614.     VersionLink* link = new(GetHeap()) VersionLink(fHighestDraftID, versionID);
  615. #endif
  616. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  617. //    The use of heap is not implemented in Windows platform
  618.     VersionLink* link = new VersionLink(fHighestDraftID, versionID);
  619. #endif
  620.     fLinkedList->AddLast(link);
  621.    }
  622.    catch (ODException _exception)
  623.    {
  624.         ODDeleteObject(link);
  625.         throw;
  626.    }
  627.         
  628.     return fHighestDraftID;
  629. }
  630.  
  631. //------------------------------------------------------------------------------
  632. // VersionList::RemoveDraft
  633. //------------------------------------------------------------------------------
  634.  
  635. void VersionList::RemoveDraft(ODDraftID draftID)
  636. {
  637.     VersionLink* link = this->GetLink(draftID);
  638.     
  639.     if (link == kODNULL)
  640.         BREAK_AND_THROW(kODErrDraftDoesNotExist);
  641.     else {
  642.         fLinkedList->Remove(*link);
  643.         delete link;
  644.     }
  645. }
  646.  
  647. //------------------------------------------------------------------------------
  648. // VersionList::GetDraft
  649. //------------------------------------------------------------------------------
  650.  
  651. ODVersionID VersionList::GetDraft(ODDraftID draftID)
  652. {
  653.     ODVersionID verID = kODTombstonedVersion;
  654.  
  655.         VersionLink*  link   = this->GetLink(draftID);
  656.     
  657.         if (link)
  658.             verID = link->GetVersionID();
  659.  
  660.         return verID;
  661. }
  662.  
  663. //------------------------------------------------------------------------------
  664. // VersionList::CreateVersion
  665. //------------------------------------------------------------------------------
  666.  
  667. ODVersionID VersionList::CreateVersion(ODDraftID draftID)
  668. {
  669.     VersionLink*    link;
  670.     ODDraftID        latestDraftID = this->GetLatestDraftID();
  671.     
  672.     if (latestDraftID != draftID)
  673.         BREAK_AND_THROW(kODErrIllegalNonTopmostDraft);
  674.     
  675.     link = this->GetLink(draftID);
  676.     if (link == kODNULL)
  677.         BREAK_AND_THROW(kODErrDraftDoesNotExist);
  678.  
  679.     fLatestVersionID++;
  680.     
  681.     link->SetVersionID(fLatestVersionID);
  682.     
  683.     return fLatestVersionID;
  684. }
  685.  
  686. //------------------------------------------------------------------------------
  687. // VersionList::GetCurrentVersion
  688. //------------------------------------------------------------------------------
  689.  
  690. ODVersionID VersionList::GetCurrentVersion(ODDraftID draftID)
  691. {
  692.         ODVersionID VerID = kODTombstonedVersion;
  693.     VersionLink*    link = this->GetLink(draftID);
  694.     
  695.     if (link == kODNULL)
  696.         BREAK_AND_THROW(kODErrDraftDoesNotExist);
  697.             
  698.     VerID =  link->GetVersionID();
  699.         return VerID;
  700. }
  701.  
  702. //------------------------------------------------------------------------------
  703. // VersionList::Exists
  704. //------------------------------------------------------------------------------
  705.  
  706. ODBoolean VersionList::Exists(ODDraftID draftID)
  707. {
  708.         ODBoolean exists = kODFalse; 
  709.     VersionLink*    link = this->GetLink(draftID);
  710.     
  711.     if ((link == kODNULL) || (link->GetVersionID() == kODTombstonedVersion))
  712.         exists =  kODFalse;
  713.     else
  714.         exists =  kODTrue;
  715.         return exists;
  716. }
  717.  
  718.  
  719. //------------------------------------------------------------------------------
  720. // VersionList::CollapseDrafts
  721. //------------------------------------------------------------------------------
  722.  
  723. void VersionList::CollapseDrafts(ODDraftID fromID, ODDraftID toID)
  724. {
  725.       VersionListIterator*    iter  = kODNULL;
  726.   try
  727.   {
  728.     ODVersionID    fromVersionID;
  729.     VersionLink*    versionLink;
  730.     ODVersionID    prevVersionID;
  731.  
  732.     // Check the Draft Topology
  733.     
  734. #ifdef _PLATFORM_MACINTOSH_
  735.                          iter   = new(GetHeap()) VersionListIterator(this);
  736. #endif
  737. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  738. //    The use of heap is not implemented in Windows platform
  739.                     iter = new VersionListIterator(this);
  740. #endif
  741.     iter->Initialize();
  742.     
  743.     versionLink = iter->Last();
  744.     while ((versionLink != kODNULL) && (versionLink->GetDraftID() != fromID)) {
  745.         versionLink = iter->Previous();
  746.     }
  747.     fromVersionID = this->GetDraft(fromID);
  748.     versionLink = iter->Previous();
  749.     while ((versionLink != kODNULL) && (versionLink->GetDraftID() >= toID)) {
  750.         prevVersionID = versionLink->GetVersionID();
  751.         if ((prevVersionID != kODTombstonedVersion) && (fromVersionID != prevVersionID))
  752.             BREAK_AND_THROW(kODErrNonEmptyDraft);
  753.         versionLink = iter->Previous();
  754.     }
  755.  
  756.     // Do the actual updating
  757.     
  758.     versionLink = iter->Last();
  759.     while ((versionLink != kODNULL) && (versionLink->GetDraftID() != fromID)) {
  760.         versionLink = iter->Previous();
  761.     }    
  762.     while ((versionLink != kODNULL) && (versionLink->GetDraftID() > toID)) {
  763.         versionLink->SetVersionID(kODTombstonedVersion);
  764.         versionLink = iter->Previous();
  765.     }
  766.     delete iter;
  767.    }
  768.    catch (ODException _exception)
  769.    {
  770.        ODDeleteObject(iter);
  771.        throw;
  772.    }
  773. }
  774.  
  775. //------------------------------------------------------------------------------
  776. // VersionList::SaveToAPrevDraft
  777. //------------------------------------------------------------------------------
  778.  
  779. void VersionList::SaveToAPrevDraft(ODDraftID fromID, ODDraftID toID)
  780. {
  781.       VersionListIterator*    iter = kODNULL;
  782.   try
  783.   {
  784.     ODVersionID    fromVersionID;
  785.     VersionLink*    versionLink;
  786.     
  787.     fromVersionID = this->GetDraft(fromID);
  788.     
  789.     // Find the from draft
  790.     
  791. #ifdef _PLATFORM_MACINTOSH_
  792.                        iter    = new(GetHeap()) VersionListIterator(this);
  793. #endif
  794. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  795. //    The use of heap is not implemented in Windows platform
  796.                 iter = new VersionListIterator(this);
  797. #endif
  798.     iter->Initialize();
  799.     versionLink = iter->Last();
  800.     while ((versionLink != kODNULL) && (versionLink->GetDraftID() != fromID)) {
  801.         versionLink = iter->Previous();
  802.     }
  803.     
  804.     // Do the actual update of the Version List
  805.     
  806.     versionLink = iter->Previous();
  807.     while ((versionLink != kODNULL) && (versionLink->GetDraftID() >= toID)) {
  808.         if (versionLink->GetVersionID() != kODTombstonedVersion)
  809.             versionLink->SetVersionID(fromVersionID);
  810.         versionLink = iter->Previous();
  811.     }
  812.     
  813.     delete iter;
  814.    }
  815.    catch (ODException _exception)
  816.    {
  817.        ODDeleteObject(iter);
  818.        throw;
  819.    }
  820. }
  821.  
  822. //------------------------------------------------------------------------------
  823. // VersionList::RemoveChanges
  824. //------------------------------------------------------------------------------
  825.  
  826. ODVersionID VersionList::RemoveChanges(ODDraftID draftID)
  827. {
  828.         ODVersionID    prevVersionID;
  829.     ODDraftID    prevDraftID;
  830.     VersionLink*    link = kODNULL;
  831.         
  832.     link = this->GetLink(draftID);
  833.     if (link == kODNULL)
  834.         BREAK_AND_THROW(kODErrDraftDoesNotExist);
  835.  
  836.     if (draftID > 1) {
  837.         prevDraftID = this->GetPreviousDraftID(draftID);
  838.         prevVersionID = this->GetDraft(prevDraftID);
  839.     }
  840.     else {
  841. #if TestFlushContainer
  842.         prevVersionID = link->GetVersionID() - 1;
  843.         if (prevVersionID == 0)
  844.             prevVersionID = 1;
  845.         else
  846.             fLatestVersionID--;
  847. #else
  848.         prevVersionID = 0;
  849. #endif
  850.     }
  851.     
  852.     link->SetVersionID(prevVersionID);
  853.  
  854.     return prevVersionID;
  855. }
  856.  
  857. //------------------------------------------------------------------------------
  858. // VersionList::ChangedFromPrev
  859. //------------------------------------------------------------------------------
  860.  
  861. ODBoolean VersionList::ChangedFromPrev(ODDraftID draftID)
  862. {
  863.         ODBoolean changedfromprev = kODFalse;
  864.     ODDraftID        prevDraftID;
  865.     ODVersionID    versionID;
  866.     ODVersionID    prevVersionID;
  867.     ODDraftID        baseDraftID = this->GetBaseDraftID();
  868.  
  869.     if (draftID == baseDraftID) 
  870.         changedfromprev =  kODFalse;
  871.         else
  872.         {
  873.  
  874.        versionID = this->GetDraft(draftID);
  875.  
  876.        prevDraftID = this->GetPreviousDraftID(draftID);
  877.        prevVersionID = this->GetDraft(prevDraftID);
  878.  
  879.        if (versionID == prevVersionID)
  880.         changedfromprev =  kODFalse;
  881.        else
  882.         changedfromprev =  kODTrue;
  883.         }
  884.        return changedfromprev;
  885. }
  886.  
  887. //------------------------------------------------------------------------------
  888. // VersionList::GetBaseDraftID
  889. //------------------------------------------------------------------------------
  890.  
  891. ODDraftID VersionList::GetBaseDraftID()
  892. {
  893.         ODDraftID retDraftID = 1;
  894.     VersionLink* link = (VersionLink*) fLinkedList->First();
  895.     
  896.     if (link != kODNULL)
  897.         retDraftID =  link->GetDraftID();
  898.         return retDraftID;
  899. }
  900.  
  901. //------------------------------------------------------------------------------
  902. // VersionList::GetLatestDraftID
  903. //------------------------------------------------------------------------------
  904.  
  905. ODDraftID VersionList::GetLatestDraftID()
  906. {
  907.     ODDraftID  retDraftID = 0;
  908.     VersionLink*     versionLink;
  909.  
  910.     versionLink = (VersionLink*) fLinkedList->Last();
  911.     
  912.     while ((versionLink != kODNULL) && 
  913.             (versionLink->GetVersionID() == kODTombstonedVersion)) {
  914.         versionLink = (VersionLink*) fLinkedList->Before(*versionLink);
  915.     }
  916.     
  917.     if (versionLink == kODNULL)
  918.         retDraftID =  this->GetBaseDraftID();
  919.     else
  920.         retDraftID =  versionLink->GetDraftID();
  921.         return retDraftID;
  922. }
  923.  
  924. //------------------------------------------------------------------------------
  925. // VersionList::GetPreviousDraftID
  926. //------------------------------------------------------------------------------
  927.  
  928. ODDraftID VersionList::GetPreviousDraftID(ODDraftID curDraftID)
  929. {
  930.     VersionLink*    curVersionLink;
  931.     ODDraftID        baseDraftID = this->GetBaseDraftID();
  932.     VersionLink*    versionLink;
  933.     
  934.     if (baseDraftID == curDraftID)
  935.         BREAK_AND_THROW(kODErrNoPreviousDraft);
  936.     if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
  937.         versionLink = (VersionLink*) fLinkedList->Before(*curVersionLink);
  938.         while (versionLink != kODNULL) {
  939.             if (versionLink->GetVersionID() != kODTombstonedVersion)
  940.                 return versionLink->GetDraftID();
  941.             versionLink = (VersionLink*) fLinkedList->Before(*versionLink);
  942.         }
  943.     }
  944.     BREAK_AND_THROW(kODErrDraftDoesNotExist);
  945.  
  946.         return 0;                       // To avoid unnecessary warning from the compiler.
  947. }
  948.  
  949. //------------------------------------------------------------------------------
  950. // VersionList::GetSameVersionDraftID
  951. //------------------------------------------------------------------------------
  952.  
  953. ODDraftID VersionList::GetSameVersionDraftID(ODDraftID curDraftID)
  954. {
  955.     ODDraftID  sameVersionDraftID = 0;
  956.  
  957.     ODDraftID        baseDraftID = this->GetBaseDraftID(), draftID;
  958.     ODVersionID     latestVersion;
  959.  
  960.     sameVersionDraftID = curDraftID;
  961.     latestVersion = this->GetCurrentVersion(sameVersionDraftID);
  962.     
  963.     if (sameVersionDraftID != baseDraftID) {
  964.         draftID = this->GetPreviousDraftID(sameVersionDraftID);
  965.         while (draftID >= baseDraftID) {
  966.             if (latestVersion == this->GetCurrentVersion(draftID)) {
  967.                 sameVersionDraftID = draftID;
  968.                 if (draftID != baseDraftID)
  969.                     draftID = this->GetPreviousDraftID(draftID);
  970.                 else
  971.                     draftID = 0;
  972.             }
  973.             else
  974.                 draftID = 0;
  975.         };
  976.     }
  977.     return sameVersionDraftID;
  978. }
  979.  
  980. //------------------------------------------------------------------------------
  981. // VersionList::PreviousDraftExists
  982. //------------------------------------------------------------------------------
  983.  
  984. ODBoolean VersionList::PreviousDraftExists(ODDraftID curDraftID)
  985. {
  986.     ODBoolean prevDraftexists = kODFalse;
  987.     VersionLink*    curVersionLink;
  988.     ODDraftID        baseDraftID = this->GetBaseDraftID();
  989.     VersionLink*    versionLink;
  990.     
  991.     if (baseDraftID == curDraftID)
  992.         prevDraftexists =  kODFalse;
  993.         else{
  994.       if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
  995.         versionLink = (VersionLink*) fLinkedList->Before(*curVersionLink);
  996.         while (versionLink != kODNULL) {
  997.             if (versionLink->GetVersionID() != kODTombstonedVersion)
  998.                 return   kODTrue;
  999.             versionLink = (VersionLink*) fLinkedList->Before(*versionLink);
  1000.         }
  1001.       }
  1002.        } 
  1003.        return prevDraftexists;
  1004. }
  1005.  
  1006. //------------------------------------------------------------------------------
  1007. // VersionList::GetNextDraftID
  1008. //------------------------------------------------------------------------------
  1009.  
  1010. ODDraftID VersionList::GetNextDraftID(ODDraftID curDraftID)
  1011. {
  1012.     VersionLink*    curVersionLink;
  1013.     VersionLink*    versionLink;
  1014.     
  1015.     if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
  1016.         versionLink = (VersionLink*) fLinkedList->After(*curVersionLink);
  1017.         while (versionLink != kODNULL) {
  1018.             if (versionLink->GetVersionID() != kODTombstonedVersion)
  1019.                 return  versionLink->GetDraftID();
  1020.             versionLink = (VersionLink*) fLinkedList->After(*versionLink);
  1021.         }
  1022.     }
  1023.     BREAK_AND_THROW(kODErrDraftDoesNotExist);
  1024.  
  1025.         return 0;                       // To avoid unnecessary warning from the compiler.
  1026. }
  1027.  
  1028. //------------------------------------------------------------------------------
  1029. // VersionList::NextDraftExists
  1030. //------------------------------------------------------------------------------
  1031.  
  1032. ODBoolean VersionList::NextDraftExists(ODDraftID curDraftID)
  1033. {
  1034.     VersionLink*    curVersionLink;
  1035.     VersionLink*    versionLink;
  1036.     
  1037.     if ((curVersionLink = this->GetLink(curDraftID)) != kODNULL) {
  1038.         versionLink = (VersionLink*) fLinkedList->After(*curVersionLink);
  1039.         while (versionLink != kODNULL) {
  1040.             if (versionLink->GetVersionID() != kODTombstonedVersion)
  1041.                 return  kODTrue;
  1042.             versionLink = (VersionLink*) fLinkedList->After(*versionLink);
  1043.         }
  1044.     }    
  1045.         return kODFalse;;
  1046. }
  1047.  
  1048. //------------------------------------------------------------------------------
  1049. // VersionList::IsAbove
  1050. //------------------------------------------------------------------------------
  1051.  
  1052. ODBoolean VersionList::IsAbove(ODDraftID draftID1, ODDraftID draftID2)
  1053. {
  1054.     return (draftID1 > draftID2);
  1055. }
  1056.  
  1057. //------------------------------------------------------------------------------
  1058. // VersionList::IsBelow
  1059. //------------------------------------------------------------------------------
  1060.  
  1061. ODBoolean VersionList::IsBelow(ODDraftID draftID1, ODDraftID draftID2)
  1062. {
  1063.     return (draftID1 < draftID2);
  1064. }
  1065.  
  1066. //------------------------------------------------------------------------------
  1067. // VersionList::GetLink
  1068. //------------------------------------------------------------------------------
  1069.  
  1070. VersionLink* VersionList::GetLink(ODDraftID draftID)
  1071. {
  1072.     VersionLink* link = kODNULL;
  1073.     LinkedListIterator    iter(fLinkedList);
  1074.     
  1075.         link  = (VersionLink*) iter.Last();
  1076.     while ((link != kODNULL) && (link->GetDraftID() != draftID)) {
  1077.         link = (VersionLink*) iter.Previous();
  1078.     }
  1079.     return link;
  1080. }
  1081.  
  1082. //------------------------------------------------------------------------------
  1083. // VersionList::Clear
  1084. //------------------------------------------------------------------------------
  1085.  
  1086. void VersionList::Clear()
  1087. {
  1088.     Link*    link;
  1089.     
  1090.     link = fLinkedList->RemoveFirst();
  1091.     while (link != kODNULL) {
  1092.         delete link;
  1093.         link = fLinkedList->RemoveFirst();
  1094.     }
  1095. }
  1096.  
  1097. //------------------------------------------------------------------------------
  1098. // VersionList::GetHeap
  1099. //------------------------------------------------------------------------------
  1100.  
  1101. ODMemoryHeapID VersionList::GetHeap()
  1102. {
  1103.     return fHeap;
  1104. }
  1105.  
  1106. //------------------------------------------------------------------------------
  1107. // VersionList::GetLinkedList
  1108. //------------------------------------------------------------------------------
  1109.  
  1110. LinkedList* VersionList::GetLinkedList()
  1111. {
  1112.     return fLinkedList;
  1113. }
  1114.  
  1115. //------------------------------------------------------------------------------
  1116. // VersionList::Print
  1117. //------------------------------------------------------------------------------
  1118.  
  1119. void VersionList::Print(char* string)
  1120. {
  1121. #if ODDebug
  1122.     VersionListIterator*    versionList = new VersionListIterator(this);
  1123.     versionList->Initialize();
  1124.     for (VersionLink* link = versionList->Last(); versionList->IsNotComplete(); link = versionList->Previous()) {
  1125.         somPrintf("%s: draftID %d versionID %d\n", string, link->GetDraftID(), link->GetVersionID());
  1126.     }
  1127.     delete versionList;
  1128. #endif
  1129. }
  1130.  
  1131. //==============================================================================
  1132. // VersionListIterator
  1133. //==============================================================================
  1134.  
  1135. //------------------------------------------------------------------------------
  1136. // VersionListIterator::VersionListIterator
  1137. //------------------------------------------------------------------------------
  1138.  
  1139. VersionListIterator::VersionListIterator(VersionList* versionList)
  1140. {
  1141.     fVersionList = versionList;
  1142.     fIterator = kODNULL;
  1143. }
  1144.     
  1145. //------------------------------------------------------------------------------
  1146. // VersionListIterator::~VersionListIterator
  1147. //------------------------------------------------------------------------------
  1148.  
  1149. VersionListIterator::~VersionListIterator()
  1150. {
  1151.     delete fIterator;
  1152. }
  1153.  
  1154. //------------------------------------------------------------------------------
  1155. // VersionListIterator::Initialize
  1156. //------------------------------------------------------------------------------
  1157.  
  1158. void VersionListIterator::Initialize()
  1159. {
  1160.     
  1161. #ifdef _PLATFORM_MACINTOSH_
  1162.     fIterator = new(fVersionList->GetHeap()) LinkedListIterator(fVersionList->GetLinkedList());
  1163. #endif
  1164. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  1165. //    The use of heap is not implemented in Windows platform
  1166.     fIterator = new LinkedListIterator(fVersionList->GetLinkedList());
  1167. #endif
  1168. }
  1169.  
  1170. //------------------------------------------------------------------------------
  1171. // VersionListIterator::Last
  1172. //------------------------------------------------------------------------------
  1173.  
  1174. VersionLink* VersionListIterator::Last()
  1175. {
  1176.     return((VersionLink*) fIterator->Last());
  1177. }
  1178.  
  1179. //------------------------------------------------------------------------------
  1180. // VersionListIterator::Previous
  1181. //------------------------------------------------------------------------------
  1182.  
  1183. VersionLink* VersionListIterator::Previous()
  1184. {
  1185.      return((VersionLink*) fIterator->Previous());
  1186. }
  1187.         
  1188. //------------------------------------------------------------------------------
  1189. // VersionListIterator::IsNotComplete
  1190. //------------------------------------------------------------------------------
  1191.  
  1192. ODBoolean VersionListIterator::IsNotComplete()
  1193. {
  1194.     return(fIterator->IsNotComplete());
  1195. }
  1196.