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

  1. /* @(#)Z 1.14 com/src/bento/EmbedCtr.cpp, odstorage, od96os2, odos29712d 97/03/21 17:19:17 (96/10/29 09:12:12) */
  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:        EmbedCtr.cpp
  31.  
  32.     Contains:    Implementation for ODEmbeddedContainer.
  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.         <27>    10/24/95    jpa        1293441: DM/VL: Bento memory reserve &
  41.                                     fatal container err.
  42.         <26>     10/8/95    TJ        Fixes Recomended by Refball
  43.         <25>     8/21/95    VL        1278330, 1278315: Error code cleanup.
  44.         <24>      8/3/95    RR        #1257260: Collapse B classes. Remove
  45.                                     somInit methods. Don't call IsInitialized
  46.                                     or SubclassResponsibility
  47.         <23>     7/21/95    VL        1270320: Dispose ba._buffer from
  48.                                     container->GetID. Dispose prevObjectName
  49.                                     when done. Delete _fHandlers in somUninit.
  50.         <22>     5/26/95    VL        1251403: Multithreading naming support.
  51.         <21>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  52.         <20>     4/25/95    VL        1210982: Removed 5$.
  53.         <19>     3/31/95    EL        1234685: Get merge target during open
  54.                                     rather than close, this would ensure
  55.                                     getting the right target and not some
  56.                                     corrrupted embedded container.
  57.         <18>     3/24/95    EL        1182275: We don't need to try to merge if
  58.                                     it is read only.
  59.         <17>      3/6/95    EL        1182275: We don't need
  60.                                     DraftPropertiesObject.
  61.         <16>     2/21/95    EL        1182275: Add SetDraftPropertiesObject and
  62.                                     call CMKeepObject with it before closing.
  63.         <15>     2/17/95    EL        1182275: Actually merge embedded
  64.                                     containers.
  65.         <14>     2/15/95    EL        1182275: Add private method SetMergeFlag.
  66.         <13>    11/14/94    VL        1188257: Use Bento errors in BenotDef.h.
  67.         <12>     11/1/94    VL        1151339: Preparation for MergeContainer.
  68.         <11>    10/19/94    VL        1155857: Commented out check for
  69.                                     cmContainer permission in Close. This
  70.                                     should fix "Cannot create  more than 10
  71.                                     drafts" problem.
  72.         <10>     9/23/94    VL        1184272: ContainerID is now a sequence of
  73.                                     octets. This affects EmbeddedContainers
  74.                                     also.
  75.          <9>     8/26/94    EL        #1182275 Include code (not yet active) for
  76.                                     merging of container.
  77.          <8>     8/10/94    NP        Added QDFixM.h.
  78.          <7>      8/5/94    VL        1171603: Use somSelf->GetCMSession instead
  79.                                     of depending on ODStorageSystem.
  80.          <6>      8/3/94    VL        1153123: Storage to ODStor.
  81.          <5>     7/11/94    VL        Fixed a bug in uninit. Close should not be
  82.                                     called on an Embedded Container. (Bug was
  83.                                     introduced during SOM conversion).
  84.          <4>      7/7/94    VL        Fixed the reversal of conditional in Abort
  85.                                     (this bug was introduced during the SOM
  86.                                     conversion).
  87.          <3>      7/5/94    VL        Added GetUseMode.
  88.          <2>      7/1/94    jpa        Fixed implicit casts from void*.
  89.          <1>     6/30/94    CC        first checked in
  90.          <0>     6/28/94    SV        SOMverted
  91.          <2>     4/13/94    VL        1157028: StorageM.h does not include
  92.                                     CMAPI.h anymore, so GetCMSession returns
  93.                                     ODULong.
  94.          <1>     3/24/94    VL        first checked in
  95.          <3>      3/1/94    JA        Moved string const here from .h file.
  96.                                     (1147295)
  97.          <2>     2/17/94    JA        Removed bogus quote in include statement.
  98.         <15>      2/8/94    VL        Correct capitalization and <> for includes.
  99.         <14>      2/8/94    VL        Use new exception macros.
  100.         <13>     1/19/94    EL        Use kCMNextGeneration when opening new
  101.                                     container for update.
  102.         <12>     1/12/94    VL        Init changes.
  103.         <11>     12/3/93    Té        Stop including ODError.h, it is included
  104.                                     as ErrorDef.h inside Except.h
  105.         <10>    11/23/93    VL        Made EmbeddedContainer pool-aware.
  106.          <9>      8/9/93    VL        Moved error code to ODError.h.
  107.          <8>     7/30/93    VL        ODContainerName* should be
  108.                                     ODContainerName.
  109.          <7>      7/6/93    VL        ODContainerName should be
  110.                                     ODContainerName*.
  111.          <6>     6/30/93    VL        Changed ODName to ODType.
  112.          <5>     6/30/93    VL        Removed ODDocument::Reopen in Abort() &
  113.                                     Close(). Open() checks for fContainer
  114.                                     instead of fUseMode.
  115.          <4>     6/22/93    VL        Used RefCount from ODRefCntObject. Added
  116.                                     Abort.
  117.          <3>     6/15/93    VL        Reopen drafts after Close.
  118.          <2>      6/1/93    VL        Changed open mode on CMOpenContainer in
  119.                                     Open.
  120.          <1>     5/27/93    VL        first checked in
  121.  
  122.     To Do:
  123.         Eliminate shouldMerge in containerID.
  124.     In Progress:
  125.         
  126. */
  127.  
  128. #ifdef _PLATFORM_MACINTOSH_
  129. #ifndef _QDFIXM_
  130. #include "QDFixM.h"
  131. #endif
  132. #endif
  133.  
  134. #ifndef _PLFMDEF_
  135. #include "PlfmDef.h"
  136. #endif
  137.  
  138. #if defined(_PLATFORM_WIN32_) || defined(_PLATFORM_OS2_) || defined(_PLATFORM_AIX_)
  139. #ifndef _ODDEBUG_
  140. #include <ODDebug.h>
  141. #endif
  142. #endif // _PLATFORM_WIN32_ _PLATFORM_OS2_ _PLATFORM_AIX_
  143.  
  144. #define ODEmbeddedContainer_Class_Source
  145. #define VARIABLE_MACROS
  146. #include <EmbedCtr.xih>
  147.  
  148. #ifndef SOM_ODRefCntObject_xh
  149. #include <RefCtObj.xh>
  150. #endif
  151.  
  152. #ifndef SOM_ODStorageSystem_xh
  153. #include <ODStor.xh>
  154. #endif
  155.  
  156. #ifndef _SESSHDR_
  157. #include "SessHdr.h"        // for sessionRoutinesMetahandler
  158. #endif
  159.  
  160. #ifndef _EMBEDHDR_
  161. #include "EmbedHdr.h"
  162. #endif
  163.  
  164. #ifndef _TARGTHDR_
  165. #include "TargtHdr.h"
  166. #endif
  167.  
  168. #ifndef __CM_API__
  169. #include "CMAPI.h"
  170. #endif
  171.  
  172. #ifndef _EXCEPT_
  173. #include "Except.h"
  174. #endif
  175.  
  176. #ifndef _INDHDR_
  177. #include "IndHdr.h"
  178. #endif
  179.  
  180. #ifndef _ODNEW_
  181. #include "ODNew.h"
  182. #endif
  183.  
  184. #ifndef __STRING__
  185. #include <string.h>        // for strlen
  186. #endif
  187.  
  188.  
  189.  
  190. //==============================================================================
  191. // Constants
  192. //==============================================================================
  193. const ODType kODEmbeddedContainerTypeName = "EmbedHdr";
  194.  
  195. #if ODDebug
  196. // #define ODDebug_EmbedCtr 1
  197. #endif
  198.  
  199. #pragma segment EmbedCtr
  200.  
  201. //==============================================================================
  202. // ODEmbeddedContainer
  203. //==============================================================================
  204.  
  205. //------------------------------------------------------------------------------
  206. // ODEmbeddedContainer: GetName
  207. //------------------------------------------------------------------------------
  208.  
  209. SOM_Scope ODContainerName  SOMLINK ODEmbeddedContainerGetName(ODEmbeddedContainer *somSelf, Environment *ev)
  210. {
  211.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  212.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetName");
  213.  
  214.     WARNMSG(WARN_INDEX(AMSG_680),"EmbeddedContainer does not have a name.");
  215.     
  216.     // The following two lines are used to pacify the compiler.
  217.     // They should never be executed.
  218.     ODIText    dummy;
  219.     return     dummy;
  220. }
  221.  
  222. //------------------------------------------------------------------------------
  223. // ODEmbeddedContainer: SetName
  224. //------------------------------------------------------------------------------
  225.  
  226. SOM_Scope void  SOMLINK ODEmbeddedContainerSetName(ODEmbeddedContainer *somSelf, Environment *ev,
  227.         ODContainerName* name)
  228. {
  229.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  230.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","SetName");
  231.  
  232.     // This function is an no-op.
  233. }
  234.  
  235. //------------------------------------------------------------------------------
  236. // ODEmbeddedContainer: AcquireDocument
  237. //------------------------------------------------------------------------------
  238.  
  239. SOM_Scope ODDocument*  SOMLINK ODEmbeddedContainerAcquireDocument(ODEmbeddedContainer *somSelf, Environment *ev,
  240.         ODDocumentID id)
  241. {
  242.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  243.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","AcquireDocument");
  244.  
  245. ODUnused(id);
  246.  
  247.     return kODNULL;
  248. }
  249.  
  250. //------------------------------------------------------------------------------
  251. // ODEmbeddedContainer: Release
  252. //------------------------------------------------------------------------------
  253.  
  254. SOM_Scope void  SOMLINK ODEmbeddedContainerRelease(ODEmbeddedContainer *somSelf, Environment *ev)
  255. {
  256.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  257.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Release");
  258.  
  259.     ODEmbeddedContainer_parent_ODBentoContainer_Release(somSelf, ev);
  260. }
  261.  
  262. //------------------------------------------------------------------------------
  263. // ODEmbeddedContainer: ~ODEmbeddedContainer
  264. //------------------------------------------------------------------------------
  265.  
  266. SOM_Scope void  SOMLINK ODEmbeddedContainersomUninit(ODEmbeddedContainer *somSelf)
  267. {
  268.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  269.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","somUninit");
  270.  
  271. #ifdef DebugRefCount
  272.     printf("~ODEmbeddedContainer %x CMContainer %x\n", somSelf, _fContainer);
  273.     fflush(stdout);
  274. #endif
  275.  
  276.     Environment* ev = somGetGlobalEnvironment ();
  277.     try
  278.     {
  279.  
  280. //    if (_fCMContainer != kODNULL)
  281. //        somSelf->Close(ev);
  282.  
  283.     if (_fHandlers != kODNULL)
  284.         delete _fHandlers;
  285.  
  286. //    Theoretically, we should not delete the ID because they should be able to 
  287. //    be reused.
  288. //
  289. //    ODContainerID id = somSelf->GetID(ev);
  290. //    if (id != kXMPNULL)
  291. //        delete id;
  292.  
  293.     ODEmbeddedContainer_parent_ODBentoContainer_somUninit(somSelf);
  294.     }
  295.     catch(ODException _exception)
  296.     {
  297.           ODSetSOMException(ev, _exception);
  298.     }
  299. }
  300.  
  301. //------------------------------------------------------------------------------
  302. // ODEmbeddedContainer: InitContainer
  303. //------------------------------------------------------------------------------
  304.  
  305. SOM_Scope void  SOMLINK ODEmbeddedContainerInitContainer(ODEmbeddedContainer *somSelf, Environment *ev,
  306.         ODStorageSystem* storage,
  307.         ODContainerID* id)
  308. {
  309.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  310.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","InitContainer");
  311.  
  312.         ODByteArray ba; 
  313.     try
  314.     {
  315.  
  316.     /* Moved from somInit. SOM itself sets fields to zero
  317.     _fCMContainer = kODNULL;
  318.     _fHandlers = kODNULL;
  319.     _fTargetValue = kODNULL;
  320.     */
  321.     _fUseMode = kCMReading;
  322.     _fShouldMerge = kODTrue;
  323.  
  324.     ODEmbeddedContainer_parent_ODBentoContainer_InitContainer(somSelf, ev, storage, id);
  325.  
  326.     
  327.     ba = somSelf->GetID(ev);
  328.     ODEmbeddedContainerID    containerID = *((ODEmbeddedContainerID*) ba._buffer);
  329. //    _fShouldMerge = containerID.shouldMerge;
  330. #ifdef _PLATFORM_MACINTOSH_
  331.     _fHandlers = new(somSelf->GetHeap(ev)) ODEmbeddedHandlers(somSelf->GetCMSession(ev),
  332.                                                                 containerID.cmValue);
  333. #endif
  334. #if defined(_PLATFORM_WIN32_)||defined(_PLATFORM_OS2_)||defined(_PLATFORM_AIX_)
  335. //    The use of heap is not implemented in Windows platform
  336.     _fHandlers = new ODEmbeddedHandlers(somSelf->GetCMSession(ev),
  337.                     containerID.cmValue);
  338. #endif
  339.     _fHandlers->Initialize();
  340.  
  341.     ODDisposePtr(ba._buffer);
  342.  
  343.      }
  344.      catch (ODException _exception)
  345.      {
  346.        if(ba._buffer)
  347.       ODDisposePtr(ba._buffer);
  348.          ODSetSOMException(ev, _exception);
  349.      }
  350.  
  351. }
  352.  
  353. //------------------------------------------------------------------------------
  354. // ODEmbeddedContainer: Create
  355. //------------------------------------------------------------------------------
  356.  
  357. SOM_Scope ODContainer*  SOMLINK ODEmbeddedContainerCreate(ODEmbeddedContainer *somSelf, Environment *ev)
  358. {
  359.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  360.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Create");
  361.  
  362.     try
  363.     {
  364.  
  365.     if (_fCMContainer == kODNULL) {
  366.  
  367.         CMSession cmSession = somSelf->GetCMSession(ev);
  368.         if (cmSession == kODNULL)
  369.             THROW(kODErrCannotCreateContainer);
  370.  
  371. //        ODType    prevObjectName = _fID->GetPrevObjectName();
  372.  
  373.         ODByteArray    ba = somSelf->GetID(ev);
  374.         CMValue cmValue = *((CMValue*) ba._buffer);
  375.         ODType prevObjectName = (ODType) CMGetValueRefCon(cmValue);
  376.         ODDisposePtr(ba._buffer);
  377.  
  378.         // Just to be safe, we are calling this even though we may have called this
  379.         // already for some other containers.
  380.         CMSetMetaHandler(cmSession,
  381.                         (CMGlobalName) CMTargetHandlersTypeName,
  382.                         targetContainerMetahandler);
  383.  
  384.         CMSetMetaHandler(cmSession, 
  385.                             kODIndirectValueGlobalName, 
  386.                             IndirectDynamicValueMetahandler);
  387.  
  388.         if (prevObjectName != kODNULL) {
  389. #if MergeContainersAvailable
  390.             CMValue             embeddedValue;
  391.             CMContainer            fileContainer;
  392.             CMObject            embeddedObject;
  393.             CMProperty            embeddedCntProp, targetObjectProp;
  394.             CMType                embeddedCntType;
  395.             CMObject            prevObject;
  396.             
  397.             _fCMContainer = CMOpenNewContainer(cmSession,
  398.                                         _fHandlers,
  399.                                         kODEmbeddedContainerTypeName,
  400.                                         (CMContainerUseMode) (kCMUpdateTarget+kCMMerging+kCMReuseFreeSpace),
  401.                                         kCMNextGeneration, kCMDefaultEndian,
  402.                                         prevObjectName);
  403.             if (_fCMContainer == kODNULL)
  404.                 THROW(kODErrCannotCreateContainer);
  405.             ODVolatile(embeddedObject);
  406.             ODVolatile(embeddedCntProp);
  407.             ODVolatile(embeddedCntType);
  408.             try
  409.                         {        
  410.                 ODSessionMustHaveCMAllocReserve(_fCMContainer);
  411.                 embeddedValue = _fHandlers->ReturnParentValueHandler();
  412.                 CMGetValueInfo(embeddedValue, &fileContainer, &embeddedObject, 
  413.                                 &embeddedCntProp, &embeddedCntType, kODNULL);
  414.                 targetObjectProp = CMRegisterProperty(fileContainer, prevObjectName);
  415.                 CMGetValueInfo(embeddedValue, &fileContainer, &embeddedObject, 
  416.                                 &embeddedCntProp, &embeddedCntType, NULL);
  417.                 prevObject = CMGetPrevObjectWithProperty(fileContainer, embeddedObject, embeddedCntProp);
  418.                 embeddedObject = CMGetPrevObjectWithProperty(fileContainer, embeddedObject, targetObjectProp);
  419.                 if (prevObject == embeddedObject)
  420.                     CMReleaseObject(prevObject);
  421.                 else {     /* we suspect this is garbage, check if we should delete it     */
  422.                     try
  423.                                         { /* if anything fails, garbage object is not deleted, big deal    */
  424.                         embeddedValue = CMUseValue(prevObject, embeddedCntProp, embeddedCntType);
  425.                         CMReleaseValue(embeddedValue);
  426.                         if (!CMContainsValidLabel(embeddedValue)) {
  427.                             CMReleaseObject(prevObject);
  428.                             CMDeleteObject(prevObject);
  429.                         }
  430.                         else
  431.                             CMReleaseObject(prevObject);
  432.                                         }
  433.                     catch (ODException _exception)
  434.                                         {
  435.                                             ODSetSOMException(ev, _exception);
  436.                                         }
  437.                 }
  438.                 embeddedValue = CMUseValue(embeddedObject, embeddedCntProp, embeddedCntType);
  439.                 ODSessionRestoreCMAllocReserve(_fCMContainer);
  440.                         }
  441.             catch (ODException _exception)
  442.                         {
  443.                 embeddedValue = kODNULL;
  444.                                 ODSetSOMException(ev, _exception);
  445.                         }
  446.             _fTargetValue = embeddedValue;
  447. #else
  448.             _fCMContainer = CMOpenNewContainer(cmSession,
  449.                                         _fHandlers,
  450.                                         kODEmbeddedContainerTypeName,
  451.                                         (CMContainerUseMode) (kCMUpdateTarget),
  452.                                         kCMNextGeneration, kCMDefaultEndian,
  453.                                         prevObjectName);
  454. #endif
  455.             _fUseMode = kCMUpdateTarget;
  456.             ODDisposePtr(prevObjectName);
  457.             CMSetValueRefCon(cmValue, kODNULL);
  458.         }
  459.         else {
  460.             _fCMContainer = CMOpenNewContainer(cmSession,
  461.                                         _fHandlers,
  462.                                         kODEmbeddedContainerTypeName,
  463.                                         (CMContainerUseMode) (kCMWriting),
  464.                                         kCMNextGeneration, kCMDefaultEndian);
  465.             _fUseMode = kCMWriting;
  466.         }
  467.         
  468.         if (_fCMContainer == kODNULL)
  469.             THROW(kODErrCannotCreateContainer);
  470.             
  471.     }
  472.  
  473.  
  474.      }
  475.      catch (ODException _exception)
  476.      {
  477.           ODSetSOMException(ev, _exception);
  478.      }
  479.     return somSelf;
  480. }
  481.  
  482. //------------------------------------------------------------------------------
  483. // ODEmbeddedContainer: Open
  484. //------------------------------------------------------------------------------
  485.  
  486. SOM_Scope ODContainer*  SOMLINK ODEmbeddedContainerOpen(ODEmbeddedContainer *somSelf, Environment *ev)
  487. {
  488.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  489.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Open");
  490.  
  491.    try
  492.    {
  493.  
  494.     if (_fCMContainer == kODNULL) {
  495.  
  496.         CMSession cmSession = somSelf->GetCMSession(ev);
  497.         if (cmSession == kODNULL)
  498.             THROW(kODErrCannotOpenContainer);
  499.  
  500.         // Just to be safe, we are calling this even though we may have called this
  501.         // already for some other containers.
  502.         CMSetMetaHandler(cmSession,
  503.                         (CMGlobalName) CMTargetHandlersTypeName,
  504.                         targetContainerMetahandler);
  505.  
  506.         CMSetMetaHandler(cmSession, 
  507.                             kODIndirectValueGlobalName, 
  508.                             IndirectDynamicValueMetahandler);
  509.  
  510.         _fCMContainer = CMOpenContainer(cmSession,
  511.                                         _fHandlers,
  512.                                         kODEmbeddedContainerTypeName,
  513.                                         (CMContainerUseMode)(kCMReading));
  514.  
  515.         ODSessionRestoreCMAllocReserve(_fCMContainer);
  516.         
  517.         if (_fCMContainer == kODNULL)
  518.             THROW(kODErrCannotOpenContainer);
  519.  
  520.         _fUseMode = kCMReading;
  521.     }
  522.         
  523.     }
  524.     catch (ODException _exception)
  525.     {
  526.         ODSetSOMException(ev, _exception);
  527.     }
  528.        
  529.     return somSelf;
  530. }
  531.  
  532. //------------------------------------------------------------------------------
  533. // ODEmbeddedContainer: Close
  534. //------------------------------------------------------------------------------
  535.  
  536. SOM_Scope ODContainer*  SOMLINK ODEmbeddedContainerClose(ODEmbeddedContainer *somSelf, Environment *ev)
  537. {
  538.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  539.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Close");
  540.     
  541.    try
  542.    {
  543.  
  544.     CMContainer cmContainer = somSelf->GetCMContainer(ev);
  545.     if (_fCMContainer != kODNULL) {
  546.             ODSessionMustHaveCMAllocReserve(_fCMContainer);
  547. //        if (_fUseMode != kCMReading) {
  548. #if MergeContainersAvailable
  549.             if (_fShouldMerge && (_fUseMode != kCMReading)) {
  550. #ifdef ODDebug_EmbedCtr
  551.     somPrintf("Closing EmbedCtr: Merge\n");
  552. #endif
  553.                 CMMergeContainer(_fCMContainer, _fTargetValue);
  554.             }
  555.             else {
  556. #ifdef ODDebug_EmbedCtr
  557.     somPrintf("Closing EmbedCtr: Close\n");
  558. #endif
  559.                 CMCloseContainer(_fCMContainer);
  560.             }
  561.             if (_fTargetValue) {
  562.                 CMReleaseValue(_fTargetValue);
  563.                 _fTargetValue = kODNULL;
  564.             }
  565.  
  566. #else
  567.             CMCloseContainer(_fCMContainer);
  568. #endif
  569.             _fCMContainer = kODNULL;
  570. //        }
  571.     }
  572.     
  573.         }
  574.     catch (ODException _exception)
  575.         {
  576.             ODSetSOMException(ev, _exception);
  577.         }
  578.     return somSelf;
  579. }
  580.  
  581. //------------------------------------------------------------------------------
  582. // ODEmbeddedContainer: Purge
  583. //------------------------------------------------------------------------------
  584.  
  585. SOM_Scope ODSize  SOMLINK ODEmbeddedContainerPurge(ODEmbeddedContainer *somSelf, Environment *ev,
  586.         ODSize size)
  587. {
  588.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  589.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Purge");
  590.  
  591.     return ODEmbeddedContainer_parent_ODBentoContainer_Purge(somSelf, ev, size);
  592. }
  593.  
  594. //------------------------------------------------------------------------------
  595. // ODEmbeddedContainer: ReleaseDocument
  596. //------------------------------------------------------------------------------
  597.  
  598. SOM_Scope ODContainer*  SOMLINK ODEmbeddedContainerReleaseDocument(ODEmbeddedContainer *somSelf, Environment *ev,
  599.         ODDocument* document)
  600. {
  601.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  602.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","ReleaseDocument");
  603.  
  604. ODUnused(document);
  605.  
  606.     return somSelf;
  607. }
  608.  
  609. //------------------------------------------------------------------------------
  610. // ODEmbeddedContainer: Abort
  611. //------------------------------------------------------------------------------
  612.  
  613. SOM_Scope ODContainer*  SOMLINK ODEmbeddedContainerAbort(ODEmbeddedContainer *somSelf, Environment *ev)
  614. {
  615.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  616.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","Abort");
  617.  
  618.  
  619.     CMSize valueSize;
  620.         ODByteArray ba;
  621.  
  622.     if (_fCMContainer != kODNULL) {
  623.         if (_fUseMode != kCMReading) {
  624.             try
  625.                         {
  626.                 ODSessionMustHaveCMAllocReserve(_fCMContainer);
  627.                 CMAbortContainer(_fCMContainer);
  628.                 
  629.                 // Trunc the value as Bento does not do it for us.
  630.                 ba = somSelf->GetID(ev);
  631.                 CMValue value = *((CMValue*) ba._buffer);
  632.                 ODDisposePtr(ba._buffer);
  633.                 valueSize = CMGetValueSize(value);
  634.                 CMDeleteValueData(value, 0, valueSize);
  635.                         }
  636.             catch (ODException _exception)
  637.                         {
  638.                           if(ba._buffer)
  639.                      ODDisposePtr(ba._buffer);
  640.                   ODSetSOMException(ev, _exception);
  641.                         }
  642.             _fCMContainer = kODNULL;
  643.         }
  644.     }
  645.     
  646.     return somSelf;
  647. }
  648.  
  649. //------------------------------------------------------------------------------
  650. // ODEmbeddedContainer: GetCMContainer
  651. //------------------------------------------------------------------------------
  652.  
  653. SOM_Scope CMContainer  SOMLINK ODEmbeddedContainerGetCMContainer(ODEmbeddedContainer *somSelf, Environment *ev)
  654. {
  655.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  656.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetCMContainer");
  657.  
  658.     return _fCMContainer;
  659. }
  660.  
  661. //------------------------------------------------------------------------------
  662. // ODEmbeddedContainer: GetHandlers
  663. //------------------------------------------------------------------------------
  664.  
  665. SOM_Scope ODBentoHandlers*  SOMLINK ODEmbeddedContainerGetHandlers(ODEmbeddedContainer *somSelf, Environment *ev)
  666. {
  667.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  668.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetHandlers");
  669.  
  670.     return _fHandlers;
  671. }
  672.  
  673. //------------------------------------------------------------------------------
  674. // ODEmbeddedContainer: GetUseMode
  675. //------------------------------------------------------------------------------
  676.  
  677. SOM_Scope CMContainerUseMode  SOMLINK ODEmbeddedContainerGetUseMode(ODEmbeddedContainer *somSelf, Environment *ev)
  678. {
  679.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  680.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","GetHandlers");
  681.  
  682.     return _fUseMode;
  683. }
  684.  
  685. //------------------------------------------------------------------------------
  686. // ODEmbeddedContainer: SetMergeFlag
  687. //------------------------------------------------------------------------------
  688.  
  689. SOM_Scope void  SOMLINK ODEmbeddedContainerSetMergeFlag(ODEmbeddedContainer *somSelf, Environment *ev,
  690.         ODBoolean flag)
  691. {
  692.     ODEmbeddedContainerData *somThis = ODEmbeddedContainerGetData(somSelf);
  693.     ODEmbeddedContainerMethodDebug("ODEmbeddedContainer","SetMergeFlag");
  694.  
  695.     _fShouldMerge = flag;
  696. }
  697.  
  698.