home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / opendc12.zip / od124os2.exe / od12osr1.exe / src / CMDoc.cpp < prev    next >
C/C++ Source or Header  |  1997-03-21  |  59KB  |  2,025 lines

  1. /* @(#)Z 1.20 com/src/bento/CMDoc.cpp, odstorage, od96os2, odos29712d 97/03/21 17:19:03 (96/12/17 13:46:57) */
  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:        CMDoc.cpp
  31.  
  32.     Contains:    Implementation for CMDoc class.
  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.         <54>    10/24/95    jpa        1293441: DM/VL: Bento memory reserve &
  41.                                     fatal container err & don't throw in
  42.                                     Release.
  43.         <53>    10/20/95    VL        1293256: Changed
  44.                                     kODErrBentoInvalidVersionList to
  45.                                     kODErrDraftDoesNotExist.
  46.         <52>    10/13/95    EL        1287340: Use standard ISO prefix
  47.         <51>     10/8/95    TJ        Fixes Recomended by Refball
  48.         <50>     10/3/95    TJ        Added Includes so it compiles
  49.         <49>     10/3/95    TJ        Changes done by RefBall Team
  50.         <48>     9/29/95    TJ        Made Changes for MAC SOM
  51.         <47>      9/8/95    VL        1282012: Replaced kODErrDraftNotExists with
  52.                                     kODErrDraftDoesNotExist.
  53.         <46>      9/8/95    Té        1281096 FB2:Many constants in ODTypesB
  54.                                     without kOD prefix!
  55.         <45>      9/7/95    EL        1281410: Window for draft just above a
  56.                                     deleted draft will not be automatically
  57.                                     closed when that draft is deleted.
  58.         <44>     8/30/95    EL        1270290: Do not close and open the draft in
  59.                                     SaveToPrev and Collapse draft if draft is
  60.                                     not top draft and hence read only.
  61.         <43>     8/21/95    VL        1278330, 1278315: Error code cleanup.
  62.         <42>     8/18/95    NP        1274946: add kODErrInvalidPersistentFormat
  63.         <41>     8/16/95    NP        1274946: ErrorDef.idl problems. Add include
  64.                                     file.
  65.         <40>     8/12/95    Té        1276806 Optimization: use kODFalse instead
  66.                                     of kODTrue in comparisons
  67.         <39>      8/8/95    EL        #1273589: version list is not collapsed
  68.                                     when document is closed.
  69.         <38>      8/3/95    RR        #1257260: Collapse B classes. Remove
  70.                                     somInit methods. Don't call IsInitialized
  71.                                     or SubclassResponsibility
  72.         <37>     7/21/95    VL        1270320: Removed internal field _fName.
  73.         <36>     6/28/95    RR        1242642 BB Mostly ref counting. RemoveDraft
  74.                                     releases draft before deleting it
  75.         <35>     6/20/95    VL        1259397: Release Draft after getting its id
  76.                                     in GetDraftGut.
  77.         <34>     5/26/95    VL        1251403: Multithreading naming support.
  78.         <33>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  79.         <32>     5/18/95    CC        1238898: Add destFrame argument to
  80.                                     BeginClone call.
  81.         <31>     5/18/95    EL        1249941: Set container dirty flag when
  82.                                     drafts changed.
  83.         <30>     4/25/95    VL        1210982: Removed 5$.
  84.         <29>      4/7/95    EL        1225905: Call SetModDate when save to prev.
  85.         <28>     3/31/95    EL        1234685: If top draft embedded container
  86.                                     has not been saved don't write it in the
  87.                                     version list. Don't externalize version
  88.                                     list except before flush or close.
  89.         <27>     3/29/95    DM        make standard format little endian
  90.         <26>     3/24/95    EL        1209355: Cut down on version list
  91.                                     externalization. Flush file container in
  92.                                     SaveToAPrevDraft.
  93.         <25>     3/23/95    VL        1230357: Implemented Purge. 1228003: Added
  94.                                     debug code for versionlist.
  95.         <24>      3/9/95    VL        1220320: Moved public error codes from
  96.                                     Bento to ErrorDef.idl.
  97.         <23>     2/17/95    EL        1182275: Collapse version list before
  98.                                     closing embedded container so we know if
  99.                                     there is a new draft.
  100.         <22>     2/13/95    Té        1219963: Document:AcquireDraft should not bump
  101.                                     refcount if kPosSame and release==true
  102.         <21>     1/31/95    EL        1195846: revert file if there is no real
  103.                                     change.
  104.         <20>     1/26/95    eeh        1214080: OpenDoc really uses kODMacIText,
  105.                                     not kODIntlText.
  106.         <19>     1/25/95    jpa        Include StdExts.xh
  107.         <18>     1/11/95    VL        1185688: Made storage more robust in terms
  108.                                     of error handling. Also did some code
  109.                                     review cleanup.
  110.         <17>    11/14/94    VL        1155887: Changed AcquireDraft to handle new
  111.                                     posCode for top draft.
  112.         <16>    10/19/94    VL        1155857: Added ODDebug_Drafts for debugging
  113.                                     "Cannot create more than 10 drafts"
  114.                                     problem.
  115.         <15>     9/29/94    RA        1189812: Mods for 68K build.
  116.         <14>     9/23/94    VL        1184272: ContainerID is now a sequence of
  117.                                     octets. 1184166: DocumentName is ODIText
  118.                                     now.
  119.         <13>      9/6/94    VL        1184154: Include StorageU.xh.
  120.         <12>      9/6/94    VL        1184154: Removed include file also.
  121.         <11>      9/6/94    VL        1184154: Removed AcquireDocumentProperties.
  122.         <10>      9/5/94    VL        1184871: Used Renew to remove dependency on
  123.                                     default heap.
  124.          <9>     8/31/94    Té        #1183129, #1183116, #1183119, #1183111:
  125.                                     Lots of ErrorCode cleanup.
  126.          <8>     8/31/94    VL        No code change. Fixed comments in <7>.
  127.          <7>     8/31/94    VL        1161158, 1106013: Commented out code which
  128.                                     does checking on embedded container's use
  129.                                     mode in AcquireDraft. This should avoid a
  130.                                     crashing bug when the embedded container is
  131.                                     kODNULL. Also, fixed GetName to make it
  132.                                     return kODNULL if the document doesn't have a name.
  133.          <6>     8/26/94    VL        1183174: Use updated cloning APIs.
  134.          <5>     8/16/94    Té        #1180922  Remove more obsolete types from
  135.                                     StdTypes.idl.  Localized kODVersionList to
  136.                                     this file.
  137.          <4>      8/3/94    VL        1153123: Storage to ODStor.
  138.          <3>     7/14/94    VL        Check return value for kODNULL before
  139.                                     calling GetUseMode in AcquireDraftGut.
  140.          <2>     7/11/94    VL        Added Exists.
  141.          <1>      7/5/94    VL        first checked in
  142.  
  143.     To Do:
  144.     In Progress:
  145.         
  146. */
  147.  
  148. #define CMDocument_Class_Source
  149. #define VARIABLE_MACROS
  150. #include <CMDoc.xih>
  151.  
  152. #ifndef SOM_ODContainer_xh
  153. #include <ODCtr.xh>
  154. #endif
  155.  
  156. #ifndef SOM_ODStorageUnit_xh
  157. #include <StorageU.xh>
  158. #endif
  159.  
  160. #ifndef _EXCEPT_
  161. #include "Except.h"
  162. #endif
  163.  
  164. #ifndef _TEMPOBJ_
  165. #include "TempObj.h"
  166. #endif
  167.  
  168. #ifndef _FLIPEND_
  169. #include "FlipEnd.h"
  170. #endif
  171.  
  172. #ifndef SOM_ODEmbeddedContainer_xh
  173. #include <EmbedCtr.xh>
  174. #endif
  175.  
  176. #ifndef SOM_CMDraft_xh
  177. #include <CMDraft.xh>
  178. #endif
  179.  
  180. #ifndef SOM_ODSession_xh
  181. #include <ODSessn.xh>
  182. #endif
  183.  
  184. #ifndef __STRING__
  185. #include <string.h>        // For strlen, strcpy....
  186. #endif
  187.  
  188. #ifndef _INDHDR_
  189. #include "IndHdr.h"            // For Embedded Property and Type names
  190. #endif
  191.  
  192. #ifndef _CMCTR_
  193. #include "CMCtr.xh"            // Just for getting fContainer
  194. #endif
  195.  
  196. #ifndef _DOCPRIV_
  197. #include "DocPriv.h"
  198. #endif
  199.  
  200. #ifndef _ISOSTR_
  201. #include "ISOStr.h"
  202. #endif
  203.  
  204. #ifndef SOM_Module_OpenDoc_StdProps_defined
  205. #include <StdProps.xh>
  206. #endif
  207.  
  208. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  209. #include <StdTypes.xh>
  210. #endif
  211.  
  212. #ifndef _ODMEMORY_
  213. #include "ODMemory.h"
  214. #endif
  215.  
  216. #ifndef _ODNEW_
  217. #include "ODNew.h"
  218. #endif
  219.  
  220. #ifndef _BENTODEF_
  221. #include "BentoDef.h"
  222. #endif
  223.  
  224. #ifndef _ODDEBUG_
  225. #include <ODDebug.h>
  226. #endif
  227.  
  228. #ifndef _ITEXT_
  229. #include <IText.h>
  230. #endif
  231.  
  232. #ifndef _UTILERRS_
  233. #include "UtilErrs.h"
  234. #endif
  235.  
  236. #ifndef __TIME_H__
  237. #include <time.h>
  238. #endif
  239.  
  240. #ifndef _SESSHDR_
  241. #include "SessHdr.h"
  242. #endif
  243.  
  244. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  245. #ifndef _ODUTILS_
  246. #include "ODUtils.h"
  247. #endif
  248. #endif
  249.  
  250. #ifndef _BENTOERR_
  251. #include "BentoErr.h"
  252. #endif
  253.  
  254. #pragma segment CMDocument
  255.  
  256. //==============================================================================
  257. // Constants
  258. //==============================================================================
  259.  
  260. // Private ISO Strings
  261. const     ODPropertyName    kODDocumentProperties    = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Bento Container Suite:Property:DocumentProperties";
  262. const    ODValueType        kODVersionList             = "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Bento Container Suite:Type:CMVersionList";
  263.  
  264. // For debugging
  265.  
  266. #if ODDebug
  267. // #define ODDebug_Drafts 1
  268. // #define ODDebug_DebugRefCount    1
  269. #endif
  270.  
  271. //==============================================================================
  272. // Function Prototype
  273. //==============================================================================
  274.  
  275. static CMDraft* NewCMDraft(ODMemoryHeapID heapID);
  276. static CMObject AcquireDocumentPropertiesObject(CMContainer container);
  277.  
  278. // The following two functions need to be filled in when we are moving to a 
  279. // real multithread system.
  280.  
  281. #define EnableInterrupt()
  282. #define DisableInterrupt()
  283.  
  284.  
  285. // For debugging
  286.  
  287. #ifdef DebugStorage
  288.  
  289. #define MyDebugStr(s) do {somPrintf(s);} while (0)
  290. #define MyDebug1Str(f,p1) do {somPrintf(f, p1);} while (0)
  291. #define MyDebug2Str(f,p1,p2) do {somPrintf(f, p1, p2);} while (0)
  292. #define MyDebug3Str(f,p1,p2,p3) do {somPrintf(f, p1, p2,p3);} while (0)
  293.  
  294. #else
  295.  
  296. #define MyDebugStr(s)
  297. #define MyDebug1Str(f,p1)
  298. #define MyDebug2Str(f,p1,p2)
  299. #define MyDebug3Str(f,p1,p2,p3)
  300.  
  301. #endif
  302.  
  303. #if ODDebug_Drafts
  304.  
  305. #ifndef _MEMDEBG_
  306. #include <MemDebg.h>
  307. #endif
  308.  
  309. static void PrintDrafts(Environment* ev, DraftList* drafts, char* string);
  310. static void PrintHeapInfo();
  311. #endif
  312.  
  313.  
  314. //==============================================================================
  315. // CMDocument
  316. //==============================================================================
  317.  
  318. //------------------------------------------------------------------------------
  319. // CMDocument: GetCMVersionList
  320. //------------------------------------------------------------------------------
  321.  
  322. SOM_Scope CMValue  SOMLINK CMDocumentGetCMVersionList(CMDocument *somSelf, Environment *ev)
  323. {
  324.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  325.     CMDocumentMethodDebug("CMDocument","CMDocumentGetCMVersionList");
  326.  
  327.     CMValue            versionList = kODNULL;
  328.     try
  329.     { 
  330.     
  331.     CMContainer cmContainer = _fContainer->GetCMContainer(ev);
  332.     ODSessionMustHaveCMAllocReserve(cmContainer);
  333.     
  334.     CMProperty        versionListProp;
  335.     CMObject        versionListObj;
  336.     
  337.     if ((versionListProp = CMRegisterProperty(cmContainer, kODPropVersionList)) == kODNULL)
  338.         THROW(kODErrBentoInvalidProperty);
  339.         
  340.     versionListObj = CMGetNextObjectWithProperty(cmContainer, kODNULL, versionListProp);
  341.     
  342.     if (versionListObj != kODNULL)
  343.         versionList = CMGetNextValue(versionListObj, versionListProp, kODNULL);
  344.  
  345.     ODSessionRestoreCMAllocReserve(cmContainer);
  346.     }
  347.     catch (ODException _exception)
  348.     {
  349.      versionList = kODNULL;
  350.          ODSetSOMException(ev, _exception);
  351.     }
  352.  
  353.     return versionList;
  354. }
  355.  
  356. //------------------------------------------------------------------------------
  357. // CMDocument: AcquireDraftGut
  358. //------------------------------------------------------------------------------
  359.  
  360. SOM_Scope CMDraft*  SOMLINK CMDocumentAcquireDraftGut(CMDocument *somSelf, Environment *ev,
  361.         VersionList* versionList,
  362.         ODDraftPermissions perms,
  363.         ODDraftID id,
  364.         CMDraft* draft,
  365.         ODPositionCode posCode,
  366.         ODBoolean release)
  367. {
  368.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  369.     CMDocumentMethodDebug("CMDocument","CMDocumentAcquireDraftGut");
  370.  
  371.     CMDraft*    newDraft = kODNULL;    
  372.         ODBoolean acquired = kODFalse;
  373.         ODBoolean CreateNewDraft = kODFalse;
  374.  
  375.     try
  376.     {
  377.  
  378. #if ODDebug_Drafts
  379.     somPrintf("**** Entering AcquireDraftGut: id %d draft %x posCode %d release %d\n", id, draft, posCode, release);
  380.     PrintDrafts(ev, _fDrafts, "**** Entering AcquireDraftGut");
  381.     somSelf->GetVersionList(ev)->Print(">>> Entering AcquireDraftGut");
  382. #endif
  383.  
  384.     CMDraft*                fromDraft = (CMDraft*) draft;
  385.     ODDraftID                latestDraftID;
  386.     ODDraftID                fromDraftID;
  387.     ODDraftID                prevDraftID;
  388.     ODDraftID                nextDraftID;
  389.  
  390.     if (id != 0) {
  391.         if ((newDraft = _fDrafts->Get(id)) != kODNULL) {
  392.             if ((perms == kODDPReadOnly) ||
  393.                 (newDraft->GetPermissions(ev) == kODDPExclusiveWrite)) {
  394.                 newDraft->Acquire(ev);
  395.                                 acquired = kODTrue;
  396.                 MyDebugStr("**** AcquireDraft: Acquire only.\n");
  397.             }
  398.             else
  399.                 THROW(kODErrInvalidPermissions);
  400.         }
  401.         else if ((newDraft = _fReleasedDrafts->Get(id)) != kODNULL) {
  402.             if (perms == kODDPExclusiveWrite) {
  403.                 if (newDraft->GetPermissions(ev) == kODDPReadOnly) {
  404.                         latestDraftID = versionList->GetLatestDraftID();
  405.                         if (versionList->IsAbove(latestDraftID, id) != kODFalse)
  406.                             THROW(kODErrInvalidPermissions);
  407.                         MyDebugStr("**** AcquireDraft: From ReadOnly to ExclusiveWrite.\n");
  408.                 }
  409.             }
  410.             newDraft->Reinitialize(ev, perms);
  411.             _fReleasedDrafts->Remove(id);
  412.             _fDrafts->Add(id, newDraft);
  413.             newDraft->Acquire(ev);
  414.                         acquired = kODTrue;
  415.             MyDebugStr("**** AcquireDraft: Back from the _fReleasedDrafts pile.\n");
  416.         }
  417.         else {                
  418.             newDraft = NewCMDraft(somSelf->GetHeap(ev));
  419.                         CreateNewDraft = kODTrue;
  420.             newDraft->InitDraft(ev, somSelf, id, perms);
  421.             
  422.             _fDrafts->Add(id, newDraft);
  423.     
  424.             MyDebug3Str("**** id %d draft %x perms %d\n", id, newDraft, newDraft->GetPermissions(ev));
  425.         }    
  426.     }
  427.     else {
  428.         if ((posCode != kODPosTop) && (fromDraft == kODNULL)) {
  429.             THROW(kODErrInvalidDraftID);
  430.         }
  431.         switch (posCode) {
  432.             case kODPosTop:
  433.                 if (fromDraft != kODNULL)
  434.                     THROW(kODErrInvalidDraftID);
  435.                 nextDraftID = versionList->GetLatestDraftID();
  436.                 newDraft = somSelf->AcquireDraftGut(ev, versionList,
  437.                                     perms,
  438.                                     nextDraftID,
  439.                                     kODNULL,
  440.                                     kODPosUndefined,
  441.                                     kODFalse);
  442.             break;
  443.             case kODPosSame:
  444.                 if (fromDraft->GetPermissions(ev) == perms) {
  445.                     if (release == kODFalse)
  446.                         fromDraft->Acquire(ev);
  447.                     newDraft = fromDraft;
  448.                                         acquired = kODTrue;
  449.                 }
  450.                 else {
  451.                     if (fromDraft->GetRefCount(ev) != 1)
  452.                         THROW(kODErrRefCountNotEqualOne);
  453.                     if (release == kODFalse)
  454.                         THROW(kODErrCannotChangePermissions);
  455.                     fromDraftID = fromDraft->GetID(ev);
  456.                     fromDraft->Release(ev);
  457.                     newDraft = somSelf->AcquireDraftGut(ev, versionList,
  458.                                                 perms,
  459.                                                 fromDraftID,
  460.                                                 kODNULL,
  461.                                                 kODPosUndefined,
  462.                                                 kODFalse);
  463.                 }
  464.             break;
  465.             case kODPosFirstBelow:
  466.             case kODPosLastBelow:
  467.                 fromDraftID = fromDraft->GetID(ev);
  468.                 prevDraftID = versionList->GetPreviousDraftID(fromDraftID);
  469.                 if (release != kODFalse)
  470.                     fromDraft->Release(ev);
  471.                 newDraft = somSelf->AcquireDraftGut(ev, versionList,
  472.                                             perms,
  473.                                             prevDraftID,
  474.                                             kODNULL,
  475.                                             kODPosUndefined,
  476.                                             kODFalse);
  477.             break;
  478.             case kODPosFirstAbove:
  479.             case kODPosLastAbove:
  480.                 fromDraftID = fromDraft->GetID(ev);
  481.                 nextDraftID = versionList->GetNextDraftID(fromDraftID);
  482.                 if (release != kODFalse)
  483.                     fromDraft->Release(ev);
  484.                 newDraft = somSelf->AcquireDraftGut(ev, versionList,
  485.                                             perms,
  486.                                             nextDraftID,
  487.                                             kODNULL,
  488.                                             kODPosUndefined,
  489.                                             kODFalse);
  490.                 break;
  491.             case kODPosUndefined:
  492.             case kODPosAll:
  493.             case kODPosFirstSib:
  494.             case kODPosLastSib:
  495.             case kODPosNextSib:
  496.             case kODPosPrevSib:
  497.             default:
  498.                 THROW(kODErrUnsupportedPosCode);
  499.             break;
  500.         }
  501.     }
  502.     
  503. #if ODDebug_Drafts
  504.     PrintDrafts(ev, _fDrafts, "**** Exiting AcquireDraftGut");
  505.     somSelf->GetVersionList(ev)->Print(">>> Exiting AcquireDraftGut");
  506. #endif
  507.  
  508.     }
  509.     catch (ODException _exception)
  510.     {
  511.       ODError error = ErrorCode();
  512.       SaveEv();
  513.       try
  514.       {
  515.          if (acquired){
  516.              newDraft->Release(ev);
  517.          newDraft = kODNULL;
  518.          }
  519.          if (CreateNewDraft)
  520.              ODDeleteObject(newDraft);
  521.       }
  522.       catch(ODException _exception)
  523.       {
  524.           SetErrorCode(kODNoError);
  525.       }
  526.       RestoreEv();
  527.       ODSetSOMException(ev, error);
  528.       
  529.     }
  530.     return newDraft;
  531. }
  532.  
  533. //------------------------------------------------------------------------------
  534. // CMDocument: ~CMDocument
  535. //------------------------------------------------------------------------------
  536.  
  537. SOM_Scope void  SOMLINK CMDocumentsomUninit(CMDocument *somSelf)
  538. {
  539.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  540.     CMDocumentMethodDebug("CMDocument","CMDocumentsomUninit");
  541.  
  542.     
  543.     Environment*    ev = somGetGlobalEnvironment();
  544.     DraftListIterator*    iter = kODNULL;
  545.     DraftListIterator*    releasedDraftsIter = kODNULL;
  546.     try
  547.     { 
  548.     
  549. #ifdef _PLATFORM_MACINTOSH_
  550.                     iter  = new(somSelf->GetHeap(ev)) DraftListIterator(_fDrafts);
  551. #endif
  552. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  553. //    The use of heap is not implemented in Windows platform
  554.         iter = new DraftListIterator(_fDrafts);
  555. #endif
  556.     iter->Initialize();
  557.     
  558. #ifdef _PLATFORM_MACINTOSH_
  559.                  releasedDraftsIter = new(somSelf->GetHeap(ev)) DraftListIterator(_fReleasedDrafts);
  560. #endif
  561. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  562. //    The use of heap is not implemented in Windows platform
  563.     releasedDraftsIter = new DraftListIterator(_fReleasedDrafts);
  564. #endif
  565.     releasedDraftsIter->Initialize();
  566.     
  567.     CMDraft*            draft;
  568.  
  569. #if ODDebug_DebugRefCount
  570.     if (somSelf->GetRefCount(ev) != 0)
  571.         DebugStr("\pRefCount of Document is not 0 at uninit.");
  572.     somPrintf("~CMDocument %x RefCount %d\n", somSelf, somSelf->GetRefCount(ev));
  573. #endif
  574.  
  575.     draft = iter->Last();
  576.     while (draft != kODNULL) {
  577.         delete draft;
  578.         draft = iter->Previous();
  579.     }
  580.         
  581.     draft = releasedDraftsIter->Last();
  582.     while (draft != kODNULL) {
  583.         delete draft;
  584.         draft = releasedDraftsIter->Previous();
  585.     }
  586.         
  587.     delete iter;
  588.     delete releasedDraftsIter;
  589.     delete _fVersions;
  590.     delete _fDrafts;
  591.     delete _fReleasedDrafts;
  592.     
  593.     parent_somUninit(somSelf);
  594.    }
  595.    catch (ODException _exception)
  596.    {
  597.         ODDeleteObject(iter);
  598.         ODDeleteObject(releasedDraftsIter);
  599.         ODSetSOMException(ev, _exception);
  600.    }
  601.  
  602. }
  603.  
  604. //------------------------------------------------------------------------------
  605. // CMDocument: Purge
  606. //------------------------------------------------------------------------------
  607.  
  608. SOM_Scope ODSize  SOMLINK CMDocumentPurge(CMDocument *somSelf, Environment *ev,
  609.         ODSize size)
  610. {
  611.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  612.     CMDocumentMethodDebug("CMDocument","CMDocumentPurge");
  613.   
  614.      ODSize purgedSize = 0;
  615.     DraftListIterator* draftList = kODNULL;
  616.  
  617.     try
  618.     {     
  619.      
  620. #ifdef _PLATFORM_MACINTOSH_
  621.                   draftList  = new(somSelf->GetHeap(ev)) DraftListIterator(_fDrafts);
  622. #endif
  623. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  624. //     The use of heap is not implemented in Windows platform
  625.              draftList = new DraftListIterator(_fDrafts);
  626. #endif
  627.     draftList->Initialize();
  628.     CMDraft* draft = draftList->Last();
  629.     while (draft != kODNULL) {
  630.         purgedSize += draft->Purge(ev, size-purgedSize);
  631.         draft = draftList->Previous();
  632.     }
  633.     delete draftList;
  634.  
  635.      }
  636.      catch(ODException _exception)
  637.      {
  638.        purgedSize = 0;
  639.            ODDeleteObject(draftList);
  640.            ODError error = ErrorCode();
  641.            ODSetSOMException(ev, error);
  642.      }
  643.     return purgedSize;
  644. }
  645.  
  646. //------------------------------------------------------------------------------
  647. // CMDocument: Acquire
  648. //------------------------------------------------------------------------------
  649.  
  650. SOM_Scope void  SOMLINK CMDocumentAcquire(CMDocument *somSelf, Environment *ev)
  651. {
  652. //  CMDocumentData *somThis = CMDocumentGetData(somSelf);
  653.     CMDocumentMethodDebug("CMDocument","CMDocumentAcquire");
  654.  
  655.     parent_Acquire(somSelf,ev);
  656. }
  657.  
  658. //------------------------------------------------------------------------------
  659. // CMDocument: Release
  660. //------------------------------------------------------------------------------
  661.  
  662. SOM_Scope void  SOMLINK CMDocumentRelease(CMDocument *somSelf, Environment *ev)
  663. {
  664.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  665.     CMDocumentMethodDebug("CMDocument","CMDocumentRelease");
  666.  
  667.     try
  668.     {
  669.     
  670. #if TestFlushContainer
  671.         if (_fContainer->GetDirtyFlag(ev) != kODFalse)
  672.             somSelf->ExternalizeVersionList(ev, kODFalse);
  673. #endif
  674.  
  675.         parent_Release(somSelf,ev);
  676.         if (somSelf->GetRefCount(ev) == 0) {
  677.             _fContainer->ReleaseDocument(ev, somSelf);
  678.         }
  679.         
  680.     }
  681.     catch(ODException _exception)
  682.     {
  683.         
  684.         ODError err = ErrorCode();
  685.  
  686.         WARNMSG(WARN_INDEX(AMSG_650),"Error occurred in ODDocument::Release: %d %s", 
  687.             err, ErrorMessage() ?ErrorMessage() :"");
  688.  
  689.         if (err == kODErrBentoErr)
  690.             SetErrorCode(kODErrUndefined);
  691.         else if (err != kODErrUndefined)
  692.             SetErrorCode(kODNoError);
  693.         
  694.     }
  695. }
  696.  
  697. //------------------------------------------------------------------------------
  698. // CMDocument: AcquireContainer
  699. //------------------------------------------------------------------------------
  700.  
  701. SOM_Scope ODContainer*  SOMLINK CMDocumentGetContainer(CMDocument *somSelf, Environment *ev)
  702. {
  703.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  704.     CMDocumentMethodDebug("CMDocument","CMDocumentGetContainer");
  705.  
  706.     return (ODContainer*) _fContainer;
  707. }
  708.  
  709. //------------------------------------------------------------------------------
  710. // CMDocument: GetID
  711. //------------------------------------------------------------------------------
  712.  
  713. SOM_Scope ODDocumentID  SOMLINK CMDocumentGetID(CMDocument *somSelf, Environment *ev)
  714. {
  715.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  716.     CMDocumentMethodDebug("CMDocument","CMDocumentGetID");
  717.  
  718.     return _fID;
  719. }
  720.  
  721. //------------------------------------------------------------------------------
  722. // CMDocument: GetName
  723. //------------------------------------------------------------------------------
  724.  
  725. SOM_Scope ODDocumentName SOMLINK CMDocumentGetName(CMDocument *somSelf, Environment *ev)
  726. {    
  727.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  728.     CMDocumentMethodDebug("CMDocument","CMDocumentGetName");
  729.     
  730.     ODDocumentName *name = kODNULL;
  731. #if defined(_PLATFORM_WIN32) || defined(_PLATFORM_OS2) || defined(_PLATFORM_AIX)
  732.     ODDocumentName dummy;
  733. #endif
  734.  
  735.      try
  736.      {
  737.     
  738.     CMContainer cmContainer = _fContainer->GetCMContainer(ev);
  739.     ODSessionMustHaveCMAllocReserve(cmContainer);
  740.  
  741.     CMObject    cmObject = AcquireDocumentPropertiesObject(cmContainer);
  742.     ASSERTMSG(cmObject, kODErrNoDocumentProperties, 
  743.         "No Document Properties Object.", 0);
  744.     
  745.     CMProperty    cmProp = CMRegisterProperty(cmContainer, kODPropDocumentName);
  746.     CMType        cmType = CMRegisterType(cmContainer, kODPlatformIText);
  747.     CMValue        cmValue = CMUseValue(cmObject, cmProp, cmType);
  748.     
  749.     if (cmValue != kODNULL) {
  750.         ODITextFormat stdFormat;
  751.         CMReadValueData(cmValue, &stdFormat, 0, sizeof(ODITextFormat));
  752.         ODITextFormat format = ConvertODULongFromStd(stdFormat);
  753.         
  754.         if( format != kODTraditionalMacText ) {
  755.             WARNMSG(WARN_INDEX(AMSG_660),"Reading IText in unknown format %ld",format);
  756.             THROW(kODErrInvalidPersistentFormat);
  757.         }
  758.         ODULong size = CMGetValueSize(cmValue) - sizeof(ODITextFormat);
  759.         name = CreateIText(size);
  760.         name->format = format;
  761.         CMReadValueData(cmValue, name->text._buffer,  sizeof(ODITextFormat), name->text._length);
  762.     } else {
  763.         name = SetITextStringLength(kODNULL,0,kODFalse);
  764.         somSelf->SetName(ev, name);
  765.     }
  766.     
  767.     ODSessionRestoreCMAllocReserve(cmContainer);
  768.         
  769.      }
  770.      catch (ODException _exception)
  771.      {
  772. #ifdef _PLATFORM_MACINTOSH_
  773.         ODDocumentName dummy;
  774.         return dummy; // will be ignored since error set
  775. #endif
  776. #if defined(_PLATFORM_WIN32) || defined(_PLATFORM_OS2) || defined(_PLATFORM_AIX)
  777.         *name = dummy;
  778. #endif
  779.         ODSetSOMException(ev, _exception);
  780.     
  781.     }
  782.     return *name;
  783. }
  784.  
  785. //------------------------------------------------------------------------------
  786. // CMDocument: SetName
  787. //------------------------------------------------------------------------------
  788.  
  789. SOM_Scope void  SOMLINK CMDocumentSetName(CMDocument *somSelf, Environment *ev,
  790.         ODDocumentName* name)
  791. {
  792.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  793.     CMDocumentMethodDebug("CMDocument","CMDocumentSetName");
  794.  
  795.    try
  796.    {
  797.     
  798.     CMContainer    cmContainer = _fContainer->GetCMContainer(ev);
  799.     ODSessionMustHaveCMAllocReserve(cmContainer);
  800.  
  801.     CMObject    cmObject = AcquireDocumentPropertiesObject(cmContainer);
  802.     ASSERTMSG(cmObject, kODErrNoDocumentProperties, 
  803.         "No Document Properties Object.", 0);
  804.     
  805.     CMProperty    cmProp = CMRegisterProperty(cmContainer, kODPropDocumentName);
  806.     CMType        cmType = CMRegisterType(cmContainer, kODPlatformIText);
  807.     CMValue        cmValue = CMUseValue(cmObject, cmProp, cmType);
  808.     if (cmValue == kODNULL) {
  809.         cmValue = CMNewValue(cmObject, cmProp, cmType);
  810.     }
  811.     ODITextFormat stdFormat = ConvertODULongToStd(name->format);
  812.     CMWriteValueData(cmValue, &stdFormat, 0, sizeof(ODITextFormat));
  813.     CMWriteValueData(cmValue, name->text._buffer,  sizeof(ODITextFormat), name->text._length);
  814.  
  815.     ODSessionRestoreCMAllocReserve(cmContainer);
  816.     }
  817.     catch (ODException _exception)
  818.     {
  819.         ODSetSOMException(ev, _exception);
  820.     }
  821.  
  822. }
  823.  
  824. //------------------------------------------------------------------------------
  825. // CMDocument: CollapseDrafts
  826. //------------------------------------------------------------------------------
  827.  
  828. SOM_Scope ODDocument*  SOMLINK CMDocumentCollapseDrafts(CMDocument *somSelf, Environment *ev,
  829.         ODDraft* fromDraft,
  830.         ODDraft* toDraft)
  831. {
  832.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  833.     CMDocumentMethodDebug("CMDocument","CMDocumentCollapseDrafts");
  834.  
  835.     try
  836.     {
  837.  
  838.     CMDraft*        from = (CMDraft*) fromDraft;
  839.     CMDraft*        to = (CMDraft*) toDraft; ODVolatile(to);
  840.     VersionList*    versionList = kODNULL;
  841.     ODDraftID        fromID;
  842.     ODDraftID        toID;
  843.     ODDraftID        baseID;
  844.     ODBoolean         revertIt = kODFalse;
  845.     
  846.     TempODDraft     tempDraft = kODNULL; // DMc - better way to release
  847.  
  848.     versionList = somSelf->TestAndGetVersionList(ev);
  849.     ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  850.     
  851.     
  852.     if (!from) {
  853. //    LOG("Illegal NULL fromDraft parameter in ODDraft::CollapseDrafts method");
  854.             THROW(kODErrIllegalNullDraftInput);
  855. //    ODSetSOMException(ev, kODErrIllegalNullDraftInput);
  856. //    return somSelf;
  857.     }
  858.  
  859.     fromID = from->GetID(ev);
  860.     baseID = versionList->GetBaseDraftID();
  861.     
  862.     if (to == kODNULL) {
  863.         toID = versionList->GetPreviousDraftID(fromID);
  864.         to = (CMDraft*) somSelf->AcquireDraft(ev, kODDPReadOnly, 
  865.                 toID, kODNULL, kODPosUndefined, kODFalse);
  866.         // releaseToDraft = kODTrue;
  867.         tempDraft = to; // ensure it's released
  868.     }
  869.     else {
  870.         toID = to->GetID(ev);
  871.     }
  872.     
  873.     if ((fromID == baseID) || (fromID == toID))
  874.         return somSelf;
  875.     if (versionList->IsAbove(fromID, toID) == kODFalse){
  876.          THROW(kODErrCannotCollapseDrafts);
  877. //    LOG("Draft version list error in ODDraft::CollapseDrafts method");
  878. //    ODSetSOMException(ev, kODErrCannotCollapseDrafts);
  879. //    return somSelf;
  880.     }
  881.     
  882.     // from cannot have a ref count more than 1 if it is the top draft
  883.     // if from is not top draft, then we are not going to do anything 
  884.     // to the draft and we need not worry about the ref count
  885.     
  886.     if (fromID == _fVersions->GetLatestDraftID())
  887.         if (from->GetRefCount(ev) > 1) // Check for outstanding draft
  888.         {
  889. //           LOG("Outstanding Draft error in ODDraft::CollapseDrafts");
  890.            THROW(kODErrOutstandingDraft);
  891.          }
  892.     
  893.         
  894. #ifdef _PLATFORM_MACINTOSH_
  895.     DraftListIterator* draftList = 
  896.             new(somSelf->GetHeap(ev)) DraftListIterator(_fDrafts);
  897. #endif
  898. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  899. //    The use of heap is not implemented in Windows platform
  900.     DraftListIterator* draftList = new DraftListIterator(_fDrafts);
  901. #endif
  902.     draftList->Initialize();
  903.     CMDraft* draft = draftList->Last();
  904.     while (draft != kODNULL) {
  905.         ODDraftID draftID = draft->GetID(ev);
  906.         if ((versionList->IsBelow(draftID, fromID) != kODFalse) && 
  907.             (versionList->IsAbove(draftID, toID) != kODFalse) &&
  908.             (versionList->GetCurrentVersion(draftID) != kODTombstonedVersion))
  909.             THROW(kODErrOutstandingDraft);
  910. //           LOG("Outstanding Draft error in ODDraft::CollapseDrafts");
  911.         else
  912.             draft = draftList->Previous();
  913.     }
  914.     delete draftList;
  915.     
  916.     // Flush the from draft
  917.         
  918.     if ((from->GetPermissions(ev) == kODDPExclusiveWrite) &&
  919.         (from->NeedExternalizing(ev) != kODFalse)) {
  920.          THROW(kODErrNonEmptyDraft);
  921. //          LOG("Nonempty Draft in ODDraft::CollapseDrafts method");
  922. //        ODSetSOMException(ev, kODErrIllegalNullDraftInput);
  923. //        return somSelf;
  924.     }
  925.     else if (from->IsChangedFromPrev(ev, versionList) != kODFalse){
  926.          THROW(kODErrNonEmptyDraft);
  927. //                 LOG("Nonempty Draft in ODDraft::CollapseDrafts method");
  928. //        ODSetSOMException(ev, kODErrIllegalNullDraftInput);
  929. //        return somSelf;
  930.     }
  931.         
  932.     if (from->IsNewDraft(ev) != kODFalse) {
  933.         revertIt = kODTrue;
  934. //        _fDrafts->Remove(from->GetID(ev));
  935.         ODDraftID id = from->GetID(ev);
  936.         from->Release(ev);
  937.         _fReleasedDrafts->Remove(id);
  938.         from->Abort(ev);
  939.         delete from;
  940.     }
  941.     else {
  942.     // so that the collapsed version list will be written out on close
  943.         _fContainer->SetDirtyFlag(ev, kODTrue);
  944.  
  945.         // Release the draft
  946.         
  947.         from->Release(ev);
  948.     }
  949.  
  950.     // CollapseDrafts on VersionList
  951.         
  952.     versionList->CollapseDrafts(fromID, toID);
  953.         
  954. #if !TestFlushContainer        
  955.     // Make the change persistent
  956.  
  957.     somSelf->ExternalizeVersionList(ev, kODFalse);
  958. #endif
  959.         
  960.     // If no change, then clear the dirty flag
  961.         
  962.     if (revertIt != kODFalse)
  963.         _fContainer->SetDirtyFlag(ev, kODFalse);
  964.  
  965.     
  966.     somSelf->ReleaseVersionList(ev);
  967.     
  968.     //if (releaseToDraft != kODFalse)
  969.     //    to->Release(ev);
  970. #ifdef _NO_TMP_OBJS_
  971.     if (tempDraft != kODNULL)
  972.         tempDraft->Release(ev);
  973. #endif
  974.     
  975.  
  976.    }
  977.    catch (ODException _exception)
  978.    {
  979.       ODError error = ErrorCode();
  980.       SaveEv();
  981.       try
  982.       {
  983.     somSelf->ReleaseVersionList(ev);
  984.       }
  985.       catch (ODException _exception)
  986.       {
  987.           SetErrorCode(kODNoError);
  988.       }
  989.       RestoreEv();
  990.       ODSetSOMException(ev, error);
  991.    }
  992.     return somSelf;
  993. }
  994.  
  995. //------------------------------------------------------------------------------
  996. // CMDocument: AcquireDraft
  997. //------------------------------------------------------------------------------
  998.  
  999. SOM_Scope ODDraft*  SOMLINK CMDocumentAcquireDraft(CMDocument *somSelf, Environment *ev,
  1000.         ODDraftPermissions perms,
  1001.         ODDraftID id,
  1002.         ODDraft* draft,
  1003.         ODPositionCode posCode,
  1004.         ODBoolean release)
  1005. {
  1006.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1007.     CMDocumentMethodDebug("CMDocument","CMDocumentAcquireDraft");
  1008.  
  1009.     ODDraft*    newDraft;
  1010.  
  1011.      try
  1012.      {
  1013.  
  1014. #if ODDebug_Drafts
  1015.     somPrintf("&&& AcquireDraft: id %d draft %x posCode %d release %d\n", id, draft, posCode, release);
  1016. #endif
  1017.  
  1018.     VersionList*            versionList;
  1019.  
  1020.     versionList = somSelf->TestAndGetVersionList(ev);
  1021.     ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  1022.         
  1023.     
  1024.         newDraft = somSelf->AcquireDraftGut(ev, versionList, perms, id, (CMDraft*) draft, posCode, release);
  1025.         
  1026.         
  1027.     
  1028.     somSelf->ReleaseVersionList(ev);            
  1029.  
  1030. #if ODDebug_Drafts
  1031.     somPrintf("&&& Exiting AcquireDraft\n");
  1032. #endif
  1033.         
  1034.     }
  1035.     catch (ODException _exception)
  1036.     {
  1037.            newDraft = kODNULL;
  1038.       ODError error = ErrorCode();
  1039.       SaveEv();
  1040.       try
  1041.       {
  1042.        somSelf->ReleaseVersionList(ev);
  1043.       }
  1044.       catch (ODException _exception)
  1045.       {
  1046.           SetErrorCode(kODNoError);
  1047.       }
  1048.       RestoreEv();
  1049.       ODSetSOMException(ev, error);
  1050.  
  1051.       
  1052.     }
  1053.     return newDraft;
  1054. }
  1055.  
  1056. //------------------------------------------------------------------------------
  1057. // CMDocument: Exists
  1058. //------------------------------------------------------------------------------
  1059.  
  1060. SOM_Scope ODBoolean  SOMLINK CMDocumentExists(CMDocument *somSelf, Environment *ev,
  1061.         ODDraftID id,
  1062.         ODDraft* fromDraft,
  1063.         ODPositionCode posCode)
  1064. {
  1065.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1066.     CMDocumentMethodDebug("CMDocument","CMDocumentExists");
  1067.  
  1068.     ODBoolean    exists = kODFalse;
  1069.  
  1070.     try
  1071.     {
  1072.  
  1073.     
  1074.     if (id != 0) {
  1075.         exists = _fVersions->Exists(id);
  1076.     }
  1077.     else if (fromDraft != kODNULL) {
  1078.     
  1079.         VersionList* versionList = somSelf->TestAndGetVersionList(ev);
  1080.         ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  1081.         
  1082.         try
  1083.                 {
  1084.             ODDraftID    fromDraftID = fromDraft->GetID(ev);
  1085.     
  1086.             switch (posCode) {
  1087.                 case kODPosSame:
  1088.                     exists = kODTrue;
  1089.                 break;
  1090.                 case kODPosFirstBelow:
  1091.                 case kODPosLastBelow:
  1092.                     exists = versionList->PreviousDraftExists(fromDraftID);
  1093.                 break;
  1094.                 case kODPosFirstAbove:
  1095.                 case kODPosLastAbove:
  1096.                     exists = versionList->NextDraftExists(fromDraftID);
  1097.                 break;
  1098.                 case kODPosUndefined:
  1099.                 case kODPosAll:
  1100.                 case kODPosFirstSib:
  1101.                 case kODPosLastSib:
  1102.                 case kODPosNextSib:
  1103.                 case kODPosPrevSib:
  1104.                 default:
  1105.                     THROW(kODErrUnsupportedPosCode);
  1106.                 break;
  1107.             }
  1108.                 }
  1109.         catch(ODException _exception)
  1110.                 {
  1111.                    ODError  error = ErrorCode();
  1112.                    SaveEv();
  1113.                    try
  1114.                    {
  1115.             somSelf->ReleaseVersionList(ev);
  1116.                    }
  1117.                     catch(ODException _exception)
  1118.                    {
  1119.                            SetErrorCode(kODNoError);
  1120.                    }
  1121.                    RestoreEv();
  1122.                    ODSetSOMException(ev, error);
  1123.            throw;
  1124.             }        
  1125.     }
  1126.     else
  1127.         THROW(kODErrInsufficientInfoInParams);
  1128.     
  1129.     }
  1130.     catch (ODException _exception)
  1131.     {
  1132.     exists = kODFalse;
  1133.         ODSetSOMException(ev, _exception);
  1134.     }
  1135.     return exists;
  1136. }
  1137.  
  1138. //------------------------------------------------------------------------------
  1139. // CMDocument: AcquireBaseDraft
  1140. //------------------------------------------------------------------------------
  1141.  
  1142. SOM_Scope ODDraft*  SOMLINK CMDocumentAcquireBaseDraft(CMDocument *somSelf, Environment *ev,
  1143.         ODDraftPermissions perms)
  1144. {
  1145.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1146.     CMDocumentMethodDebug("CMDocument","CMDocumentAcquireBaseDraft");
  1147.  
  1148.     ODDraft*    baseDraft;
  1149.    try
  1150.    {
  1151.  
  1152.     CMContainer    cmContainer = _fContainer->GetCMContainer(ev);
  1153.     ODSessionMustHaveCMAllocReserve(cmContainer);
  1154.  
  1155.     ODDraftID    baseDraftID;
  1156.     CMProperty    versionListProp;
  1157.     CMObject    versionListObj;
  1158.     CMType        versionListType;
  1159.     CMValue        versionList;
  1160.     ODSByte    bogusData[1];
  1161.     
  1162.     if (somSelf->GetCMVersionList(ev) == kODNULL) {
  1163.         if ((versionListProp = CMRegisterProperty(cmContainer, kODPropVersionList)) == kODNULL)
  1164.             THROW(kODErrBentoInvalidProperty);
  1165.         if ((versionListType = CMRegisterType(cmContainer, kODVersionList)) == kODNULL)
  1166.             THROW(kODErrBentoInvalidType);
  1167.         if ((versionListObj = CMNewObject(cmContainer)) == kODNULL)
  1168.             THROW(kODErrBentoCannotNewObject);
  1169.         versionList = CMNewValue(versionListObj, versionListProp, versionListType);
  1170.  
  1171.         if (versionList != kODNULL)
  1172.             CMWriteValueData(versionList, bogusData, 0, 0);
  1173.         
  1174. #ifdef _PLATFORM_MACINTOSH_
  1175.         _fVersions = new(somSelf->GetHeap(ev)) VersionList();
  1176. #endif
  1177. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  1178. //        The use of heap is not implemented in Windows platform
  1179.         _fVersions = new VersionList();
  1180. #endif
  1181.         _fVersions->Initialize();
  1182.         
  1183.         baseDraft = somSelf->CreateDraft(ev, kODNULL, kODFalse);
  1184.     }
  1185.     else {
  1186.         baseDraftID = _fVersions->GetBaseDraftID();
  1187.         baseDraft = somSelf->AcquireDraft(ev, perms, baseDraftID, kODNULL, kODPosUndefined, kODFalse);
  1188.     }
  1189.     ODSessionRestoreCMAllocReserve(cmContainer);
  1190.  
  1191.     }
  1192.     catch (ODException _exception)
  1193.     {
  1194.       baseDraft = kODNULL;
  1195.           ODSetSOMException(ev, _exception);
  1196.     }
  1197.     return baseDraft;
  1198. }
  1199.  
  1200. //------------------------------------------------------------------------------
  1201. // CMDocument: CreateDraft
  1202. //------------------------------------------------------------------------------
  1203.  
  1204. SOM_Scope ODDraft*  SOMLINK CMDocumentCreateDraft(CMDocument *somSelf, Environment *ev,
  1205.         ODDraft* below,
  1206.         ODBoolean releaseBelow)
  1207. {
  1208.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1209.     CMDocumentMethodDebug("CMDocument","CMDocumentCreateDraft");
  1210.  
  1211.     CMDraft*    newDraft;
  1212.  
  1213.    try
  1214.    {
  1215.  
  1216. #if ODDebug_Drafts
  1217.     somPrintf("### Entering CreateDraft: below %x releaseBelow %d\n", below, releaseBelow);
  1218.     PrintDrafts(ev, _fDrafts, "### Entering CreateDraft");
  1219.     somSelf->GetVersionList(ev)->Print(">>> Entering CreateDraft");
  1220. #endif
  1221.     
  1222.     ODDraftID                    prevDraftID;
  1223.     VersionList*                versionList;
  1224.     
  1225.     versionList = somSelf->TestAndGetVersionList(ev);
  1226.     ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  1227.         
  1228.     try
  1229.         {
  1230.  
  1231.         prevDraftID = versionList->GetLatestDraftID();    
  1232.         if ((prevDraftID != 0) &&
  1233.             (below != kODNULL) &&
  1234.             (prevDraftID != below->GetID(ev)))
  1235.             THROW(kODErrInvalidBelowDraft);
  1236.     
  1237.         if (releaseBelow != kODFalse) {
  1238.             if (below != kODNULL) {
  1239.                 below->Release(ev);
  1240.             }
  1241.         }
  1242.         else {
  1243.             if ((below != kODNULL) && (below->GetPermissions(ev) == kODDPExclusiveWrite)) {
  1244.                 THROW(kODErrInvalidPermissions);
  1245.             }
  1246.         }
  1247.  
  1248.         newDraft = NewCMDraft(somSelf->GetHeap(ev));
  1249.         newDraft->InitDraft(ev, somSelf, kODNULL, kODDPExclusiveWrite);
  1250.     
  1251.         _fDrafts->Add(newDraft->GetID(ev), newDraft);
  1252.  
  1253.         }
  1254.     catch (ODException _exception)
  1255.         {
  1256.     
  1257.              ODError  error = ErrorCode();
  1258.             SaveEv();
  1259.             try
  1260.             {
  1261.         somSelf->ReleaseVersionList(ev);
  1262.             }
  1263.             catch (ODException _exception)
  1264.             {
  1265.                  SetErrorCode(kODNoError);
  1266.             }
  1267.              RestoreEv();
  1268.              ODSetSOMException(ev, error);
  1269.              throw;
  1270.         
  1271.     }
  1272.     
  1273.     somSelf->ReleaseVersionList(ev);            
  1274.     
  1275. #if ODDebug_Drafts
  1276.     PrintDrafts(ev, _fDrafts, "### Exiting CreateDraft");
  1277.     somSelf->GetVersionList(ev)->Print(">>> Exiting CreateDraft");
  1278. #endif
  1279.         
  1280.     }
  1281.     catch (ODException _exception)
  1282.     {
  1283.          newDraft = kODNULL;
  1284.          ODSetSOMException(ev, _exception);
  1285.     }
  1286.     return newDraft;
  1287. }
  1288.  
  1289. //------------------------------------------------------------------------------
  1290. // CMDocument: SaveToAPrevDraft
  1291. //------------------------------------------------------------------------------
  1292.  
  1293. SOM_Scope void  SOMLINK CMDocumentSaveToAPrevDraft(CMDocument *somSelf, Environment *ev,
  1294.         ODDraft* fromDraft,
  1295.         ODDraft* toDraft)
  1296. {
  1297.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1298.     CMDocumentMethodDebug("CMDocument","CMDocumentSaveToAPrevDraft");
  1299.  
  1300.     try
  1301.     {
  1302.  
  1303.     CMDraft*        from = (CMDraft*) fromDraft;
  1304.     ODDraftID        fromID; 
  1305.     ODDraftID        toID;
  1306.     VersionList*    versionList;
  1307.     ODBoolean        notTopDraft = kODFalse;
  1308.     ODTime            now;
  1309.     DraftListIterator*    draftList = kODNULL;
  1310.  
  1311.     versionList = somSelf->TestAndGetVersionList(ev);
  1312.     ASSERT((versionList != kODNULL), kODErrDraftDoesNotExist);
  1313.         
  1314.     try
  1315.         {
  1316.  
  1317.         if (!from)
  1318.             THROW(kODErrIllegalNullDraftInput);
  1319.         fromID = from->GetID(ev);
  1320.  
  1321.         if (toDraft == kODNULL) {
  1322.             toID = _fVersions->GetPreviousDraftID(fromID);
  1323.         }
  1324.         else {
  1325.             toID = toDraft->GetID(ev);
  1326.         }
  1327.             
  1328.         if (fromID == toID)
  1329.             return;
  1330.             
  1331.         if ((_fVersions->Exists(fromID) == kODFalse) ||
  1332.             (_fVersions->Exists(toID) == kODFalse) ||
  1333.             (versionList->IsAbove(fromID, toID) == kODFalse))
  1334.             THROW(kODErrDraftDoesNotExist);
  1335.         
  1336.         // Check to see whether we have any outstanding ODDraft associated
  1337.         //    with this document.
  1338.         
  1339. #ifdef _PLATFORM_MACINTOSH_
  1340.                          draftList = new(somSelf->GetHeap(ev)) DraftListIterator(_fDrafts);
  1341. #endif
  1342. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  1343. //        The use of heap is not implemented in Windows platform
  1344.             draftList = new DraftListIterator(_fDrafts);
  1345. #endif
  1346.         draftList->Initialize();
  1347.         
  1348.         CMDraft* draft = draftList->Last();
  1349.         while (draft != kODNULL) {
  1350.             ODDraftID    id = draft->GetID(ev);
  1351.             if ((versionList->IsBelow(id, fromID) != kODFalse) && 
  1352.                 (versionList->IsAbove(id, toID) != kODFalse) &&
  1353.                 (versionList->GetCurrentVersion(id) != kODTombstonedVersion))
  1354.                 THROW(kODErrOutstandingDraft);
  1355.             else
  1356.                 draft = draftList->Previous();
  1357.         }
  1358.         delete draftList;
  1359.     
  1360.         // SaveToAPrevDraft on VersionList
  1361.         
  1362.         _fVersions->SaveToAPrevDraft(fromID, toID);
  1363.         
  1364.         if (fromID != _fVersions->GetLatestDraftID())
  1365.             notTopDraft = kODTrue;
  1366.  
  1367. #if !TestFlushContainer
  1368.         // Make the version list change persistent
  1369.         
  1370.         somSelf->ExternalizeVersionList(ev, kODFalse);
  1371. #endif
  1372.         
  1373.         // Write out if it is an exclusive write container
  1374.         if (notTopDraft == kODFalse)    
  1375.             from->Close(ev);
  1376.  
  1377.         CMContainer    cmContainer = _fContainer->GetCMContainer(ev);
  1378.         
  1379. #if TestFlushContainer
  1380.  
  1381.         // Make the version list change persistent
  1382.         
  1383.         somSelf->ExternalizeVersionList(ev, notTopDraft);
  1384.         
  1385.         ODSessionMustHaveCMAllocReserve(cmContainer);
  1386.         CMTakeSnapShot(cmContainer, kODFalse);
  1387. #endif
  1388.         time(&now);
  1389.         ASSERTMSG(sizeof(ODTime)==sizeof(time_t), 
  1390.             kODErrAssertionFailed, 
  1391.             "ODTime not same as time_t.", 0);
  1392.  
  1393.         _fContainer->SetModDate(ev, now); 
  1394.  
  1395.         if (notTopDraft == kODFalse) { // if we have close it before we open it again
  1396.             from->Open(ev);
  1397.             
  1398.             from->SetChangedFromPrevFlag(ev, kODFalse);
  1399.         }        
  1400.         
  1401.         // Release to draft if necessary
  1402.         
  1403.         if (toDraft != kODNULL) {
  1404.             ((CMDraft*) toDraft)->Close(ev);
  1405.             ((CMDraft*) toDraft)->Open(ev);
  1406.         }
  1407.         ODSessionMustHaveCMAllocReserve(cmContainer);
  1408.         
  1409.         }
  1410.     catch (ODException _exception)
  1411.         {
  1412.             ODError error = ErrorCode();
  1413.             SaveEv();
  1414.             try
  1415.             {
  1416.                 ODDeleteObject(draftList);    
  1417.         somSelf->ReleaseVersionList(ev);
  1418.             }
  1419.             catch (ODException _exception)
  1420.             {
  1421.                   SetErrorCode(kODNoError);
  1422.             }
  1423.             RestoreEv();
  1424.         ODSetSOMException(ev, error);
  1425.         throw;
  1426.         
  1427.     }
  1428.     
  1429.     somSelf->ReleaseVersionList(ev);            
  1430.  
  1431.     }
  1432.     catch (ODException _exception)
  1433.     {
  1434.          ODSetSOMException(ev, _exception);
  1435.     }
  1436. }
  1437.  
  1438. //------------------------------------------------------------------------------
  1439. // CMDocument: SetBaseDraftFromForeignDraft
  1440. //------------------------------------------------------------------------------
  1441.  
  1442. SOM_Scope void  SOMLINK CMDocumentSetBaseDraftFromForeignDraft(CMDocument *somSelf, Environment *ev,
  1443.         ODDraft* draft)
  1444. {
  1445.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1446.     CMDocumentMethodDebug("CMDocument","CMDocumentSetBaseDraftFromForeignDraft");
  1447.  
  1448.  
  1449.      try
  1450.      {
  1451.  
  1452. #ifdef _NO_TMP_OBJS_
  1453.     ODDraft *baseDraft = somSelf->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  1454. #else
  1455.     TempODDraft baseDraft = somSelf->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  1456. #endif
  1457.     
  1458.     {
  1459. #ifdef _NO_TMP_OBJS_
  1460.         ODStorageUnit *fromDraftProperties = draft->AcquireDraftProperties(ev);
  1461.         ODStorageUnit *toDraftProperties = baseDraft->AcquireDraftProperties(ev);
  1462. #else
  1463.         TempODStorageUnit fromDraftProperties = draft->AcquireDraftProperties(ev);
  1464.         TempODStorageUnit toDraftProperties = baseDraft->AcquireDraftProperties(ev);
  1465. #endif
  1466.         
  1467.         ODDraftKey key = draft->BeginClone(ev, baseDraft, kODNULL, kODCloneAll); 
  1468.         try
  1469.                 {
  1470.             draft->Clone(ev, key, fromDraftProperties->GetID(ev), toDraftProperties->GetID(ev), kODNULL);
  1471.             draft->EndClone(ev, key );
  1472.                 }
  1473.         catch (ODException _exception)
  1474.                 {
  1475.                      ODError error = ErrorCode();
  1476.                      SaveEv();
  1477.                      try
  1478.                      {
  1479.             draft->AbortClone(ev, key);
  1480.                      }
  1481.                      catch (ODException _exception)
  1482.                      {
  1483.                          SetErrorCode(kODNoError);
  1484.                      }
  1485.                      RestoreEv();
  1486.                      ODSetSOMException(ev, error);
  1487.         }
  1488. #ifdef _NO_TMP_OBJS_
  1489.         fromDraftProperties->Release(ev);
  1490.         toDraftProperties->Release(ev);
  1491. #endif
  1492.         
  1493.     }
  1494.     baseDraft->Externalize(ev);
  1495. #ifdef _NO_TMP_OBJS_
  1496.     baseDraft->Release(ev);
  1497. #endif
  1498.  
  1499.      }
  1500.      catch (ODException _exception)
  1501.      {
  1502.            ODSetSOMException(ev, _exception);
  1503.      }
  1504. }
  1505.  
  1506. //------------------------------------------------------------------------------
  1507. // CMDocument: InitDocument
  1508. //------------------------------------------------------------------------------
  1509.  
  1510. SOM_Scope void  SOMLINK CMDocumentInitDocument(CMDocument *somSelf, Environment *ev,
  1511.         ODContainer* container,
  1512.         ODDocumentID id)
  1513. {
  1514.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1515.     CMDocumentMethodDebug("CMDocument","CMDocumentInitDocument");
  1516.     
  1517.      try
  1518.      {
  1519.         
  1520.     /* Moved from somInit. SOM itself sets fields to zero
  1521.     _fContainer = (ODBentoContainer*) kODNULL;
  1522.     _fID = 0;
  1523.     _fDrafts = kODNULL;
  1524.     _fReleasedDrafts = kODNULL;
  1525.     
  1526.     _fVersions = kODNULL;
  1527.     _fVersionListSemaphore = 0;
  1528.     
  1529.     _fHeap = kDefaultHeapID;
  1530.     */
  1531.     
  1532.     somSelf->InitRefCntObject(ev);
  1533.     
  1534.     _fContainer = (ODBentoContainer*) container;
  1535.     if (_fContainer == kODNULL)
  1536.         THROW(kODErrIllegalNullContainerInput);
  1537.  
  1538.     _fID = id;
  1539.         
  1540. #ifdef _PLATFORM_MACINTOSH_
  1541.     _fDrafts = new(somSelf->GetHeap(ev)) DraftList;
  1542. #endif
  1543. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  1544. //    The use of heap is not implemented in Windows platform
  1545.     _fDrafts = new DraftList;
  1546. #endif
  1547.     _fDrafts->Initialize();
  1548.     
  1549. #ifdef _PLATFORM_MACINTOSH_
  1550.     _fReleasedDrafts = new(somSelf->GetHeap(ev)) DraftList;
  1551. #endif
  1552. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  1553. //    The use of heap is not implemented in Windows platform
  1554.     _fReleasedDrafts = new DraftList;
  1555. #endif
  1556.     _fReleasedDrafts->Initialize();
  1557.     
  1558.     somSelf->InternalizeVersionList(ev);
  1559.  
  1560.     if (_fVersions == kODNULL) {
  1561.     
  1562.         // If we get here, that means we have a new document.
  1563.         // A new document makes a container dirty by definition. Therefore,
  1564.         // we have to set the dirty flag.
  1565.     
  1566.         _fContainer->SetDirtyFlag(ev, kODTrue);
  1567.         
  1568.         // We are not creating a VersionList yet because the user may
  1569.         // just close the document without creating any version.
  1570.     
  1571.     }
  1572.     
  1573.     _fHeap = _fContainer->GetHeap(ev);
  1574.     
  1575.      }
  1576.      catch (ODException _exception)
  1577.      {
  1578.           ODSetSOMException(ev, _exception);
  1579.      }
  1580. }
  1581.  
  1582. //------------------------------------------------------------------------------
  1583. // CMDocument: ReleaseDraft
  1584. //------------------------------------------------------------------------------
  1585.  
  1586. SOM_Scope ODDocument*  SOMLINK CMDocumentReleaseDraft(CMDocument *somSelf, Environment *ev,
  1587.         ODDraft* draftToRelease)
  1588. {
  1589.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1590.     CMDocumentMethodDebug("CMDocument","CMDocumentReleaseDraft");
  1591.  
  1592. #if ODDebug_Drafts
  1593.     somPrintf("@@@ ReleaseDraft: draft %x id %d\n", draftToRelease, draftToRelease->GetID(ev));
  1594.     PrintHeapInfo();
  1595. #endif
  1596.  
  1597.     CMDraft*        draft = (CMDraft*) draftToRelease;
  1598.     ODDraftID        draftID = draft->GetID(ev);
  1599.     
  1600.      try
  1601.      {
  1602.     if ((draft = _fDrafts->Get(draftID)) != kODNULL) {
  1603.         _fDrafts->Remove(draftID);
  1604.         _fReleasedDrafts->Add(draftID, draft);
  1605.         if (draft->GetPermissions(ev) == kODDPExclusiveWrite) {
  1606.             if (draft->NeedExternalizing(ev) != kODFalse) {
  1607.                 if (draft->ChangedFromPrev(ev) != kODFalse)
  1608.                     _fContainer->SetDirtyFlag(ev, kODTrue);
  1609.                 draft->Close(ev);
  1610. #if !TestFlushContainer
  1611.                 somSelf->ExternalizeVersionList(ev, kODFalse);
  1612. #endif
  1613.             }
  1614.             else if (draft->IsNewDraft(ev) != kODFalse) {
  1615.                 if (draft->GetID(ev) == _fVersions->GetBaseDraftID()) {
  1616.                     if (draft->ChangedFromPrev(ev) != kODFalse)
  1617.                         draft->RemoveChanges(ev);
  1618.                     draft->Close(ev);
  1619. #if !TestFlushContainer
  1620.                     somSelf->ExternalizeVersionList(ev, kODFalse);
  1621. #endif
  1622.                 }
  1623.                 else
  1624.                     draft->Abort(ev);
  1625.             }
  1626.             else
  1627.                 draft->Abort(ev);
  1628.         }
  1629.         else
  1630.             draft->Close(ev);
  1631.     }
  1632.     else
  1633.         THROW(kODErrDraftDoesNotExist);
  1634.  
  1635. #if ODDebug_Drafts
  1636.     somPrintf("@@@ ReleaseDraft: Done.\n");
  1637.     PrintHeapInfo();
  1638. #endif
  1639.      }
  1640.      catch (ODException _exception)
  1641.      {
  1642.           ODSetSOMException(ev, _exception);
  1643.      }
  1644.         
  1645.     return somSelf;
  1646. }
  1647.  
  1648. //------------------------------------------------------------------------------
  1649. // CMDocument: InternalizeVersionList
  1650. //------------------------------------------------------------------------------
  1651.  
  1652. SOM_Scope void  SOMLINK CMDocumentInternalizeVersionList(CMDocument *somSelf, Environment *ev)
  1653. {
  1654.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1655.     CMDocumentMethodDebug("CMDocument","CMDocumentInternalizeVersionList");
  1656.     ODPtr            tmpBuffer;
  1657.  
  1658.  
  1659.     try
  1660.     {
  1661.     ODULong        versionListSize;
  1662.     CMValue            versionList = somSelf->GetCMVersionList(ev);
  1663.     
  1664.     if (versionList == kODNULL)
  1665.         return;
  1666.  
  1667.     CMContainer    cmContainer = _fContainer->GetCMContainer(ev);
  1668.     ODSessionMustHaveCMAllocReserve(cmContainer);
  1669.  
  1670.     versionListSize = CMGetValueSize(versionList);
  1671.     
  1672.     tmpBuffer = ODNewPtr(versionListSize, somSelf->GetHeap(ev));
  1673.     
  1674.     CMReadValueData(versionList, tmpBuffer, 0, versionListSize);
  1675.     
  1676.     if (_fVersions == kODNULL) {
  1677. #ifdef _PLATFORM_MACINTOSH_
  1678.         _fVersions = new(somSelf->GetHeap(ev)) VersionList;
  1679. #endif
  1680. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  1681. //        The use of heap is not implemented in Windows platform
  1682.         _fVersions = new VersionList;
  1683. #endif
  1684.         _fVersions->Initialize(tmpBuffer, versionListSize);
  1685.     }
  1686.     else {
  1687.         _fVersions->Reinitialize(tmpBuffer, versionListSize);
  1688.     }
  1689.     
  1690.     ODDisposePtr(tmpBuffer);
  1691.  
  1692.     ODSessionRestoreCMAllocReserve(cmContainer);
  1693.     
  1694. #if ODDebug_Drafts
  1695.     _fVersions->Print("Internalized VersionList");
  1696. #endif
  1697.  
  1698.     }
  1699.     catch (ODException _exception)
  1700.     {
  1701.       if(tmpBuffer)
  1702.     ODDisposePtr(tmpBuffer);
  1703.         ODSetSOMException(ev, _exception);
  1704.     }
  1705. }
  1706.  
  1707. //------------------------------------------------------------------------------
  1708. // CMDocument: ExternalizeVersionList
  1709. //------------------------------------------------------------------------------
  1710.  
  1711. SOM_Scope void  SOMLINK CMDocumentExternalizeVersionList(CMDocument *somSelf, Environment *ev, ODBoolean ignoreTopDraft)
  1712. {
  1713.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1714.     CMDocumentMethodDebug("CMDocument","CMDocumentExternalizeVersionList");
  1715.  
  1716.     ODPtr            tmpBuffer = kODNULL;
  1717.  
  1718.     try
  1719.     {
  1720.  
  1721.     ODULong        tmpBufferSize;
  1722.     CMValue            versionList = somSelf->GetCMVersionList(ev);
  1723.  
  1724.     if (versionList == kODNULL)
  1725.         THROW(kODErrNoVersionList);
  1726.  
  1727.     if (_fVersions != kODNULL) {
  1728.         CMContainer    cmContainer = _fContainer->GetCMContainer(ev);
  1729.         ODSessionMustHaveCMAllocReserve(cmContainer);
  1730.  
  1731. #if ODDebug_Drafts
  1732.     _fVersions->Print("Externalizing VersionList");
  1733. #endif
  1734.         CMSize oldSize = CMGetValueSize(versionList);
  1735.  
  1736.         _fVersions->ExportTo(&tmpBuffer, &tmpBufferSize, ignoreTopDraft);
  1737.         
  1738.         CMWriteValueData(versionList, tmpBuffer, 0, tmpBufferSize);
  1739.         
  1740.         if (oldSize > tmpBufferSize)
  1741.             CMDeleteValueData(versionList, tmpBufferSize, oldSize - tmpBufferSize);
  1742.         
  1743.         ODDisposePtr(tmpBuffer);
  1744.         ODSessionRestoreCMAllocReserve(cmContainer);
  1745.         
  1746.     }
  1747.  
  1748.     }
  1749.     catch (ODException _exception)
  1750.     {
  1751.       if(tmpBuffer)
  1752.      ODDisposePtr(tmpBuffer);
  1753.          ODSetSOMException(ev, _exception);
  1754.     }
  1755. }
  1756.  
  1757. //------------------------------------------------------------------------------
  1758. // CMDocument: Reopen
  1759. //------------------------------------------------------------------------------
  1760.  
  1761. SOM_Scope void  SOMLINK CMDocumentReopen(CMDocument *somSelf, Environment *ev)
  1762. {
  1763.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1764.     CMDocumentMethodDebug("CMDocument","Reopen");
  1765.     DraftListIterator*        iter = kODNULL; 
  1766.  
  1767.    try
  1768.    {
  1769.  
  1770. #ifdef _PLATFORM_MACINTOSH_
  1771.          iter = new(somSelf->GetHeap(ev)) DraftListIterator(_fDrafts);
  1772. #endif
  1773. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  1774. //    The use of heap is not implemented in Windows platform
  1775.     iter = new DraftListIterator(_fDrafts);
  1776. #endif
  1777.     CMDraft*                draft;
  1778.  
  1779.     iter->Initialize();
  1780.     draft = iter->Last();
  1781.     while (draft != kODNULL) {
  1782.         draft->Open(ev);
  1783.         draft = iter->Previous();
  1784.     }
  1785.     delete iter;
  1786.  
  1787.    }
  1788.    catch (ODException _exception)
  1789.    {
  1790.         delete iter;
  1791.         ODSetSOMException(ev, _exception);
  1792.    }
  1793. }
  1794.  
  1795. //------------------------------------------------------------------------------
  1796. // CMDocument: GetVersionList
  1797. //------------------------------------------------------------------------------
  1798.  
  1799. SOM_Scope VersionList*  SOMLINK CMDocumentGetVersionList(CMDocument *somSelf, Environment *ev)
  1800. {
  1801.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1802.     CMDocumentMethodDebug("CMDocument","GetVersionList");
  1803.  
  1804.     return _fVersions;
  1805. }
  1806.  
  1807. //------------------------------------------------------------------------------
  1808. // CMDocument: TestAndGetVersionList
  1809. //------------------------------------------------------------------------------
  1810.  
  1811. SOM_Scope VersionList*  SOMLINK CMDocumentTestAndGetVersionList(CMDocument *somSelf, Environment *ev)
  1812. {
  1813.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1814.     CMDocumentMethodDebug("CMDocument","TestAndGetVersionList");
  1815.  
  1816.  
  1817.     VersionList *retVersion = kODNULL;
  1818.    try
  1819.    {
  1820.  
  1821.     DisableInterrupt();
  1822.  
  1823.     if (_fVersionListSemaphore > 0) {
  1824. //        if same thread,
  1825.             _fVersionListSemaphore++;
  1826. //         else {
  1827. //            EnableInterrupt();
  1828. //            THROW(kODErrVersionListUnavailable);
  1829. //
  1830.     }
  1831.     else {
  1832. //        store the thread
  1833.         _fVersionListSemaphore++;
  1834.     }
  1835.             
  1836.     EnableInterrupt();
  1837.  
  1838.     retVersion = _fVersions;
  1839.     }
  1840.     catch (ODException _exception)
  1841.     {
  1842.         ODSetSOMException(ev, _exception);
  1843.     }
  1844.  
  1845.     return retVersion;
  1846. }
  1847.  
  1848. //------------------------------------------------------------------------------
  1849. // CMDocument: ReleaseVersionList
  1850. //------------------------------------------------------------------------------
  1851.  
  1852. SOM_Scope void  SOMLINK CMDocumentReleaseVersionList(CMDocument *somSelf, Environment *ev)
  1853. {
  1854.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1855.     CMDocumentMethodDebug("CMDocument","ReleaseVersionList");
  1856.  
  1857.  
  1858.    try
  1859.    {
  1860.     DisableInterrupt();
  1861.     
  1862.     if (_fVersionListSemaphore > 0) {
  1863. //        if (same thread) {
  1864.             --_fVersionListSemaphore;
  1865.             EnableInterrupt();    
  1866. //        }
  1867. //        else {
  1868. //            EnableInterrupt();
  1869. //            THROW(kODErrVersionListUnavailable);
  1870. //        }
  1871.     }
  1872.     else {
  1873.         EnableInterrupt();    
  1874.         THROW(kODErrSemaphoreReleased);
  1875.     }
  1876.  
  1877.     }
  1878.     catch (ODException _exception)
  1879.     {
  1880.         ODSetSOMException(ev, _exception);
  1881.     }
  1882. }
  1883.  
  1884. //------------------------------------------------------------------------------
  1885. // CMDocument: GetHeap
  1886. //------------------------------------------------------------------------------
  1887.  
  1888. SOM_Scope ODMemoryHeapID  SOMLINK CMDocumentGetHeap(CMDocument *somSelf, Environment *ev)
  1889. {
  1890.     CMDocumentData *somThis = CMDocumentGetData(somSelf);
  1891.     CMDocumentMethodDebug("CMDocument","GetHeap");
  1892.  
  1893.     return _fHeap;
  1894. }
  1895.  
  1896. //------------------------------------------------------------------------------
  1897. // AcquireDocumentPropertiesObject
  1898. //------------------------------------------------------------------------------
  1899.  
  1900. static CMObject AcquireDocumentPropertiesObject(CMContainer container)
  1901. {
  1902.     CMObject        documentPropertiesObject  = kODNULL;
  1903.     Environment* ev = somGetGlobalEnvironment();
  1904.   try
  1905.   {
  1906.     CMProperty        docPropertiesProp;
  1907.     CMType            docPropertiesType;
  1908.     CMValue            value;
  1909.  
  1910.     // CMContainer    cmContainer = _fContainer->GetCMContainer(ev);
  1911.     // ODSessionMustHaveCMAllocReserve(cmContainer);
  1912.     // This is a static function which is only called by functions that
  1913.     // have already called ODSessionMustHaveCMAllocReserve().
  1914.  
  1915.     if ((docPropertiesProp = CMRegisterProperty(container, kODDocumentProperties)) == kODNULL)
  1916.         THROW(kODErrBentoInvalidProperty);
  1917.     documentPropertiesObject = CMGetNextObjectWithProperty(container, kODNULL, docPropertiesProp);
  1918.     
  1919.     if (documentPropertiesObject == kODNULL) {
  1920.  
  1921.         CMContainerModeFlags    openMode;
  1922.         
  1923.         CMGetContainerInfo(container, kODNULL, kODNULL, kODNULL, kODNULL, &openMode);
  1924.         if (openMode == kCMReading)
  1925.             return kODNULL;
  1926.         
  1927.         if ((docPropertiesType = CMRegisterType(container, kODValue)) == kODNULL)
  1928.             THROW(kODErrBentoInvalidProperty);
  1929.  
  1930.         if ((documentPropertiesObject = CMNewObject(container)) == kODNULL)
  1931.             THROW(kODErrBentoCannotNewObject);
  1932.             
  1933.         if ((value = CMNewValue(documentPropertiesObject, docPropertiesProp, docPropertiesType)) == kODNULL)
  1934.             THROW(kODErrBentoCannotNewValue);
  1935.             
  1936.         CMWriteValueData(value, "", 0, 0);
  1937.     }
  1938.     // ODSessionRestoreCMAllocReserve(cmContainer);
  1939.     }
  1940.     catch (ODException _exception)
  1941.     {
  1942.         ODSetSOMException(ev, _exception);
  1943.     }
  1944.     
  1945.     return documentPropertiesObject;
  1946. }
  1947.  
  1948. //------------------------------------------------------------------------------
  1949. // NewCMDraft
  1950. //------------------------------------------------------------------------------
  1951.  
  1952. static CMDraft* NewCMDraft(ODMemoryHeapID heapID)
  1953. {
  1954.          Environment* ev = somGetGlobalEnvironment();
  1955.      CMDraft*    cmDraft = kODNULL;
  1956.    try
  1957.    {
  1958. #ifdef _PLATFORM_MACINTOSH_
  1959.     SOMClass*    cmDraftClass = somNewClassReference(CMDraft);
  1960.     ODULong        size = cmDraftClass->somGetInstanceSize();
  1961.     ODPtr        buffer = ODNewPtr(size, heapID);
  1962.     CMDraft*    cmDraft = (CMDraft*) cmDraftClass->somRenew(buffer);
  1963.     somReleaseClassReference ( cmDraftClass );
  1964. #endif
  1965. #if defined(_PLATFORM_WIN32_) || defined (_PLATFORM_OS2_) || defined (_PLATFORM_AIX_)
  1966. //    The use of heap is not implemented in Windows platform
  1967.             cmDraft  = new CMDraft;
  1968. #endif
  1969.    }
  1970.    catch (ODException _exception)
  1971.    {
  1972.         ODDeleteObject(cmDraft);
  1973.         ODError  error = ErrorCode();
  1974.         ODSetSOMException(ev, error);
  1975.    }
  1976.     
  1977.     return cmDraft;
  1978. }
  1979.  
  1980. #if ODDebug_Drafts
  1981.  
  1982. //------------------------------------------------------------------------------
  1983. // PrintDrafts
  1984. //------------------------------------------------------------------------------
  1985.  
  1986. static void PrintDrafts(Environment* ev, DraftList* drafts, char* string)
  1987. {
  1988. /*
  1989.     DraftListIterator*    draftList = new DraftListIterator(drafts);
  1990.     draftList->Initialize();
  1991.     for (CMDraft* draft = draftList->Last(); draftList->IsNotComplete(); draft = draftList->Previous()) {
  1992.         somPrintf("%s: draft %x %d refCount %d\n", string, draft, draft->GetID(ev), draft->GetRefCount(ev));
  1993.     }
  1994.     delete draftList;
  1995. */
  1996. }
  1997.  
  1998. //------------------------------------------------------------------------------
  1999. // PrintHeapInfo
  2000. //------------------------------------------------------------------------------
  2001.  
  2002. static void PrintHeapInfo()
  2003. {
  2004. /*
  2005.     MemHeap*    heapID = 0;
  2006.     const char *name;
  2007.     size_t allocated;
  2008.     size_t free;
  2009.     size_t nBlocks;
  2010.     size_t nObjects;
  2011.     MMGetHeapInfo(heapID,
  2012.                     &name,
  2013.                     &allocated,
  2014.                     &free,
  2015.                     &nBlocks,
  2016.                     &nObjects );
  2017.     somPrintf("Heap: allocated %d, free %d, nBlocks %d, nObjects %d\n", allocated, free, nBlocks, nObjects);
  2018. */
  2019. }
  2020.  
  2021.  
  2022. #endif
  2023.  
  2024.  
  2025.