home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Storage / Bento / CMSU.cpp < prev    next >
Encoding:
Text File  |  1996-04-22  |  77.4 KB  |  2,595 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        CMSU.cpp
  3.  
  4.     Contains:    Implementation CMStorageUnit class.
  5.  
  6.     Owned by:    Vincent Lo
  7.  
  8.     Copyright:    © 1994 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <2>     3/29/96    DM        1296171: suppress fatal container error in
  13.                                     IsValidStorageUnitRef()
  14.         <53>    10/24/95    jpa        1293441: DM/VL: Bento memory reserve &
  15.                                     fatal container err & don't throw in
  16.                                     Release.
  17.         <52>    10/19/95    EL        1292685: After purging we may get a
  18.                                     different storage unit for the same
  19.                                     CMObject.
  20.         <51>     10/8/95    TJ        Fixes Recomended by Refball
  21.         <50>     10/3/95    TJ        Changes done by RefBall Team
  22.         <49>     9/29/95    TJ        Made Changes for MAC SOM
  23.         <48>     8/22/95    VL        1276990: Removed bogus THROW in
  24.                                     SetPromiseValue.
  25.         <47>     8/21/95    VL        1278330, 1278315: Error code cleanup.
  26.         <46>     8/17/95    VL        1266572: Added SOM_TRY and CATCH in
  27.                                     CountValues and fixed THROW in GetDraft.
  28.         <45>     8/16/95    VL        1266572: Added SOM_TRY and CATCH in
  29.                                     SetOffset and GetOffset.
  30.         <44>     8/12/95    TÇ        1276812 Need to use TempObjs and TempRefs
  31.                                     for exception safety and to avoid TRY
  32.                                     blocks, 1276807 Opt./Bug: use StdTypIO
  33.                                     routines for portable streaming & smaller
  34.                                     footprint, 1276806 Optimization: use
  35.                                     kODFalse instead of kODTrue in comparisons
  36.         <43>      8/8/95    EL        #1265282: GetStorageUnitRef does not check
  37.                                     for null. #1266000: Focus cannot be called
  38.                                     twice on the same value.
  39.         <42>      8/3/95    RR        #1257260: Collapse B classes. Remove
  40.                                     somInit methods. Don't call IsInitialized
  41.                                     or SubclassResponsibility
  42.         <41>     6/20/95    VL        Turned off debug code (accidentally left on
  43.                                     in the previous checkin.
  44.         <40>     6/16/95    VL        1259613: Changed CreateCursorXXX to allow
  45.                                     creation of cursor even when the su is
  46.                                     unfocused. Used PreserveFocus.
  47.         <39>     6/13/95    VL        1241352: Added modification date support
  48.                                     (mainly in SetChangedFromPrevFlag and
  49.                                     Externalize).
  50.         <38>     5/26/95    VL        1251403: Multithreading naming support.
  51.         <37>     5/25/95    jpa        Fixed usage of ODDebug. [1253321]
  52.         <36>     5/22/95    VL        1246940: Added more debug code.
  53.         <35>     5/19/95    VL        1249626: in length and out byteArray for
  54.                                     GetValue and GetPromiseValue.
  55.         <34>     5/11/95    EL        1242515: value not released in
  56.                                     GetObjectSize.
  57.         <33>      5/2/95    VL        1245113: RefCount check should not be used
  58.                                     for invariants.
  59.         <32>     4/25/95    VL        1210982: Removed 5$.
  60.         <31>     4/24/95    VL        1241729: Fixed backward iteration of SU
  61.                                     values.
  62.         <30>     4/11/95    VL        1236483: Fixed infinite cloning.
  63.         <29>     4/10/95    VL        1235948: Fixed crash for NULL input for
  64.                                     GetStorageUnitRef. 1236490: Made
  65.                                     GetPromiseValue work during FulfillPromise.
  66.         <28>     3/31/95    VL        1232945: Fixed leaking in CloneInto.
  67.         <27>     3/27/95    VL        1231412: Removed CopyTo.
  68.         <26>     3/19/95    VL        1228275: ASSERT if ODByteArray  is kODNULL.
  69.         <25>     3/14/95    VL        1225208,1225201: Added IsSettingPromise to
  70.                                     ensure that we don't call ResolvePromise
  71.                                     while setting a promise.
  72.         <24>     3/10/95    VL        1226116: No need to typecast for
  73.                                     SetStorageUnitRef.
  74.         <23>      3/9/95    VL        1225493: CloneInto should preserve the
  75.                                     focus. 1226082: Removed WASSERTM.
  76.         <22>     2/28/95    VL        1194656: Added checks for existing property
  77.                                     and value for AddProperty and AddValue.
  78.         <21>     2/21/95    EL        1182275: Do not throw if object cannot be
  79.                                     internalized (it probably was disposed in
  80.                                     garbage collection).
  81.         <20>     1/31/95    EL        1213321: Speed up focus and exist by using
  82.                                     CMUseValue.
  83.         <19>     1/26/95    VL        #???: SURef is now a 4-byte array.
  84.         <18>      1/9/95    VL        1183661: Use new SUCursor getters.
  85.         <17>    12/20/94    VL        1195012: Make Storage calls be
  86.                                     marshallable.
  87.         <16>     11/1/94    CC        1190911 - CloneInto(): Updated comment.
  88.         <15>     11/1/94    VL        1179951: Implemented Remove for all
  89.                                     Properties. 1194188: Implemented
  90.                                     unimplemented functions.
  91.         <14>     10/6/94    VL        1185112: Lock should not throw if the
  92.                                     storage unit is already locked.
  93.         <13>     9/29/94    RA        1189812: Mods for 68K build.
  94.         <12>     9/15/94    VL        1184871: In order to get cross-doc dad to
  95.                                     work, I need to fix Focus to correctly
  96.                                     focus to the value type first.
  97.         <11>      9/5/94    VL        1184871: Used Renew to remove dependency on
  98.                                     default heap.
  99.         <10>      9/1/94    VL        1183174: Removed Clone and GetClonedIDs.
  100.                                     1183054: Changed kODErrInvalidName to
  101.                                     kODErrInvalidProperty.
  102.          <9>     8/31/94    TÇ        #1183129, #1183116, #1183119, #1183111:
  103.                                     Lots of ErrorCode cleanup.
  104.          <8>     8/31/94    VL        1183174, 1106013: #ifdef ODDebug somPrintf
  105.                                     statements. Also, fixed GetName to return
  106.                                     kODNULL if there is no name.
  107.          <7>     8/26/94    VL        1183174: Implemented CloneInto and removed
  108.                                     CloneTo.
  109.          <6>     8/11/94    VL        1180299: Added CreateCursor and modified
  110.                                     CreateView.
  111.          <5>      8/3/94    VL        1153123: Storage to ODStor.
  112.          <4>     7/26/94    VL        Got rid of helper methods for promise
  113.                                     resolution. Instead, use PromiseResolver.
  114.          <3>     7/21/94    VL        Added WASSERTM at various places to check
  115.                                     for illegal sizes.
  116.          <2>      7/7/94    VL        Fixed up local variables in Focus.
  117.          <1>      7/5/94    VL        first checked in
  118.  
  119.     To Do:
  120.     In Progress:
  121.         
  122. */
  123.  
  124. #define CMStorageUnit_Class_Source
  125. #define VARIABLE_MACROS
  126. #include <CMSU.xih>
  127.  
  128. #ifndef SOM_CMStorageUnitRefIterator_xh
  129. #include <CMSURefI.xh>
  130. #endif
  131.  
  132. #ifndef _BENTODEF_
  133. #include "BentoDef.h"
  134. #endif
  135.  
  136. #ifndef SOM_ODStorageUnitCursor_xh
  137. #include <SUCursor.xh>
  138. #endif
  139.  
  140. #ifndef SOM_ODStorageUnitView_xh
  141. #include <SUView.xh>
  142. #endif
  143.  
  144. #ifndef SOM_CMDraft_xh
  145. #include <CMDraft.xh>
  146. #endif
  147.  
  148. #ifndef SOM_CMDocument_xh
  149. #include <CMDoc.xh>
  150. #endif
  151.  
  152. #ifndef SOM_CMCtr_xh
  153. #include <CMCtr.xh>
  154. #endif
  155.  
  156. #ifndef _DRAFPRIV_
  157. #include "DrafPriv.h"
  158. #endif
  159.  
  160. #ifndef __CM_API__
  161. #include "CMAPI.h"
  162. #endif
  163.  
  164. #ifndef _EXCEPT_
  165. #include "Except.h"
  166. #endif
  167.  
  168. #ifndef _AEHSHTBL_
  169. #include "AEHshTbl.h"
  170. #endif
  171.  
  172. #ifndef _ISOSTR_
  173. #include "ISOStr.h"
  174. #endif
  175.  
  176. #ifndef _TEMPOBJ_
  177. #include "TempObj.h"
  178. #endif
  179.  
  180. #ifndef _ODMEMORY_
  181. #include "ODMemory.h"
  182. #endif
  183.  
  184. #ifndef SOM_Module_OpenDoc_StdProps_defined
  185. #include <StdProps.xh>
  186. #endif
  187.  
  188. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  189. #include <StdTypes.xh>
  190. #endif
  191.  
  192. #ifndef SOM_ODStorageSystem_xh
  193. #include <ODStor.xh>
  194. #endif
  195.  
  196. #ifndef SOM_ODSession_xh
  197. #include <ODSessn.xh>
  198. #endif
  199.  
  200. #ifndef _PRMRSLVR_
  201. #include "PrmRslvr.h"
  202. #endif
  203.  
  204. #ifndef _SUREF_
  205. #include "SURef.h"
  206. #endif
  207.  
  208. #ifndef _SUCLONE_
  209. #include "SUClone.h"
  210. #endif
  211.  
  212. #ifndef _STORUTIL_
  213. #include <StorUtil.h>
  214. #endif
  215.  
  216. #ifndef __STDIO__
  217. #include <stdio.h>            // For sprintf
  218. #endif
  219.  
  220. #ifndef _ODDEBUG_
  221. #include "ODDebug.h"
  222. #endif
  223.  
  224. #ifndef _ODNEW_
  225. #include "ODNew.h"
  226. #endif
  227.  
  228. #ifndef _TIME
  229. #include <time.h>
  230. #endif
  231.  
  232. #ifndef _STDTYPIO_
  233. #include <StdTypIO.h>
  234. #endif
  235.  
  236. #ifndef _SESSHDR_
  237. #include "SessHdr.h"
  238. #endif
  239.  
  240. #pragma segment CMStorageUnit
  241.  
  242. #define USE_CLONEHELPER 1
  243.  
  244. //==============================================================================
  245. // Constants
  246. //==============================================================================
  247. #define kInitialHashTableEntries 8
  248. #define kHighBitMask    0x80000000
  249. #define kLowBitsMask    0x7FFFFFFF
  250.  
  251. #if ODDebug
  252. // #define ODDebug_ODStorageUnit 1
  253. #define ODDebug_AddProperty    1
  254. #define ODDebug_AddValue    1
  255. // #define ODDebug_SUCloneHelper    1
  256. #endif
  257.  
  258. //==============================================================================
  259. // Function Prototype
  260. //==============================================================================
  261.  
  262. static ODStorageUnitView* NewODStorageUnitView(ODMemoryHeapID heapID);
  263. static ODStorageUnitCursor* NewODStorageUnitCursor(ODMemoryHeapID heapID);
  264. static CMStorageUnitRefIterator*    NewCMStorageUnitRefIterator(ODMemoryHeapID heapID);
  265.  
  266. #define FailIfInvalidRefCount() ASSERTM(somSelf->GetRefCount(ev) != 0, kODErrZeroRefCount, "Invalid refCount")
  267. #define FailIfIllegalByteArray(value) ASSERT(value != kODNULL, kODErrIllegalNullInput)
  268.  
  269. inline void BREAK_AND_THROW(ODError err)
  270. {
  271. //    Debugger();
  272.     THROW(err);
  273. }
  274.  
  275. #define ODEnterCriticalSection()
  276. #define ODExitCriticalSection()
  277.  
  278. // Callers must call ODSessionMustHaveCMAllocReserve(container);
  279. static ODULong GetPropertySize(CMObject object, CMProperty property);
  280. static ODULong GetObjectSize(CMObject object);
  281.  
  282. //==============================================================================
  283. // CMStorageUnit
  284. //==============================================================================
  285.  
  286. //------------------------------------------------------------------------------
  287. // CMStorageUnit: AcquireDraft
  288. //------------------------------------------------------------------------------
  289.  
  290. SOM_Scope ODDraft*  SOMLINK CMStorageUnitGetDraft(CMStorageUnit *somSelf, Environment *ev)
  291. {
  292.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  293.     CMStorageUnitMethodDebug("CMStorageUnit","GetDraft");
  294.     
  295.     return _fDraft;
  296. }
  297.  
  298. //------------------------------------------------------------------------------
  299. // CMStorageUnit: Acquire
  300. //------------------------------------------------------------------------------
  301.  
  302. SOM_Scope void  SOMLINK CMStorageUnitAcquire(CMStorageUnit *somSelf, Environment *ev)
  303. {
  304.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  305.     CMStorageUnitMethodDebug("CMStorageUnit","Acquire");
  306.  
  307.     SOM_CATCH    return;
  308.  
  309.     parent_Acquire(somSelf, ev);
  310. }
  311.     
  312. //------------------------------------------------------------------------------
  313. // CMStorageUnit: Release
  314. //------------------------------------------------------------------------------
  315.  
  316. SOM_Scope void  SOMLINK CMStorageUnitRelease(CMStorageUnit *somSelf, Environment *ev)
  317. {
  318.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  319.     CMStorageUnitMethodDebug("CMStorageUnit","Release");
  320.  
  321.     SOM_TRY
  322.  
  323.     CMStorageUnit_parent_ODStorageUnit_Release(somSelf, ev);
  324.     if (somSelf->GetRefCount(ev) == 0) {
  325.         if (_fCurValue != kODNULL) {
  326.             CMContainer cmContainer = _fDraft->GetCMContainer(ev);
  327.             ODSessionMustHaveCMAllocReserve(cmContainer);
  328.             
  329.             CMReleaseValue(_fCurValue);
  330.             
  331.             _fCurValue = kODNULL;
  332.         }
  333.         _fCurProperty = kODNULL;
  334.         _fDraft->ReleaseStorageUnit(ev, _fID);
  335.     }
  336.         
  337.     SOM_CATCH_ALL
  338.     
  339.         ODError err = ErrorCode();
  340.  
  341.         WARN("Error occurred in ODStorageUnit::Release: %d %s", err, ErrorMessage());
  342.  
  343.         if (err == kODErrBentoErr)
  344.             SetErrorCode(kODErrFatalContainerError);
  345.         else if (err != kODErrFatalContainerError)
  346.             SetErrorCode(kODNoError);
  347.             
  348.     SOM_ENDTRY
  349. }
  350.  
  351. //------------------------------------------------------------------------------
  352. // CMStorageUnit: Purge
  353. //------------------------------------------------------------------------------
  354.  
  355. SOM_Scope ODSize SOMLINK CMStorageUnitPurge(CMStorageUnit *somSelf, Environment *ev,
  356.         ODSize size)
  357. {
  358.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  359.     CMStorageUnitMethodDebug("CMStorageUnit","Purge");
  360.  
  361.     ODULong    runningTotal = 0; ODVolatile( runningTotal );
  362.         
  363.     SOM_TRY
  364.  
  365.         ODBoolean hasReserve = kODFalse;
  366.         
  367.         if (_fCurValue != kODNULL) {
  368.             CMContainer cmContainer = _fDraft->GetCMContainer(ev);
  369.             ODSessionMustHaveCMAllocReserve(cmContainer);
  370.             hasReserve = kODTrue;
  371.             
  372.             CMReleaseValue(_fCurValue);
  373.             _fCurValue = kODNULL;
  374.         }
  375.         
  376.         _fCurProperty = kODNULL;
  377.         
  378.         if (_fObject != kODNULL) {
  379.         
  380.             IDList*    idList = ((CMDraft*) somSelf->GetDraft(ev))->GetIDList(ev);
  381.             ASSERT(idList != kODNULL, kODErrInvalidIDList);
  382.             
  383.             if (idList->Exists(_fID) == kODFalse) {
  384.                 if ( !hasReserve )
  385.                 {
  386.                     CMContainer cmContainer = _fDraft->GetCMContainer(ev);
  387.                     ODSessionMustHaveCMAllocReserve(cmContainer);
  388.                     hasReserve = kODTrue;
  389.                 }
  390.                 CMReleaseObject(_fObject);
  391.                 _fObject = kODNULL;
  392.             }
  393.         }
  394.  
  395.         // dh - call parent Purge method
  396.         runningTotal += parent_Purge(somSelf, ev, size);
  397.         
  398.     SOM_CATCH_ALL
  399.         WARN("Error %ld trying to purge in CMStorageUnitPurge",ErrorCode());
  400.         SetErrorCode(kODNoError);        // dh - Eat the exception; Purge should not 
  401.                                         // propagate it because clients function
  402.                                         // fine whether memory was purged or not.
  403.     SOM_ENDTRY
  404.  
  405.     
  406.     return runningTotal;
  407. }
  408.  
  409. //------------------------------------------------------------------------------
  410. // CMStorageUnit: Exists
  411. //------------------------------------------------------------------------------
  412.  
  413. SOM_Scope ODBoolean     SOMLINK CMStorageUnitExists(CMStorageUnit *somSelf, Environment *ev,
  414.         ODPropertyName propertyName,
  415.                                     ODValueType valueType, 
  416.                                     ODValueIndex valueIndex)
  417. {
  418.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  419.     CMStorageUnitMethodDebug("CMStorageUnit","Exists");
  420.  
  421.     SOM_CATCH    return kODFalse;
  422.  
  423.     CMContainer        container = somSelf->GetCMContainer(ev);
  424.     ODBoolean        propertyFound = kODFalse;
  425.     ODBoolean        valueFound = kODFalse;
  426.     CMProperty        targetProperty;
  427.     CMProperty        property;
  428.     CMType            targetType;
  429.     CMValue            value;
  430.     CMValue            tmpValue;
  431.     ODValueIndex    index;
  432.  
  433.     FailIfInvalidRefCount();
  434.     somSelf->Internalize(ev);
  435.         
  436.     if (_fObject == kODNULL)
  437.         return kODFalse;
  438.  
  439.     ODSessionMustHaveCMAllocReserve(container);
  440.  
  441.     if (propertyName != kODNULL) {
  442.         targetProperty = CMRegisterProperty(container, propertyName);
  443.         if (targetProperty == kODNULL)
  444.             BREAK_AND_THROW(kODErrIllegalPropertyName);
  445.     }
  446.     else
  447.         targetProperty = _fCurProperty;
  448.     
  449.     if (valueType != kODNULL) {
  450.         targetType = CMRegisterType(container, valueType);
  451.         if (targetType == kODNULL)
  452.             BREAK_AND_THROW(kODErrInvalidValueType);
  453.             
  454.         value = CMUseValue(_fObject, targetProperty, targetType);
  455.         if (value != kODNULL) {
  456.             CMReleaseValue(value);
  457.             valueFound = kODTrue;
  458.         }
  459.     }
  460.     else if (valueIndex > 0) {
  461.         index = 1;
  462.         value = CMGetNextValue(_fObject, targetProperty, kODNULL);
  463.         while ((value != kODNULL) && (index < valueIndex)) {
  464.             index++;
  465.             tmpValue = value;
  466.             value = CMGetNextValue(_fObject, targetProperty, tmpValue);
  467.             CMReleaseValue(tmpValue);
  468.         }
  469.         if (value != kODNULL) {
  470.             CMReleaseValue(value);
  471.             if (index == valueIndex)
  472.                 valueFound = kODTrue;
  473.         }
  474.     }
  475.     else {
  476.         if (propertyName != kODNULL) {
  477.             property = CMGetNextObjectProperty(_fObject, kODNULL);
  478.             while ((property != kODNULL) && (valueFound == kODFalse)) {
  479.                 if (targetProperty == property)
  480.                     valueFound = kODTrue;
  481.                 property = CMGetNextObjectProperty(_fObject, property);
  482.             }
  483.         }
  484.         else
  485.             valueFound = kODTrue;
  486.     }
  487.     ODSessionRestoreCMAllocReserve(container);
  488.  
  489.     return    valueFound;
  490. }
  491.  
  492. //------------------------------------------------------------------------------
  493. // CMStorageUnit: Exists
  494. //------------------------------------------------------------------------------
  495.  
  496. SOM_Scope ODBoolean     SOMLINK CMStorageUnitExistsWithCursor(CMStorageUnit *somSelf, Environment *ev,
  497.         ODStorageUnitCursor* cursor)
  498. {
  499.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  500.     CMStorageUnitMethodDebug("CMStorageUnit","ExistsWithCursor");
  501.  
  502.     SOM_CATCH    return kODFalse;
  503.  
  504.     ODPropertyName propertyName;
  505.     ODValueType    valueType;
  506.     ODValueIndex    valueIndex;
  507.     ODBoolean        exists;
  508.  
  509.     FailIfInvalidRefCount();
  510.     somSelf->Internalize(ev);
  511.     
  512.     cursor->GetProperty(ev, &propertyName);
  513.     cursor->GetValueType(ev, &valueType);
  514.     cursor->GetValueIndex(ev, &valueIndex);
  515.  
  516.     exists = somSelf->Exists(ev, propertyName, valueType, valueIndex);
  517.     
  518.     ODDisposePtr(propertyName);
  519.     ODDisposePtr(valueType);
  520.  
  521.     return exists;
  522. }
  523.  
  524. //------------------------------------------------------------------------------
  525. // CMStorageUnit: CountProperties
  526. //------------------------------------------------------------------------------
  527.  
  528. SOM_Scope ODULong     SOMLINK CMStorageUnitCountProperties(CMStorageUnit *somSelf, Environment *ev)
  529. {
  530.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  531.     CMStorageUnitMethodDebug("CMStorageUnit","CountProperties");
  532.  
  533.     SOM_CATCH    return 0;
  534.     
  535.     FailIfInvalidRefCount();
  536.     somSelf->Internalize(ev);
  537.  
  538.     CMContainer container = _fDraft->GetCMContainer(ev);
  539.     ODSessionMustHaveCMAllocReserve(container);
  540.     
  541.     return CMCountProperties(_fObject, kODNULL);
  542. }
  543.  
  544. //------------------------------------------------------------------------------
  545. // CMStorageUnit: CountValues
  546. //------------------------------------------------------------------------------
  547.  
  548. SOM_Scope ODULong     SOMLINK CMStorageUnitCountValues(CMStorageUnit *somSelf, Environment *ev)
  549. {
  550.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  551.     CMStorageUnitMethodDebug("CMStorageUnit","CountValues");
  552.     
  553.     ODULong numValues = 0;
  554.     
  555.     SOM_TRY
  556.     
  557.         FailIfInvalidRefCount();
  558.         somSelf->Internalize(ev);
  559.         
  560.         if (_fCurProperty == kODNULL)
  561.             THROW(kODErrUnfocusedStorageUnit);
  562.     
  563.         CMContainer container = _fDraft->GetCMContainer(ev);
  564.         ODSessionMustHaveCMAllocReserve(container);
  565.         
  566.         numValues = CMCountValues(_fObject, _fCurProperty, kODNULL);
  567.         
  568.     SOM_CATCH_ALL
  569.     SOM_ENDTRY
  570.     
  571.     return numValues;
  572. }
  573.         
  574. //------------------------------------------------------------------------------
  575. // CMStorageUnit: Focus
  576. //------------------------------------------------------------------------------
  577.  
  578. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitFocus(CMStorageUnit *somSelf, Environment *ev,
  579.         ODPropertyName propertyName,
  580.                                     ODPositionCode propertyPosCode,
  581.                                     ODValueType valueType,
  582.                                     ODValueIndex valueIndex,
  583.                                     ODPositionCode    valuePosCode)
  584. {
  585.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  586.     CMStorageUnitMethodDebug("CMStorageUnit","Focus");
  587.  
  588.     SOM_CATCH return somSelf;
  589.     
  590.     FailIfInvalidRefCount();
  591.     somSelf->Internalize(ev);
  592.     
  593.     CMProperty    property = _fCurProperty;
  594.     CMValue        value = _fCurValue;
  595.     
  596.     CMContainer container = _fDraft->GetCMContainer(ev);
  597.     ODSessionMustHaveCMAllocReserve(container);
  598.     
  599.     if (propertyName != kODNULL) {
  600.         property = CMRegisterProperty(container, propertyName);
  601.         if (property == kODNULL) {
  602. #ifdef ODDebug_ODStorageUnit
  603.     somPrintf("Error in Focus: ID %x PID %x propertyName %s\n", somSelf->GetID(ev), _fObjectID, propertyName);
  604. #endif
  605.             somSelf->CleanupAndFail(ev, kODErrIllegalPropertyName);
  606.         }
  607.     }
  608.     else {
  609.         _fHasPropertyLooped = propertyPosCode & kODPosMWrap;
  610.         switch (propertyPosCode) {
  611.             case kODPosUndefined:
  612.                 somSelf->CleanupAndFail(ev, kODErrUnsupportedPosCode);
  613.                 break;
  614.             case kODPosSame:
  615.                 break;
  616.             case kODPosAll:
  617.                 property = kODNULL;
  618.                 break;
  619.             case kODPosFirstSib:
  620.                 property = CMGetNextObjectProperty(_fObject, kODNULL);
  621.                 if (property == kODNULL)
  622.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  623.                 break;
  624.             case kODPosLastSib:
  625.                 property = CMGetPrevObjectProperty(_fObject, kODNULL);
  626.                 if (property == kODNULL)
  627.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  628.                 break;
  629.             case kODPosNextSib:
  630.                 property = CMGetNextObjectProperty(_fObject, property);
  631.                 if (property == kODNULL)
  632.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  633.                 break;
  634.             case kODPosPrevSib:
  635.                 property = CMGetPrevObjectProperty(_fObject, property);
  636.                 if (property == kODNULL)
  637.                     somSelf->CleanupAndFail(ev, kODErrPropertyDoesNotExist);
  638.                 break;
  639.             case kODPosFirstBelow:
  640.             case kODPosLastBelow:
  641.             case kODPosFirstAbove:
  642.             case kODPosLastAbove:
  643.             default:
  644.                 somSelf->CleanupAndFail(ev, kODErrUnsupportedPosCode);
  645.                 break;
  646.         }
  647.     }
  648.     
  649.     ODBoolean needReleaseValue = kODTrue;
  650.  
  651.     if (valueType != kODNULL) {
  652.         CMType type = kODNULL;
  653.         
  654.         CMType targetType = CMRegisterType(container, valueType);
  655.         
  656.         value = CMUseValue(_fObject, property, targetType);
  657.         if (value == kODNULL)
  658.             somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  659.             
  660.     } else if (valueIndex > 0) {
  661.         ODULong        i = 1;
  662.         CMValue        tmpValue;
  663.  
  664.         value = CMGetNextValue(_fObject, property, kODNULL);
  665.         while ((value != kODNULL) && (i < valueIndex)) {
  666.             tmpValue = value;
  667.             value = CMGetNextValue(_fObject, property, tmpValue);
  668.             CMReleaseValue(tmpValue);
  669.             i++;
  670.         }        
  671.         if (value == kODNULL)
  672.             somSelf->CleanupAndFail(ev, kODErrValueIndexOutOfRange);
  673.     }
  674.     else {
  675.         _fHasValueLooped = valuePosCode & kODPosMWrap;
  676.         switch (valuePosCode) {
  677.             case kODPosUndefined:
  678.                 value = kODNULL;
  679.             break;
  680.             case kODPosAll:
  681.                 value = kODNULL;
  682.                 break;
  683.             case kODPosFirstSib:
  684.                 value = CMGetNextValue(_fObject, property, kODNULL);
  685.                 if (value == kODNULL)
  686.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  687.                 break;
  688.             case kODPosNextSib:
  689.                 value = CMGetNextValue(_fObject, property, value);
  690.                 if (value == kODNULL)
  691.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  692.                 break;
  693.             case kODPosSame:
  694.                 needReleaseValue = kODFalse;
  695.                 break;
  696.             case kODPosLastSib:
  697.                 value = CMGetPrevValue(_fObject, property, kODNULL);
  698.                 if (value == kODNULL)
  699.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  700.                 break;
  701.             case kODPosPrevSib:
  702.                 value = CMGetPrevValue(_fObject, property, value);
  703.                 if (value == kODNULL)
  704.                     somSelf->CleanupAndFail(ev, kODErrSUValueDoesNotExist);
  705.                 break;
  706.             case kODPosFirstBelow:
  707.             case kODPosLastBelow:
  708.             case kODPosFirstAbove:
  709.             case kODPosLastAbove:
  710.             default:
  711.                 somSelf->CleanupAndFail(ev, kODErrUnsupportedPosCode);
  712.                 break;
  713.         }
  714.     }
  715.     
  716.     if (needReleaseValue != kODFalse) 
  717.         if (_fCurValue != kODNULL)
  718.             CMReleaseValue(_fCurValue);
  719.     
  720.     _fOffset = 0;
  721.     _fCurValue = value;
  722.     _fCurProperty = property;
  723.  
  724.     ODSessionRestoreCMAllocReserve(container);
  725.     
  726.     return somSelf;
  727. }
  728.  
  729. //------------------------------------------------------------------------------
  730. // CMStorageUnit: Focus
  731. //------------------------------------------------------------------------------
  732.  
  733. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitFocusWithCursor(CMStorageUnit *somSelf, Environment *ev,
  734.         ODStorageUnitCursor* suCursor)
  735. {
  736.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  737.     CMStorageUnitMethodDebug("CMStorageUnit","FocusWithCursor");
  738.     
  739.     SOM_CATCH return somSelf;
  740.     
  741.     ODPropertyName    propertyName;
  742.     ODValueType    valueType;
  743.     ODValueIndex    valueIndex;
  744.     
  745.     FailIfInvalidRefCount();
  746.     somSelf->Internalize(ev);
  747.  
  748.     if (suCursor == kODNULL)
  749.         BREAK_AND_THROW(kODErrIllegalNullSUCursorInput);
  750.  
  751.     suCursor->GetProperty(ev, &propertyName);
  752.     suCursor->GetValueType(ev, &valueType);
  753.     suCursor->GetValueIndex(ev, &valueIndex);
  754.     
  755.     somSelf->Focus(ev, propertyName,
  756.                 kODPosAll,
  757.                 valueType,
  758.                 valueIndex,
  759.                 kODPosAll);
  760.                 
  761.     if (propertyName != kODNULL)
  762.         ODDisposePtr(propertyName);
  763.         
  764.     if (valueType != kODNULL)
  765.         ODDisposePtr(valueType);
  766.     
  767.     return somSelf;
  768. }
  769.  
  770. //------------------------------------------------------------------------------
  771. // CMStorageUnit: Externalize
  772. //------------------------------------------------------------------------------
  773.  
  774. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitExternalize(CMStorageUnit *somSelf, Environment *ev)
  775. {
  776.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  777.     CMStorageUnitMethodDebug("CMStorageUnit","Externalize");
  778.  
  779.     SOM_CATCH    return somSelf;
  780.  
  781.     PreserveFocus    originalFocus(ev, somSelf);
  782.  
  783.     if (_fDirty) {    
  784.         somSelf->ResolveAllPromises(ev);
  785.     
  786.         if (_fSURefKeeper != kODNULL)
  787.             _fSURefKeeper->Externalize();
  788.         
  789.         if (somSelf->Exists(ev, kODPropModDate, kODTime_T, 0)) {
  790.             ODSetTime_TProp(ev, somSelf, kODPropModDate, kODTime_T, (ODTime) _fModificationDate);
  791.         }
  792.         
  793.         _fDirty = kODFalse;
  794.     }
  795.     return somSelf;
  796. }
  797.  
  798. //------------------------------------------------------------------------------
  799. // CMStorageUnit: Internalize
  800. //------------------------------------------------------------------------------
  801.  
  802. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitInternalize(CMStorageUnit *somSelf, Environment *ev)
  803. {
  804.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  805.     CMStorageUnitMethodDebug("CMStorageUnit","Internalize");
  806.  
  807.     SOM_CATCH    return somSelf;
  808.         
  809.     if (_fObject == kODNULL) {
  810.  
  811.         IDList*    idList = ((CMDraft*) somSelf->GetDraft(ev))->GetIDList(ev);
  812.         ASSERT(idList != kODNULL, kODErrInvalidIDList);
  813.                 
  814.         if (idList->Exists(_fID) != kODFalse) {            
  815.             _fObject = (CMObject) idList->Get(_fID);
  816.         }
  817.         else if (_fObjectID != kODNULL) {
  818.             CMContainer container = _fDraft->GetCMContainer(ev);
  819.             ODSessionMustHaveCMAllocReserve(container);
  820.             
  821.             _fObject = CMGetObject(container, _fObjectID);
  822.  
  823.             ODSessionRestoreCMAllocReserve(container);
  824.             
  825. //            if (_fObject == kODNULL)
  826. //                BREAK_AND_THROW(kODErrBentoCannotNewObject);
  827.             if (_fObject != kODNULL)
  828.                 idList->Add(_fID, _fObject);
  829.         }
  830.         else
  831.             BREAK_AND_THROW(kODErrInvalidStorageUnit);
  832.     }
  833.         
  834.     return somSelf;
  835. }
  836.  
  837. //------------------------------------------------------------------------------
  838. // CMStorageUnit: GetID
  839. //------------------------------------------------------------------------------
  840.  
  841. SOM_Scope ODStorageUnitID  SOMLINK CMStorageUnitGetID(CMStorageUnit *somSelf, Environment *ev)
  842. {
  843.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  844.     CMStorageUnitMethodDebug("CMStorageUnit","GetID");
  845.  
  846.     // Do not call fail if RefCount is zero because GetID can be called
  847.     // from Remove where RefCount MUST be zero -pjh
  848.     // FailIfInvalidRefCount();
  849.     
  850.     return _fID;
  851. }
  852.  
  853. //------------------------------------------------------------------------------
  854. // CMStorageUnit: GetName
  855. //------------------------------------------------------------------------------
  856.  
  857. SOM_Scope ODStorageUnitName  SOMLINK CMStorageUnitGetName(CMStorageUnit *somSelf, Environment *ev)
  858. {
  859.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  860.     CMStorageUnitMethodDebug("CMStorageUnit","GetName");
  861.     
  862.     SOM_CATCH    return kODNULL;
  863.     
  864.     FailIfInvalidRefCount();
  865.     return ODGetISOStrProp(ev, somSelf, kODPropStorageUnitName, kODISOStr, kODNULL, kODNULL);
  866. }
  867.     
  868. //------------------------------------------------------------------------------
  869. // CMStorageUnit: SetName
  870. //------------------------------------------------------------------------------
  871.  
  872. SOM_Scope void  SOMLINK CMStorageUnitSetName(CMStorageUnit *somSelf, Environment *ev,
  873.         ODStorageUnitName name)
  874. {
  875.     // CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  876.     CMStorageUnitMethodDebug("CMStorageUnit","SetName");
  877.  
  878.     SOM_CATCH    return;
  879.             
  880.     FailIfInvalidRefCount();
  881.         
  882.     ODSetISOStrProp(ev, somSelf, kODPropStorageUnitName, kODISOStr, name);
  883. }
  884.  
  885. //------------------------------------------------------------------------------
  886. // CMStorageUnit: AddProperty
  887. //------------------------------------------------------------------------------
  888.  
  889. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitAddProperty(CMStorageUnit *somSelf, Environment *ev,
  890.         ODPropertyName propertyName)    
  891. {
  892.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  893.     CMStorageUnitMethodDebug("CMStorageUnit","AddProperty");
  894.  
  895.     SOM_CATCH    return somSelf;
  896.  
  897. #ifdef ODDebug_ODStorageUnit
  898.     somPrintf("AddProperty %x %x %s\n", _fID, _fObjectID, propertyName);
  899. #endif
  900.     
  901.     CMContainer container = somSelf->GetCMContainer(ev);    
  902.     CMProperty    property = kODNULL;
  903.     
  904.     FailIfInvalidRefCount();
  905.     
  906.     somSelf->Internalize(ev);
  907.     
  908.     if (propertyName == kODNULL)
  909.         BREAK_AND_THROW(kODErrIllegalNullPropertyInput);
  910.     if (propertyName != kODNULL) {
  911.  
  912.         ODSessionMustHaveCMAllocReserve(container);
  913.         
  914.         property = CMRegisterProperty(container,propertyName);
  915.         if (property == kODNULL) {
  916.             somSelf->CleanupAndFail(ev, kODErrCannotAddProperty);
  917.         }
  918.         else {
  919.         
  920. #if ODDebug_AddProperty
  921.             CMProperty tmpProp = kODNULL;
  922.             do {
  923.                 ODSessionMustHaveCMAllocReserve(container); // safest once per loop
  924.                 tmpProp = CMGetNextObjectProperty(_fObject, tmpProp);
  925.             } while ((tmpProp != kODNULL) && (tmpProp != property));
  926.             
  927.             if (tmpProp == property) {
  928.                 WARN("Property exists already.");
  929.                 somPrintf("propertyName %s exists already.\n", propertyName);
  930.             }
  931. #endif
  932.  
  933.             if (_fCurValue != kODNULL) {
  934.                 CMReleaseValue(_fCurValue);
  935.                 _fCurValue = kODIDAll;
  936.             }
  937.             _fCurProperty = property;
  938.             somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  939.         }
  940.         ODSessionRestoreCMAllocReserve(container);
  941.     }
  942.     return somSelf;
  943. }
  944.  
  945.     
  946. //------------------------------------------------------------------------------
  947. // CMStorageUnit: AddValue
  948. //------------------------------------------------------------------------------
  949.  
  950. SOM_Scope ODStorageUnit*  SOMLINK CMStorageUnitAddValue(CMStorageUnit *somSelf, Environment *ev,
  951.         ODValueType type)
  952. {
  953.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  954.     CMStorageUnitMethodDebug("CMStorageUnit","AddValue");
  955.  
  956.     SOM_CATCH    return somSelf;
  957.  
  958.     CMContainer    container = somSelf->GetCMContainer(ev);
  959.     char*        dummyBuffer = "";
  960.     CMValue        value;
  961.     
  962.     FailIfInvalidRefCount();
  963.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  964.     
  965.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL))
  966.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  967.     if (type == kODNULL)
  968.         BREAK_AND_THROW(kODErrIllegalNullValueTypeInput);
  969.     else {
  970.         ODSessionMustHaveCMAllocReserve(container);
  971.  
  972.         _fCurType = CMRegisterType(container, type);
  973.         if (_fCurType == kODNULL)
  974.             BREAK_AND_THROW(kODErrInvalidValueType);
  975.         value = CMUseValue(_fObject, _fCurProperty, _fCurType);
  976.         if (value == kODNULL) {
  977.             value = CMNewValue(_fObject, _fCurProperty, _fCurType);
  978.             if (value == kODNULL)
  979.                 somSelf->CleanupAndFail(ev, kODErrBentoCannotNewValue);
  980.             CMWriteValueData(value, dummyBuffer, 0, 0);
  981.         }
  982. #if ODDebug_AddValue
  983.         else {
  984.             WARN("Value exists already.");
  985.             CMGlobalName propName = CMGetGlobalName(_fCurProperty);
  986.             somPrintf("Property %s Value %s exists already.\n", propName, type);
  987.         }
  988. #endif
  989.         if (_fCurValue != kODNULL)
  990.             CMReleaseValue(_fCurValue);
  991.         _fCurValue = value;
  992.         _fOffset = 0;
  993.  
  994.         ODSessionRestoreCMAllocReserve(container);
  995.     }
  996.     return somSelf;
  997. }
  998.  
  999. //------------------------------------------------------------------------------
  1000. // CMStorageUnit: Remove
  1001. //------------------------------------------------------------------------------
  1002.  
  1003. SOM_Scope ODStorageUnit*     SOMLINK CMStorageUnitRemove(CMStorageUnit *somSelf, Environment *ev)
  1004. {
  1005.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1006.     CMStorageUnitMethodDebug("CMStorageUnit","Remove");
  1007.  
  1008.     SOM_CATCH    return somSelf;
  1009.  
  1010.     FailIfInvalidRefCount();
  1011.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1012.  
  1013.     CMContainer container = _fDraft->GetCMContainer(ev);
  1014.     ODSessionMustHaveCMAllocReserve(container);
  1015.  
  1016.     if (_fCurValue != kODNULL) {
  1017.         if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1018.             _fPromiseResolver->ClearPromise(ev);
  1019.         CMDeleteValue(_fCurValue);
  1020.         _fCurValue = kODNULL;
  1021.     }
  1022.     else if (_fCurProperty != kODNULL) {
  1023.         CMDeleteObjectProperty(_fObject, _fCurProperty);
  1024.         _fCurProperty = kODNULL;
  1025.     }
  1026.     else {
  1027.         CMProperty curProperty = CMGetNextObjectProperty(_fObject, kODNULL);
  1028.         while (curProperty != kODNULL) {
  1029.             CMGlobalName name = CMGetGlobalName(curProperty);
  1030.             CMProperty property = curProperty;
  1031.             curProperty = CMGetNextObjectProperty(_fObject, curProperty);
  1032.             if (ODISOStrNCompare(name, kODBentoPrefix, ODISOStrLength(kODBentoPrefix)) != 0) {
  1033.                 CMDeleteObjectProperty(_fObject, property);
  1034.             }
  1035.         }
  1036.     }
  1037.     ODSessionRestoreCMAllocReserve(container);
  1038.     
  1039.     return somSelf;
  1040. }
  1041.  
  1042. //------------------------------------------------------------------------------
  1043. // CMStorageUnit: CloneInto
  1044. //------------------------------------------------------------------------------
  1045.  
  1046. SOM_Scope void  SOMLINK CMStorageUnitCloneInto(CMStorageUnit *somSelf, Environment *ev,
  1047.         ODDraftKey key, ODStorageUnit* toSU, ODID scopeID)
  1048. {
  1049.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1050.     CMStorageUnitMethodDebug("CMStorageUnit","CloneInto");
  1051.  
  1052.     SOM_CATCH return;
  1053.  
  1054. #ifdef USE_CLONEHELPER
  1055.     if (_fSUCloneHelper->ShouldClone(key, scopeID) != kODFalse) {
  1056. #endif
  1057. #ifdef ODDebug_SUCloneHelper
  1058.         somPrintf("Cloning %d in scope %d\n", somSelf->GetID(ev), scopeID);
  1059. #endif
  1060.  
  1061. #ifdef ODDebug_ODStorageUnit
  1062.     somPrintf("CMSU CloneInto: from %x %x to %x %x scope %x\n",
  1063.         _fID, _fObjectID, toSU->GetID(ev), ((CMStorageUnit*) toSU)->GetObjectID(ev), scopeID);
  1064. #endif
  1065.     
  1066.     if (((CMDraft*) somSelf->GetDraft(ev))->IsValidDraftKey(ev, key) == kODFalse)
  1067.         THROW(kODErrInvalidDraftKey);
  1068.  
  1069.     FailIfInvalidRefCount();
  1070.         
  1071.     ODULong            numProperties;
  1072.     ODULong            numValues;
  1073.     ODULong            i;
  1074.     ODULong            j;
  1075.     ODPropertyName    propertyName;
  1076.     CMGlobalName    typeName;
  1077.     ODULong            tmpSize;
  1078.     ODULong            size;
  1079.     ODPtr            buffer;
  1080.     ODStorageUnitCursor*    originalFocus = kODNULL;
  1081.     
  1082.     somSelf->Internalize(ev);
  1083.  
  1084.     if (_fCurProperty != kODNULL)
  1085.         originalFocus = somSelf->CreateCursorWithFocus(ev);
  1086.         
  1087.     somSelf->Focus(ev, (ODPropertyName) kODNULL, 
  1088.                             kODPosAll,
  1089.                             kODTypeAll,
  1090.                             0,
  1091.                             kODPosUndefined);
  1092.                             
  1093.     numProperties = somSelf->CountProperties(ev);
  1094.     
  1095.     for (i = 0; i < numProperties; i++) {
  1096.     
  1097.         somSelf->Focus(ev, (ODPropertyName) kODNULL,
  1098.                         kODPosNextSib,
  1099.                         kODTypeAll,
  1100.                         0,
  1101.                         kODPosUndefined);
  1102.     
  1103.         propertyName = somSelf->GetProperty(ev);
  1104.         
  1105. #if ODDebug_AddProperty
  1106.         if (toSU->Exists(ev, propertyName, kODNULL, 0) != kODFalse) {
  1107.             toSU->Focus(ev, propertyName, kODPosUndefined, kODNULL, 0, kODPosUndefined);
  1108.         }
  1109.         else
  1110.             toSU->AddProperty(ev, propertyName);
  1111. #else
  1112.         toSU->AddProperty(ev, propertyName);
  1113. #endif
  1114.     
  1115.         numValues = somSelf->CountValues(ev);    
  1116.         
  1117.         for (j = 0; j < numValues; j++) {
  1118.  
  1119.             somSelf->Focus(ev, (ODPropertyName) kODNULL,
  1120.                             kODPosSame,
  1121.                             kODNULL,
  1122.                             0,
  1123.                             kODPosNextSib);
  1124.  
  1125.             typeName = somSelf->GetType(ev);
  1126.             
  1127.             // Do no overrite existing values except for the storage unit type property.
  1128.             // New storage units are created with a generic storage unit type which should
  1129.             // be overwritten.  The link iterators currently use the storage unit type
  1130.             // property to identify link and linkSource storage units.
  1131.             if ((ODISOStrCompare(propertyName, (const ODISOStr) kODPropStorageUnitType) == 0)
  1132.                 || (toSU->Exists(ev, propertyName, typeName, 0) == kODFalse)) { 
  1133.  
  1134. #ifdef ODDebug_ODStorageUnit            
  1135.                 somPrintf("Copying from %x %x %s %s to %x %x\n", 
  1136.                     _fID, _fObjectID, propertyName, typeName, toSU->GetID(ev), ((CMStorageUnit*) toSU)->GetObjectID(ev));
  1137. #endif
  1138.  
  1139. #if ODDebug_AddValue
  1140.                 if (toSU->Exists(ev, propertyName, typeName, 0) != kODFalse) {
  1141.                     toSU->Focus(ev, propertyName, kODPosUndefined, typeName, 0, kODPosUndefined);
  1142.                 }
  1143.                 else
  1144.                     toSU->AddValue(ev, typeName);
  1145. #else                
  1146.                 toSU->AddValue(ev, typeName);
  1147. #endif
  1148.                 
  1149.                 tmpSize = toSU->GetSize(ev);
  1150.                 toSU->DeleteValue(ev, tmpSize);
  1151.                 
  1152.                 PreserveFocus* focus = new PreserveFocus(ev, somSelf);
  1153.                 size = somSelf->GetSize(ev);
  1154.                 delete focus;
  1155.                 numValues = somSelf->CountValues(ev);
  1156.                 numProperties = somSelf->CountProperties(ev);
  1157.                 
  1158.                 buffer = ODNewPtr(size, somSelf->GetHeap(ev));
  1159.                 StorageUnitGetValue(somSelf, ev, size, (ODValue) buffer);
  1160.                 StorageUnitSetValue(toSU, ev, size, (ODValue) buffer);
  1161.                 ODDisposePtr(buffer);
  1162.             }
  1163.             else {
  1164.                 toSU->Focus(ev, propertyName,
  1165.                             kODPosUndefined,
  1166.                             typeName,
  1167.                             0,
  1168.                             kODPosUndefined);
  1169.             }
  1170.             
  1171.             ODStorageUnitRefIterator*    iter;
  1172.             ODStorageUnitRef            ref;
  1173.  
  1174.             iter = somSelf->CreateStorageUnitRefIterator(ev);                
  1175.                 for(iter->First(ev, ref); iter->IsNotComplete(ev) != kODFalse; iter->Next(ev, ref)) {
  1176.                 if (somSelf->IsValidStorageUnitRef(ev, ref) != kODFalse) {                
  1177.                     ODStorageUnitID            toEmbeddedID = 0;
  1178.                     ODStorageUnitID            containingFrameID = 0;
  1179.                     ODBoolean                strongClone = somSelf->IsStrongStorageUnitRef(ev, ref);
  1180.                     ODStorageUnitID            fromEmbeddedID = somSelf->GetIDFromStorageUnitRef(ev, ref);
  1181.     
  1182.                     if (scopeID != 0) {
  1183.                         TempODStorageUnit fromEmbeddedSU = _fDraft->AcquireStorageUnit(ev, fromEmbeddedID);
  1184.                         if ((containingFrameID = ODGetWeakSURefProp(ev, fromEmbeddedSU, kODPropContainingFrame, kODWeakStorageUnitRef))
  1185.                             != kODNULLID)
  1186.                         {                                
  1187.                             if (containingFrameID == scopeID)
  1188.                                 scopeID = fromEmbeddedID;
  1189.                             else
  1190.                                 strongClone = kODFalse;
  1191.                         }
  1192.                     }
  1193.                     
  1194.                     if (strongClone != kODFalse) {
  1195. #ifdef ODDebug_ODStorageUnit
  1196.                         somPrintf("{{{ Strong Clone %x Begins\n", fromEmbeddedID);
  1197. #endif
  1198.                             toEmbeddedID = _fDraft->Clone(ev, key, fromEmbeddedID, 0, scopeID);
  1199. #ifdef ODDebug_ODStorageUnit
  1200.                         somPrintf("}}} Strong Clone %x Ends %x\n", fromEmbeddedID, toEmbeddedID);
  1201. #endif
  1202.                     }
  1203.                     else {
  1204. #ifdef ODDebug_ODStorageUnit
  1205.                         somPrintf("Begin Weak Clone from %x\n", fromEmbeddedID);
  1206. #endif
  1207.                             toEmbeddedID = _fDraft->WeakClone(ev, key, fromEmbeddedID, 0, scopeID);
  1208. #ifdef ODDebug_ODStorageUnit
  1209.                         somPrintf("End Weak Clone from %x %x to %x %x\n", fromEmbeddedID, toEmbeddedID);
  1210. #endif
  1211.                     }
  1212.                     if (toEmbeddedID != 0) {
  1213.     
  1214. #ifdef ODDebug_ODStorageUnit
  1215.     ODPropertyName    tmpPropertyName = somSelf->GetProperty(ev);
  1216.     ODValueType    tmpTypeName = somSelf->GetType(ev);
  1217.     ODPropertyName    tmpToPropertyName = toSU->GetProperty(ev);
  1218.     ODValueType    tmpToTypeName = toSU->GetType(ev);
  1219.     somPrintf("SetStorageUnitRef: FromID %x %s %s to toID %x %s %s\n",
  1220.                                                 fromEmbeddedID,
  1221.                                                 tmpPropertyName,
  1222.                                                 tmpTypeName,
  1223.                                                 toEmbeddedID,
  1224.                                                 tmpToPropertyName,
  1225.                                                 tmpToTypeName);
  1226.     ODDisposePtr(tmpPropertyName);
  1227.     ODDisposePtr(tmpTypeName);
  1228.     ODDisposePtr(tmpToPropertyName);
  1229.     ODDisposePtr(tmpToTypeName);
  1230. #endif
  1231.     
  1232.                         toSU->SetStorageUnitRef(ev, toEmbeddedID, ref);
  1233.                     }
  1234.                 }
  1235.             }
  1236.             delete iter;
  1237.  
  1238.             ODDisposePtr(typeName);
  1239.         }
  1240.         ODDisposePtr(propertyName);
  1241.     }
  1242.     
  1243.     if (originalFocus == kODNULL)
  1244.         somSelf->Focus(ev, kODNULL, kODPosAll, kODNULL, 0, kODPosAll);
  1245.     else {
  1246.         somSelf->FocusWithCursor(ev, originalFocus);
  1247.         delete originalFocus;
  1248.     }
  1249. #ifdef USE_CLONEHELPER
  1250.     }
  1251. #endif
  1252. #ifdef USE_CLONEHELPER
  1253. #ifdef ODDebug_SUCloneHelper
  1254.     else
  1255.         somPrintf("Not cloning %d in scope %d\n", somSelf->GetID(ev), scopeID);
  1256. #endif
  1257. #endif
  1258. }
  1259.  
  1260. //------------------------------------------------------------------------------
  1261. // CMStorageUnit: CreateView
  1262. //------------------------------------------------------------------------------
  1263.  
  1264. SOM_Scope ODStorageUnitView*     SOMLINK CMStorageUnitCreateView(CMStorageUnit *somSelf, Environment *ev)
  1265. {
  1266.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1267.     CMStorageUnitMethodDebug("CMStorageUnit","CreateView");
  1268.     
  1269.     SOM_CATCH    return kODNULL;
  1270.  
  1271.     ODStorageUnitView* suView = kODNULL;
  1272.  
  1273.     FailIfInvalidRefCount();
  1274.     
  1275.     ODStorageUnitCursor* cursor = somSelf->CreateCursorWithFocus(ev);
  1276.     
  1277.     suView = NewODStorageUnitView(somSelf->GetHeap(ev));
  1278.     suView->InitStorageUnitView(ev, somSelf, cursor);
  1279.  
  1280.     return suView;
  1281. }
  1282.  
  1283. //------------------------------------------------------------------------------
  1284. // CMStorageUnit: CreateCursor
  1285. //------------------------------------------------------------------------------
  1286.  
  1287. SOM_Scope ODStorageUnitCursor*  SOMLINK CMStorageUnitCreateCursor(CMStorageUnit *somSelf, Environment *ev,
  1288.         ODPropertyName propertyName,
  1289.         ODValueType valueType,
  1290.         ODValueIndex valueIndex)
  1291. {
  1292.     /*    CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf); */
  1293.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitCreateCursor");
  1294.     
  1295.     SOM_CATCH    return kODNULL;
  1296.     
  1297.     ODStorageUnitCursor*    suCursor = NewODStorageUnitCursor(somSelf->GetHeap(ev));
  1298.     suCursor->InitStorageUnitCursor(ev, propertyName, valueType, valueIndex);
  1299.     
  1300.     return suCursor;
  1301. }
  1302.  
  1303. //------------------------------------------------------------------------------
  1304. // CMStorageUnit: CreateCursorWithFocus
  1305. //------------------------------------------------------------------------------
  1306.  
  1307. SOM_Scope ODStorageUnitCursor*  SOMLINK CMStorageUnitCreateCursorWithFocus(CMStorageUnit *somSelf, Environment *ev)
  1308. {
  1309.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1310.     CMStorageUnitMethodDebug("CMStorageUnit","CreateCursorWithFocus");
  1311.  
  1312.     SOM_CATCH    return kODNULL;
  1313.  
  1314.     ODStorageUnitCursor*     suCursor = kODNULL;
  1315.     ODPropertyName            propertyName = kODNULL;
  1316.     ODValueType            valueType = kODNULL;
  1317.  
  1318.     FailIfInvalidRefCount();
  1319.     somSelf->Internalize(ev);
  1320.  
  1321.     if (_fCurProperty != kODNULL)
  1322.         propertyName = somSelf->GetProperty(ev);
  1323.     
  1324.     if (_fCurValue != kODNULL)
  1325.         valueType = somSelf->GetType(ev);
  1326.  
  1327.     suCursor = NewODStorageUnitCursor(somSelf->GetHeap(ev));
  1328.     suCursor->InitStorageUnitCursor(ev, propertyName, valueType, _fCurValueIndex);
  1329.     
  1330.     ODDisposePtr(propertyName);
  1331.     ODDisposePtr(valueType);
  1332.                         
  1333.     return suCursor;
  1334. }
  1335.  
  1336. //------------------------------------------------------------------------------
  1337. // CMStorageUnit: GetProperty
  1338. //------------------------------------------------------------------------------
  1339.  
  1340. SOM_Scope ODPropertyName  SOMLINK CMStorageUnitGetProperty(CMStorageUnit *somSelf, Environment *ev)
  1341. {
  1342.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1343.     CMStorageUnitMethodDebug("CMStorageUnit","GetProperty");
  1344.  
  1345.     SOM_CATCH    return kODNULL;
  1346.     
  1347.     CMGlobalName    tmp;
  1348.     ODPropertyName    propertyName = kODNULL;
  1349.  
  1350.     FailIfInvalidRefCount();
  1351.  
  1352.     if (_fCurProperty == kODNULL)
  1353.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1354.     
  1355.     // CMContainer container = _fDraft->GetCMContainer(ev);
  1356.     // ODSessionMustHaveCMAllocReserve(container);
  1357.     // CMIsProperty() and CMGetGlobalName() do not allocate memory.
  1358.  
  1359.     if (CMIsProperty(_fCurProperty)) {
  1360.         tmp = CMGetGlobalName(_fCurProperty);
  1361.         propertyName = ODISOStrFromCStr(tmp);
  1362.     }
  1363.     // ODSessionRestoreCMAllocReserve(container);
  1364.     
  1365.     return (propertyName);
  1366. }
  1367.  
  1368. //------------------------------------------------------------------------------
  1369. // CMStorageUnit: GetType
  1370. //------------------------------------------------------------------------------
  1371.  
  1372. SOM_Scope ODValueType  SOMLINK CMStorageUnitGetType(CMStorageUnit *somSelf, Environment *ev)
  1373. {
  1374.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1375.     CMStorageUnitMethodDebug("CMStorageUnit","GetType");
  1376.  
  1377.     SOM_CATCH    return kODNULL;
  1378.  
  1379.     CMType            type;
  1380.     CMGlobalName    tmp;
  1381.     ODValueType    typeName = kODNULL;
  1382.  
  1383.     FailIfInvalidRefCount();
  1384.  
  1385.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1386.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1387.     
  1388.     CMContainer container = _fDraft->GetCMContainer(ev);
  1389.     ODSessionMustHaveCMAllocReserve(container);
  1390.  
  1391.     CMGetValueInfo(_fCurValue, kODNULL, kODNULL, kODNULL, &type, kODNULL);
  1392.     
  1393.     if (CMIsType(type)) {
  1394.         tmp = CMGetGlobalName(type);
  1395.         typeName = ODISOStrFromCStr(tmp);
  1396.     }
  1397.     ODSessionRestoreCMAllocReserve(container);
  1398.     
  1399.     return (typeName);
  1400. }
  1401.  
  1402. //------------------------------------------------------------------------------
  1403. // CMStorageUnit: SetType
  1404. //------------------------------------------------------------------------------
  1405.  
  1406. SOM_Scope void  SOMLINK CMStorageUnitSetType(CMStorageUnit *somSelf, Environment *ev,
  1407.         ODValueType typeName)
  1408. {
  1409.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1410.     CMStorageUnitMethodDebug("CMStorageUnit","SetType");
  1411.  
  1412.     SOM_CATCH    return;
  1413.  
  1414.     CMContainer container = _fDraft->GetCMContainer(ev);
  1415.     CMType        type;
  1416.  
  1417.     FailIfInvalidRefCount();
  1418.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1419.     
  1420.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1421.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1422.         
  1423.     // CMContainer container = somSelf->GetCMContainer(ev);
  1424.     ODSessionMustHaveCMAllocReserve(container);
  1425.     
  1426.     type = CMRegisterType(container, (CMGlobalName) typeName);
  1427.     if (type != kODNULL)
  1428.         CMSetValueType(_fCurValue, type);
  1429.     else
  1430.         BREAK_AND_THROW(kODErrInvalidValueType);
  1431.  
  1432.     ODSessionRestoreCMAllocReserve(container);
  1433. }
  1434.  
  1435. //------------------------------------------------------------------------------
  1436. // CMStorageUnit: SetOffset
  1437. //------------------------------------------------------------------------------
  1438.  
  1439. SOM_Scope void  SOMLINK CMStorageUnitSetOffset(CMStorageUnit *somSelf, Environment *ev,
  1440.         ODULong offset)
  1441. {
  1442.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1443.     CMStorageUnitMethodDebug("CMStorageUnit","SetOffset");
  1444.  
  1445.     SOM_TRY
  1446.         FailIfInvalidRefCount();
  1447.         
  1448.         if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1449.             THROW(kODErrUnfocusedStorageUnit);
  1450.     
  1451.         _fOffset = offset;
  1452.     
  1453.     SOM_CATCH_ALL
  1454.     SOM_ENDTRY
  1455. }
  1456.  
  1457. SOM_Scope ODULong  SOMLINK CMStorageUnitGetOffset(CMStorageUnit *somSelf, Environment *ev)
  1458. {
  1459.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1460.     CMStorageUnitMethodDebug("CMStorageUnit","GetOffset");
  1461.  
  1462.     ODULong offset = 0;
  1463.     
  1464.     SOM_TRY
  1465.         FailIfInvalidRefCount();
  1466.         
  1467.         if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1468.             THROW(kODErrUnfocusedStorageUnit);
  1469.             
  1470.         offset = _fOffset;
  1471.         
  1472.     SOM_CATCH_ALL
  1473.     SOM_ENDTRY
  1474.     
  1475.     return offset;
  1476. }
  1477.  
  1478. //------------------------------------------------------------------------------
  1479. // CMStorageUnit: GetValue
  1480. //------------------------------------------------------------------------------
  1481.  
  1482. SOM_Scope ODULong  SOMLINK CMStorageUnitGetValue(CMStorageUnit *somSelf, Environment *ev,
  1483.         ODULong length,
  1484.         ODByteArray* value)
  1485. {
  1486.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1487.     CMStorageUnitMethodDebug("CMStorageUnit","GetValue");
  1488.  
  1489.     SOM_CATCH return 0;
  1490.     
  1491.     FailIfIllegalByteArray(value);
  1492.     FailIfInvalidRefCount();
  1493.     
  1494.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1495.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1496.     
  1497.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1498.         _fPromiseResolver->ResolvePromise(ev);
  1499.  
  1500.     value->_buffer = (octet*) ODNewPtr(length);
  1501.     value->_maximum = length;
  1502.     
  1503.     CMContainer container = _fDraft->GetCMContainer(ev);
  1504.     ODSessionMustHaveCMAllocReserve(container);
  1505.  
  1506.     value->_length = CMReadValueData(_fCurValue, (CMPtr) value->_buffer, _fOffset, length);
  1507.  
  1508.     ODSessionRestoreCMAllocReserve(container);
  1509.  
  1510.     _fOffset += value->_length;
  1511.  
  1512.     return value->_length;
  1513. }
  1514.  
  1515. //------------------------------------------------------------------------------
  1516. // CMStorageUnit: SetValue
  1517. //------------------------------------------------------------------------------
  1518.  
  1519. SOM_Scope void  SOMLINK CMStorageUnitSetValue(CMStorageUnit *somSelf, Environment *ev,
  1520.         ODByteArray* value)
  1521. {
  1522.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1523.     CMStorageUnitMethodDebug("CMStorageUnit","SetValue");
  1524.  
  1525.     SOM_CATCH    return;
  1526.     
  1527.     FailIfIllegalByteArray(value);
  1528.     FailIfInvalidRefCount();
  1529.     
  1530.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1531.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1532.  
  1533.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1534.         _fPromiseResolver->ResolvePromise(ev);
  1535.  
  1536.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1537.     
  1538.     CMContainer container = _fDraft->GetCMContainer(ev);
  1539.     ODSessionMustHaveCMAllocReserve(container);
  1540.  
  1541.     CMWriteValueData(_fCurValue, (CMPtr) value->_buffer, _fOffset, value->_length);
  1542.  
  1543.     ODSessionRestoreCMAllocReserve(container);
  1544.  
  1545.     _fOffset += value->_length;
  1546. }
  1547.  
  1548. //------------------------------------------------------------------------------
  1549. // CMStorageUnit: InsertValue
  1550. //------------------------------------------------------------------------------
  1551.  
  1552. SOM_Scope void  SOMLINK CMStorageUnitInsertValue(CMStorageUnit *somSelf, Environment *ev,
  1553.         ODByteArray* value)
  1554. {
  1555.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1556.     CMStorageUnitMethodDebug("CMStorageUnit","InsertValue");
  1557.  
  1558.     SOM_CATCH    return;
  1559.     FailIfIllegalByteArray(value);
  1560.     FailIfInvalidRefCount();
  1561.     
  1562.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1563.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1564.  
  1565.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1566.         _fPromiseResolver->ResolvePromise(ev);
  1567.  
  1568.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1569.  
  1570.     CMContainer container = _fDraft->GetCMContainer(ev);
  1571.     ODSessionMustHaveCMAllocReserve(container);
  1572.     
  1573.     CMInsertValueData(_fCurValue,(CMPtr)  value->_buffer, _fOffset, value->_length);
  1574.  
  1575.     ODSessionRestoreCMAllocReserve(container);
  1576.  
  1577.     _fOffset += value->_length;
  1578. }
  1579.  
  1580. //------------------------------------------------------------------------------
  1581. // CMStorageUnit: DeleteValue
  1582. //------------------------------------------------------------------------------
  1583.  
  1584. SOM_Scope void  SOMLINK CMStorageUnitDeleteValue(CMStorageUnit *somSelf, Environment *ev,
  1585.         ODULong length)
  1586. {
  1587.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1588.     CMStorageUnitMethodDebug("CMStorageUnit","DeleteValue");
  1589.  
  1590.     SOM_CATCH    return;
  1591.     FailIfInvalidRefCount();
  1592.     
  1593.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1594.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1595.  
  1596.     if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1597.         _fPromiseResolver->ResolvePromise(ev);
  1598.  
  1599.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1600.  
  1601.     CMContainer container = _fDraft->GetCMContainer(ev);
  1602.     ODSessionMustHaveCMAllocReserve(container);
  1603.     
  1604.     CMDeleteValueData(_fCurValue, _fOffset, length);
  1605.  
  1606.     ODSessionRestoreCMAllocReserve(container);
  1607. }
  1608.  
  1609. //------------------------------------------------------------------------------
  1610. // CMStorageUnit: GetSize
  1611. //------------------------------------------------------------------------------
  1612.  
  1613. SOM_Scope ODULong  SOMLINK CMStorageUnitGetSize(CMStorageUnit *somSelf, Environment *ev)
  1614. {
  1615.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1616.     CMStorageUnitMethodDebug("CMStorageUnit","GetSize");
  1617.  
  1618.     SOM_CATCH    return 0;
  1619.     ODULong    size = 0;
  1620.     
  1621.     FailIfInvalidRefCount();
  1622.     somSelf->Internalize(ev);
  1623.  
  1624.     CMContainer container = _fDraft->GetCMContainer(ev);
  1625.     ODSessionMustHaveCMAllocReserve(container);
  1626.     // GetPropertySize() and GetObjectSize() call CM methods
  1627.         
  1628.     if (_fCurValue != kODNULL) {
  1629.         if ((_fPromiseResolver != kODNULL) && (_fPromiseResolver->IsSettingPromise() == kODFalse))
  1630.             _fPromiseResolver->ResolvePromise(ev);
  1631.         
  1632.         size = CMGetValueSize(_fCurValue);
  1633.     }
  1634.     else if (_fCurProperty != kODNULL)
  1635.         size = GetPropertySize(_fObject, _fCurProperty);
  1636.     else
  1637.         size = GetObjectSize(_fObject);
  1638.  
  1639.     ODSessionRestoreCMAllocReserve(container);
  1640.         
  1641.     return size;
  1642. }
  1643.  
  1644. //------------------------------------------------------------------------------
  1645. // CMStorageUnit: GetStrongStorageUnitRef
  1646. //------------------------------------------------------------------------------
  1647.  
  1648. SOM_Scope void  SOMLINK CMStorageUnitGetStrongStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1649.         ODStorageUnitID embeddedSUID, ODStorageUnitRef ref)
  1650. {
  1651.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1652.     CMStorageUnitMethodDebug("CMStorageUnit","GetStrongStorageUnitRef");
  1653.  
  1654.     SOM_CATCH    return;
  1655.     
  1656.     somSelf->GetStorageUnitRef(ev, embeddedSUID, kODTrue, ref);
  1657. }
  1658.  
  1659. //------------------------------------------------------------------------------
  1660. // CMStorageUnit: GetWeakStorageUnitRef
  1661. //------------------------------------------------------------------------------
  1662.  
  1663. SOM_Scope void  SOMLINK CMStorageUnitGetWeakStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1664.         ODStorageUnitID embeddedSUID, ODStorageUnitRef ref)
  1665. {
  1666.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1667.     CMStorageUnitMethodDebug("CMStorageUnit","GetWeakStorageUnitRef");
  1668.  
  1669.     SOM_CATCH    return;
  1670.     
  1671.     somSelf->GetStorageUnitRef(ev, embeddedSUID, kODFalse, ref);
  1672. }
  1673.  
  1674. //------------------------------------------------------------------------------
  1675. // CMStorageUnit: IsValidStorageUnitRef
  1676. //------------------------------------------------------------------------------
  1677.  
  1678. extern ODBoolean gODSuppressBentoFatalError; // defined in SessHdr.cpp
  1679.  
  1680. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsValidStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1681.         ODStorageUnitRef ref)
  1682. {
  1683.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1684.     CMStorageUnitMethodDebug("CMStorageUnit","IsValidStorageUnitRef");
  1685.  
  1686.     ODBoolean oldSuppress = gODSuppressBentoFatalError;
  1687.     gODSuppressBentoFatalError = kODTrue;
  1688.  
  1689.     SOM_CATCH
  1690.     {
  1691.         gODSuppressBentoFatalError = oldSuppress; // neutral
  1692.         return kODFalse;
  1693.     }
  1694.     
  1695.     CMObject    object = kODNULL;
  1696.  
  1697.     FailIfInvalidRefCount();
  1698.     
  1699.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1700.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1701.     
  1702.     ODVolatile(object);
  1703.     TRY
  1704.         CMContainer container = _fDraft->GetCMContainer(ev);
  1705.         ODSessionMustHaveCMAllocReserve(container);
  1706.         
  1707.         object = CMGetReferencedObject(_fCurValue, ref);
  1708.         if (object != kODNULL)
  1709.             CMReleaseObject(object);
  1710.             
  1711.         ODSessionRestoreCMAllocReserve(container);
  1712.     CATCH_ALL
  1713.         object = kODNULL;
  1714.     ENDTRY
  1715.  
  1716.     gODSuppressBentoFatalError = oldSuppress; // neutral
  1717.     
  1718.     return (object != kODNULL);
  1719. }
  1720.  
  1721. //------------------------------------------------------------------------------
  1722. // CMStorageUnit: IsStrongStorageUnitRef
  1723. //------------------------------------------------------------------------------
  1724.  
  1725. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsStrongStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1726.         ODStorageUnitRef ref)
  1727. {
  1728.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1729.     CMStorageUnitMethodDebug("CMStorageUnit","IsStrongStorageUnitRef");
  1730.  
  1731.     return _fSURefKeeper->IsStrongSURef(ref);
  1732. }
  1733.  
  1734. //------------------------------------------------------------------------------
  1735. // CMStorageUnit: IsWeakStorageUnitRef
  1736. //------------------------------------------------------------------------------
  1737.  
  1738. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsWeakStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1739.         ODStorageUnitRef ref)
  1740. {
  1741.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1742.     CMStorageUnitMethodDebug("CMStorageUnit","IsWeakStorageUnitRef");
  1743.  
  1744.     return _fSURefKeeper->IsWeakSURef(ref);
  1745. }
  1746.  
  1747. //------------------------------------------------------------------------------
  1748. // CMStorageUnit: RemoveStorageUnitRef
  1749. //------------------------------------------------------------------------------
  1750.  
  1751. SOM_Scope ODStorageUnit*  SOMLINK CMStorageUnitRemoveStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1752.         ODStorageUnitRef ref)
  1753. {
  1754.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1755.     CMStorageUnitMethodDebug("CMStorageUnit","RemoveStorageUnitRef");
  1756.  
  1757.     SOM_CATCH    return somSelf;
  1758.     FailIfInvalidRefCount();
  1759.  
  1760.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1761.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1762.  
  1763.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1764.  
  1765.     CMContainer container = _fDraft->GetCMContainer(ev);
  1766.     ODSessionMustHaveCMAllocReserve(container);
  1767.         
  1768.     CMDeleteReference(_fCurValue, ref);
  1769.                     
  1770.     ODSessionRestoreCMAllocReserve(container);
  1771.     
  1772.     return somSelf;
  1773. }
  1774.  
  1775. //------------------------------------------------------------------------------
  1776. // CMStorageUnit: GetIDFromStorageUnitRef
  1777. //------------------------------------------------------------------------------
  1778.  
  1779. SOM_Scope ODStorageUnitID  SOMLINK CMStorageUnitGetIDFromStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  1780.         ODStorageUnitRef ref)
  1781. {
  1782.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1783.     CMStorageUnitMethodDebug("CMStorageUnit","GetIDFromStorageUnitRef");
  1784.  
  1785.     SOM_CATCH    return 0;
  1786.     FailIfInvalidRefCount();
  1787.     
  1788.     CMObject    object;
  1789.     
  1790.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1791.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1792.  
  1793.     CMContainer container = _fDraft->GetCMContainer(ev);
  1794.     ODSessionMustHaveCMAllocReserve(container);
  1795.     
  1796.     TRY
  1797.         object = CMGetReferencedObject(_fCurValue, ref);
  1798.     CATCH_ALL
  1799.         BREAK_AND_THROW(kODErrInvalidStorageUnitRef);
  1800.     ENDTRY
  1801.     
  1802.     if (object == kODNULL)
  1803.         BREAK_AND_THROW(kODErrInvalidStorageUnitRef);
  1804.         
  1805.     ODID    id = 0;
  1806.     IDList*    idList = ((CMDraft*) somSelf->GetDraft(ev))->GetIDList(ev);
  1807.     ASSERT(idList != kODNULL, kODErrInvalidIDList);
  1808.  
  1809.     if (idList->ObjectExists(object) != kODFalse) {
  1810.         id = idList->GetID(object);
  1811.         CMReleaseObject(object);
  1812.     }
  1813.     else {
  1814.         id = idList->Add(object);
  1815.     }
  1816.     ODSessionRestoreCMAllocReserve(container);
  1817.     
  1818.     return id;
  1819. }
  1820.  
  1821. //------------------------------------------------------------------------------
  1822. // CMStorageUnit: CreateStorageUnitRefIterator
  1823. //------------------------------------------------------------------------------
  1824.  
  1825. SOM_Scope ODStorageUnitRefIterator*  SOMLINK CMStorageUnitCreateStorageUnitRefIterator(CMStorageUnit *somSelf, Environment *ev)
  1826. {
  1827.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1828.     CMStorageUnitMethodDebug("CMStorageUnit","CrateStorageUnitRefIterator");
  1829.  
  1830.     SOM_CATCH    return kODNULL;
  1831.     FailIfInvalidRefCount();
  1832.  
  1833.     CMStorageUnitRefIterator*    iter = NewCMStorageUnitRefIterator(somSelf->GetHeap(ev));
  1834.     iter->InitStorageUnitRefIterator(ev, somSelf);
  1835.  
  1836.     return iter;
  1837. }
  1838.  
  1839. //------------------------------------------------------------------------------
  1840. // CMStorageUnit: GetGenerationNumber
  1841. //------------------------------------------------------------------------------
  1842.  
  1843. SOM_Scope ODULong  SOMLINK CMStorageUnitGetGenerationNumber(CMStorageUnit *somSelf, Environment *ev)
  1844. {
  1845.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1846.     CMStorageUnitMethodDebug("CMStorageUnit","GetGenerationNumber");
  1847.  
  1848.     SOM_CATCH    return 0;
  1849.     FailIfInvalidRefCount();
  1850.     
  1851.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1852.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1853.         
  1854.     ODULong    generation = 0;
  1855.  
  1856.     CMContainer container = _fDraft->GetCMContainer(ev);
  1857.     ODSessionMustHaveCMAllocReserve(container);
  1858.  
  1859.     CMGetValueInfo(_fCurValue, kODNULL, kODNULL, kODNULL, kODNULL, &generation);
  1860.     
  1861.     ODSessionRestoreCMAllocReserve(container);
  1862.  
  1863.     return generation;
  1864. }
  1865.  
  1866. //------------------------------------------------------------------------------
  1867. // CMStorageUnit: IncrementGenerationNumber
  1868. //------------------------------------------------------------------------------
  1869.  
  1870. SOM_Scope ODULong  SOMLINK CMStorageUnitIncrementGenerationNumber(CMStorageUnit *somSelf, Environment *ev)
  1871. {
  1872.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1873.     CMStorageUnitMethodDebug("CMStorageUnit","IncrementGenerationNumber");
  1874.  
  1875.     SOM_CATCH    return 0;
  1876.     FailIfInvalidRefCount();
  1877.     
  1878.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  1879.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  1880.  
  1881.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  1882.  
  1883.     ODULong generation = somSelf->GetGenerationNumber(ev);
  1884.     generation++;
  1885.  
  1886.     CMContainer container = _fDraft->GetCMContainer(ev);
  1887.     ODSessionMustHaveCMAllocReserve(container);
  1888.  
  1889.     CMSetValueGeneration(_fCurValue, generation);
  1890.  
  1891.     ODSessionRestoreCMAllocReserve(container);
  1892.     
  1893.     return generation;
  1894. }
  1895.  
  1896. //------------------------------------------------------------------------------
  1897. // CMStorageUnit: GetSession
  1898. //------------------------------------------------------------------------------
  1899.  
  1900. SOM_Scope ODSession*     SOMLINK CMStorageUnitGetSession(CMStorageUnit *somSelf, Environment *ev)
  1901. {
  1902.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1903.     CMStorageUnitMethodDebug("CMStorageUnit","GetSession");
  1904.  
  1905.     SOM_CATCH    return kODNULL;
  1906.  
  1907.     return (ODSession*) _fDraft->GetDocument(ev)->GetContainer(ev)->GetStorageSystem(ev)->GetSession(ev);
  1908. }
  1909.  
  1910. //------------------------------------------------------------------------------
  1911. // CMStorageUnit: InitStorageUnit
  1912. //------------------------------------------------------------------------------
  1913.  
  1914. SOM_Scope void  SOMLINK CMStorageUnitInitStorageUnit(CMStorageUnit *somSelf, Environment *ev,
  1915.         ODDraft* draft,ODStorageUnitID suid)
  1916. {
  1917.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1918.     CMStorageUnitMethodDebug("CMStorageUnit","InitStorageUnit");
  1919.     
  1920.     SOM_CATCH    return;
  1921.             
  1922.     /* Moved from somInit. SOM itself sets fields to zero
  1923.     _fDraft = kODNULL;
  1924.     _fID = 0;
  1925.     _fObjectID = kODNULL;
  1926.     _fObject = kODNULL;
  1927.     _fCurProperty = kODIDAll;
  1928.     _fCurValueIndex = 0;
  1929.     _fCurValue = kODIDAll;
  1930.     _fCurValueType = 0;
  1931.     _fCurType = kODNULL;
  1932.     _fOffset = 0;
  1933.     _fHasPropertyLooped = kODFalse;
  1934.     _fHasValueLooped = kODFalse;
  1935.     
  1936.     _fCurrentKey = 0;
  1937.     _fLockCount = 0;
  1938.     
  1939.     _fSURefKeeper = kODNULL;
  1940.     
  1941. #ifdef USE_CLONEHELPER
  1942.     _fSUCloneHelper = kODNULL;
  1943. #endif
  1944.     
  1945.     _fHeap = kDefaultHeapID;
  1946.     
  1947.     _fModificationDate = 0;
  1948.     _fDirty = kODFalse;
  1949.     */
  1950.     _fCurProperty = kODIDAll;
  1951.     _fCurValue = kODIDAll;
  1952.     _fHeap = kDefaultHeapID;
  1953.     
  1954.     somSelf->InitRefCntObject(ev);
  1955.     
  1956.     
  1957.     if (draft != kODNULL) {
  1958.     
  1959.         _fDraft = (CMDraft*) draft;
  1960.         _fID = suid;
  1961.     
  1962.         IDList*    idList = kODNULL;
  1963.             
  1964.         idList = _fDraft->GetIDList(ev);
  1965.         ASSERT(idList != kODNULL, kODErrInvalidIDList);
  1966.     
  1967.         _fObject = (CMObject) idList->Get(_fID);
  1968.         if (_fObject == kODNULL)
  1969.             BREAK_AND_THROW(kODErrBentoInvalidObject);
  1970.         
  1971.         _fCMContainer = _fDraft->GetCMContainer(ev);
  1972.             
  1973.         _fObjectID = CMGetObjectID(_fObject);
  1974.         
  1975.         _fHeap = _fDraft->GetHeap(ev);
  1976.  
  1977.         _fPromiseResolver = new(_fHeap) PromiseResolver;
  1978.         _fPromiseResolver->InitPromiseResolver(somSelf);
  1979.         
  1980.         _fSURefKeeper = new(_fHeap) SURefKeeper(somSelf);
  1981.  
  1982. #ifdef USE_CLONEHELPER        
  1983.         _fSUCloneHelper = new(_fHeap) SUCloneHelper;
  1984. #endif
  1985.     }
  1986.     else
  1987.         THROW(kODErrIllegalNullDraftInput);
  1988. }
  1989.  
  1990.  
  1991. //------------------------------------------------------------------------------
  1992. // CMStorageUnit: ~CMStorageUnit
  1993. //------------------------------------------------------------------------------
  1994.  
  1995. SOM_Scope void  SOMLINK CMStorageUnitsomUninit(CMStorageUnit *somSelf)
  1996. {
  1997.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  1998.     CMStorageUnitMethodDebug("CMStorageUnit","somUninit");
  1999.  
  2000.     delete _fPromiseResolver;
  2001.     delete _fSURefKeeper;
  2002.     
  2003. #ifdef USE_CLONEHELPER        
  2004.     delete _fSUCloneHelper;
  2005. #endif    
  2006.     
  2007.     CMStorageUnit_parents_somUninit(somSelf);
  2008.  
  2009. }
  2010.  
  2011. //------------------------------------------------------------------------------
  2012. // CMStorageUnit: CleanupAndFail
  2013. //------------------------------------------------------------------------------
  2014.  
  2015. SOM_Scope void  SOMLINK CMStorageUnitCleanupAndFail(CMStorageUnit *somSelf, Environment *ev,
  2016.         ODError err)
  2017. {
  2018.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2019.     CMStorageUnitMethodDebug("CMStorageUnit","CleanupAndFail");
  2020.  
  2021.     SOM_CATCH return;
  2022.     
  2023. #ifdef ODDebug_ODStorageUnit
  2024.     somPrintf("Cleanup and fail: ID %x PID %x\n", somSelf->GetID(ev), _fObjectID);
  2025. #endif
  2026.  
  2027.     if (_fCurValue != kODNULL) {
  2028.         CMContainer container = _fDraft->GetCMContainer(ev);
  2029.         ODSessionMustHaveCMAllocReserve(container);
  2030.         
  2031.         CMReleaseValue(_fCurValue);
  2032.         
  2033.         ODSessionRestoreCMAllocReserve(container);
  2034.         
  2035.         _fCurValue = kODNULL;
  2036.     }
  2037.     if (err) {
  2038.         BREAK_AND_THROW(err);
  2039.     }
  2040. }
  2041.  
  2042. //------------------------------------------------------------------------------
  2043. // CMStorageUnit: Lock
  2044. //------------------------------------------------------------------------------
  2045.  
  2046. SOM_Scope ODStorageUnitKey  SOMLINK CMStorageUnitLock(CMStorageUnit *somSelf, Environment *ev,
  2047.         ODStorageUnitKey key)
  2048. {
  2049.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2050.     CMStorageUnitMethodDebug("CMStorageUnit","Lock");
  2051.     
  2052.     ODEnterCriticalSection();
  2053.     
  2054.     if (key == 0) {
  2055.         if (_fLockCount == 0) {
  2056.             _fLockCount = 1;
  2057.             _fCurrentKey++;
  2058.             key = _fCurrentKey;
  2059.         }
  2060.     }
  2061.     else {
  2062.         if ((_fCurrentKey != key) || (_fLockCount == 0))
  2063.             ODSetSOMException(ev,kODErrInvalidStorageUnitKey);
  2064.         else
  2065.             _fLockCount++;
  2066.     }
  2067.         
  2068.     ODExitCriticalSection();
  2069.     
  2070.     return key;
  2071. }
  2072.  
  2073. //------------------------------------------------------------------------------
  2074. // CMStorageUnit: Unlock
  2075. //------------------------------------------------------------------------------
  2076.  
  2077. SOM_Scope void  SOMLINK CMStorageUnitUnlock(CMStorageUnit *somSelf, Environment *ev,
  2078.         ODStorageUnitKey key)
  2079. {
  2080.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2081.     CMStorageUnitMethodDebug("CMStorageUnit","Unlock");
  2082.     
  2083.     ODEnterCriticalSection();
  2084.     
  2085.     if (_fCurrentKey != key)
  2086.         ODSetSOMException(ev,kODErrInvalidStorageUnitKey);
  2087.     
  2088.     else if (_fLockCount == 0)
  2089.         ODSetSOMException(ev,kODErrStorageUnitNotLocked);
  2090.     
  2091.     else
  2092.         --_fLockCount;
  2093.         
  2094.     ODExitCriticalSection();
  2095. }
  2096.  
  2097.  
  2098. //------------------------------------------------------------------------------
  2099. // CMStorageUnit: GetStorageUnitRef
  2100. //------------------------------------------------------------------------------
  2101.  
  2102. SOM_Scope void  SOMLINK CMStorageUnitGetStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  2103.         ODStorageUnitID embeddedSUID, ODBoolean strong, ODStorageUnitRef ref)
  2104. {
  2105.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2106.     CMStorageUnitMethodDebug("CMStorageUnit","GetStorageUnitRef");
  2107.  
  2108.     SOM_CATCH    return;
  2109.     FailIfInvalidRefCount();
  2110.  
  2111.     if (embeddedSUID == kODNULLID)
  2112.         THROW(kODErrIllegalNullStorageUnitInput);
  2113.         
  2114.     // Clear incoming reference
  2115.     _fSURefKeeper->InvalidateSURef(ref);
  2116.  
  2117.     CMReference            theReferenceData;    
  2118.     
  2119.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  2120.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  2121.         
  2122.     CMStorageUnit* embeddedSU = (CMStorageUnit*) somSelf->GetDraft(ev)->AcquireStorageUnit(ev, embeddedSUID);
  2123.     TempODStorageUnit tempSU = embeddedSU; // ensure it's released
  2124.     
  2125.     if (embeddedSU) {
  2126.         CMObject object = embeddedSU->GetObject(ev);
  2127.         if (object) {    
  2128.             CMContainer container = _fDraft->GetCMContainer(ev);
  2129.             ODSessionMustHaveCMAllocReserve(container);
  2130.             
  2131.             if (CMGetReferenceForObject(_fCurValue, object, theReferenceData) != kODNULL) {
  2132.                 // we already have this object in the reference, reuse the id            
  2133.                 ODBlockMove(theReferenceData, ref, sizeof(CMReference));
  2134.                 // if strong, value must be strong, else value must be weak
  2135.                 if ((strong != kODFalse) ? somSelf->IsWeakStorageUnitRef(ev, ref) : somSelf->IsStrongStorageUnitRef(ev, ref))
  2136.                     _fSURefKeeper->InvalidateSURef(ref);
  2137.             }
  2138.             
  2139.             if (somSelf->IsValidStorageUnitRef(ev, ref) == kODFalse) {
  2140.                 _fSURefKeeper->GetNextSURef(ref, strong);
  2141. //                ODBlockMove(ref, theReferenceData, sizeof(CMReference));
  2142.             }
  2143.             
  2144. //            CMSetReference(_fCurValue, embeddedSU->GetObject(ev), theReferenceData);
  2145.             CMSetReference(_fCurValue, object, ref);
  2146.  
  2147.             ODSessionRestoreCMAllocReserve(container);
  2148.         }
  2149.     }
  2150. }
  2151.  
  2152. //------------------------------------------------------------------------------
  2153. // CMStorageUnit: SetStorageUnitRef
  2154. //------------------------------------------------------------------------------
  2155.  
  2156. SOM_Scope void  SOMLINK CMStorageUnitSetStorageUnitRef(CMStorageUnit *somSelf, Environment *ev,
  2157.         ODStorageUnitID embeddedSUID, ODStorageUnitRef ref)
  2158. {
  2159.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2160.     CMStorageUnitMethodDebug("CMStorageUnit","SetStorageUnitRef");
  2161.  
  2162.     SOM_CATCH    return;
  2163.     FailIfInvalidRefCount();
  2164.  
  2165.     CMReference            theReferenceData;
  2166.     
  2167.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL) || (_fCurValue == kODNULL))
  2168.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  2169.     
  2170.     if (embeddedSUID == 0)
  2171.         THROW(kODErrIllegalNullIDInput);
  2172.         
  2173.     CMStorageUnit* embeddedSU = (CMStorageUnit*) somSelf->GetDraft(ev)->AcquireStorageUnit(ev, embeddedSUID);
  2174.     TempODStorageUnit tempSU = embeddedSU;
  2175.     
  2176.     somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2177.     
  2178.     ODBlockMove(ref, theReferenceData, sizeof(CMReference));
  2179.     
  2180.     if (_fSURefKeeper != kODNULL) {
  2181.         _fSURefKeeper->Reset(ref);
  2182.     }
  2183.     
  2184.     CMContainer container = _fDraft->GetCMContainer(ev);
  2185.     ODSessionMustHaveCMAllocReserve(container);
  2186.     
  2187.     CMSetReference(_fCurValue, embeddedSU->GetObject(ev), theReferenceData);
  2188.  
  2189.     ODSessionRestoreCMAllocReserve(container);
  2190. }
  2191.  
  2192. //------------------------------------------------------------------------------
  2193. // CMStorageUnit: GetHeap
  2194. //------------------------------------------------------------------------------
  2195.  
  2196. SOM_Scope ODMemoryHeapID  SOMLINK CMStorageUnitGetHeap(CMStorageUnit *somSelf, Environment *ev)
  2197. {
  2198.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2199.     CMStorageUnitMethodDebug("CMStorageUnit","GetHeap");
  2200.  
  2201.     return _fHeap;
  2202. }
  2203.  
  2204. //------------------------------------------------------------------------------
  2205. // CMStorageUnit: GetCMContainer
  2206. //------------------------------------------------------------------------------
  2207.  
  2208. SOM_Scope CMContainer  SOMLINK CMStorageUnitGetCMContainer(CMStorageUnit *somSelf, Environment *ev)
  2209. {
  2210.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2211.     CMStorageUnitMethodDebug("CMStorageUnit","GetCMContainer");
  2212.  
  2213.     SOM_CATCH    return kODNULL;
  2214.  
  2215.     return _fDraft->GetCMContainer(ev);
  2216. }
  2217.  
  2218. //------------------------------------------------------------------------------
  2219. // CMStorageUnit: SetChangedFromPrevFlag
  2220. //------------------------------------------------------------------------------
  2221.  
  2222. SOM_Scope void  SOMLINK CMStorageUnitSetChangedFromPrevFlag(CMStorageUnit *somSelf, Environment *ev,
  2223.         ODBoolean changed)
  2224. {
  2225.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2226.     CMStorageUnitMethodDebug("CMStorageUnit","SetChangedFromPrevFlag");
  2227.  
  2228.     SOM_CATCH    return;
  2229.  
  2230.     if (_fDraft != kODNULL)
  2231.         _fDraft->SetChangedFromPrevFlag(ev, changed);
  2232.  
  2233.     time((time_t *)(&_fModificationDate));
  2234.     
  2235.     _fDirty = kODTrue;
  2236. }
  2237.  
  2238. //------------------------------------------------------------------------------
  2239. // CMStorageUnit: GetObjectID
  2240. //------------------------------------------------------------------------------
  2241.  
  2242. SOM_Scope ODID  SOMLINK CMStorageUnitGetObjectID(CMStorageUnit *somSelf, Environment *ev)
  2243. {
  2244.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2245.     CMStorageUnitMethodDebug("CMStorageUnit","GetObjectID");
  2246.  
  2247.     return (ODID) _fObjectID;
  2248. }
  2249.  
  2250. //------------------------------------------------------------------------------
  2251. // GetPropertySize
  2252. //------------------------------------------------------------------------------
  2253.  
  2254. // Callers must call ODSessionMustHaveCMAllocReserve(container);
  2255.  
  2256. static ODULong GetPropertySize(CMObject object, CMProperty property)
  2257. {
  2258.     ODULong    size = 0;
  2259.     ODULong    numValues = CMCountValues(object, property, kODNULL);
  2260.     CMValue        curValue = kODNULL;
  2261.     
  2262.     for (ODULong i = 0; i < numValues; i++) {
  2263.         curValue = CMGetNextValue(object, property, curValue);
  2264.         if (curValue != kODNULL) {
  2265.             size += CMGetValueSize(curValue);
  2266.             CMReleaseValue(curValue);
  2267.         }
  2268.     }
  2269.     return size;
  2270. }
  2271.  
  2272. //------------------------------------------------------------------------------
  2273. // GetObjectSize
  2274. //------------------------------------------------------------------------------
  2275.  
  2276. // Callers must call ODSessionMustHaveCMAllocReserve(container);
  2277.  
  2278. static ODULong GetObjectSize(CMObject object)
  2279. {
  2280.     ODULong    size = 0;
  2281.     ODULong    numProperties = CMCountProperties(object, kODNULL);
  2282.     CMProperty    curProperty = kODNULL;
  2283.     
  2284.     for (ODULong i = 0; i < numProperties; i++) {
  2285.         curProperty = CMGetNextObjectProperty(object, curProperty);
  2286.         size += GetPropertySize(object, curProperty);
  2287.     }
  2288.     return size;
  2289. }
  2290.  
  2291. //------------------------------------------------------------------------------
  2292. // CMStorageUnit: GetCurValue
  2293. //------------------------------------------------------------------------------
  2294.  
  2295. SOM_Scope CMValue  SOMLINK CMStorageUnitGetCurValue(CMStorageUnit *somSelf, Environment *ev)
  2296. {
  2297.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2298.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurValue");
  2299.  
  2300.     return _fCurValue;
  2301. }
  2302.  
  2303. //------------------------------------------------------------------------------
  2304. // CMStorageUnit: SetCurValue
  2305. //------------------------------------------------------------------------------
  2306. //
  2307. //SOM_Scope void  SOMLINK CMStorageUnitSetCurValue(CMStorageUnit *somSelf, Environment *ev, CMValue curValue)
  2308. //{
  2309. //    CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2310. //    CMStorageUnitMethodDebug("CMStorageUnit","SetCurValue");
  2311. //
  2312. //    _fCurValue = curValue;
  2313. //}
  2314.  
  2315. //------------------------------------------------------------------------------
  2316. // CMStorageUnit: GetObject
  2317. //------------------------------------------------------------------------------
  2318.  
  2319. SOM_Scope CMObject  SOMLINK CMStorageUnitGetObject(CMStorageUnit *somSelf, Environment *ev)
  2320. {
  2321.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2322.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurValue");
  2323.  
  2324.     return _fObject;
  2325. }
  2326.  
  2327. //------------------------------------------------------------------------------
  2328. // CMStorageUnit: GetCurProperty
  2329. //------------------------------------------------------------------------------
  2330.  
  2331. SOM_Scope CMObject  SOMLINK CMStorageUnitGetCurProperty(CMStorageUnit *somSelf, Environment *ev)
  2332. {
  2333.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2334.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurProperty");
  2335.  
  2336.     return _fCurProperty;
  2337. }
  2338.  
  2339. //------------------------------------------------------------------------------
  2340. // CMStorageUnit: GetCurType
  2341. //------------------------------------------------------------------------------
  2342.  
  2343. SOM_Scope CMType  SOMLINK CMStorageUnitGetCurType(CMStorageUnit *somSelf, Environment *ev)
  2344. {
  2345.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2346.     CMStorageUnitMethodDebug("CMStorageUnit","GetCurType");
  2347.  
  2348.     return _fCurType;
  2349. }
  2350.  
  2351. //------------------------------------------------------------------------------
  2352. // CMStorageUnit: SetCurType
  2353. //------------------------------------------------------------------------------
  2354.  
  2355. SOM_Scope void  SOMLINK CMStorageUnitSetCurType(CMStorageUnit *somSelf, Environment *ev, CMType curType)
  2356. {
  2357.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2358.     CMStorageUnitMethodDebug("CMStorageUnit","SetCurType");
  2359.  
  2360.     _fCurType = curType;
  2361. }
  2362.  
  2363. //------------------------------------------------------------------------------
  2364. // CMStorageUnit: IsPromiseValue
  2365. //------------------------------------------------------------------------------
  2366.  
  2367. SOM_Scope ODBoolean  SOMLINK CMStorageUnitIsPromiseValue(CMStorageUnit *somSelf, Environment *ev)
  2368. {
  2369.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2370.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitIsPromiseValue");
  2371.  
  2372.     SOM_CATCH    return kODFalse;
  2373.  
  2374.     return _fPromiseResolver->IsPromiseValue(ev);
  2375. }
  2376.  
  2377. //------------------------------------------------------------------------------
  2378. // CMStorageUnit: SetPromiseValue
  2379. //------------------------------------------------------------------------------
  2380.  
  2381. SOM_Scope void  SOMLINK CMStorageUnitSetPromiseValue(CMStorageUnit *somSelf, Environment *ev,
  2382.         ODValueType valueType,
  2383.         ODULong offset,
  2384.         ODByteArray* value,
  2385.         ODPart* sourcePart)
  2386. {
  2387.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2388.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitSetPromiseValue");
  2389.  
  2390.     SOM_CATCH    return;
  2391.     FailIfIllegalByteArray(value);
  2392.     FailIfInvalidRefCount();
  2393.  
  2394.     if ((_fObject == kODNULL) || (_fCurProperty == kODNULL))
  2395.         BREAK_AND_THROW(kODErrUnfocusedStorageUnit);
  2396.     
  2397.     if (_fPromiseResolver != kODNULL) {
  2398.         _fPromiseResolver->SettingPromise();
  2399.  
  2400.         TRY
  2401. #if ODDebug_AddValue
  2402.             ODPropertyName propertyName = somSelf->GetProperty(ev);
  2403.             if (somSelf->Exists(ev, propertyName, valueType, 0) != kODFalse) {
  2404.                 somSelf->Focus(ev, propertyName, kODPosUndefined, valueType, 0, kODPosUndefined);
  2405.             }
  2406.             else
  2407.                 somSelf->AddValue(ev, valueType);
  2408.             ODDisposePtr(propertyName);
  2409. #else                
  2410.             somSelf->AddValue(ev, valueType);
  2411. #endif
  2412.             somSelf->SetChangedFromPrevFlag(ev, kODTrue);
  2413.             
  2414.             somSelf->SetOffset(ev, offset);
  2415.             somSelf->SetValue(ev, value);
  2416.             
  2417.             _fPromiseResolver->SetSourcePart(ev, sourcePart);
  2418.             
  2419.             _fPromiseResolver->DoneSettingPromise();
  2420.         CATCH_ALL
  2421.             _fPromiseResolver->DoneSettingPromise();
  2422.             RERAISE;
  2423.         ENDTRY
  2424.     }
  2425. }
  2426.  
  2427. //------------------------------------------------------------------------------
  2428. // CMStorageUnit: GetPromiseValue
  2429. //------------------------------------------------------------------------------
  2430.  
  2431. SOM_Scope ODULong  SOMLINK CMStorageUnitGetPromiseValue(CMStorageUnit *somSelf, Environment *ev,
  2432.         ODValueType valueType,
  2433.         ODULong offset,
  2434.         ODULong length,
  2435.         ODByteArray* value,
  2436.         ODPart** sourcePart)
  2437. {
  2438.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2439.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitGetPromiseValue");
  2440.  
  2441.     SOM_CATCH    return 0;
  2442.     FailIfIllegalByteArray(value);
  2443.     FailIfInvalidRefCount();
  2444.  
  2445.     somSelf->Focus(ev, kODNULL, kODPosSame, valueType, 0, kODPosSame);
  2446.     
  2447.     value->_buffer = (octet*) ODNewPtr(length);
  2448.     value->_maximum = length;
  2449.     value->_length = CMReadValueData(_fCurValue, (CMPtr) value->_buffer, offset, length);
  2450.     
  2451.     if ((_fPromiseResolver != kODNULL) && (sourcePart != kODNULL))
  2452.         *sourcePart = _fPromiseResolver->GetSourcePart(ev);
  2453.     
  2454.     return value->_length;
  2455. }
  2456.  
  2457. //------------------------------------------------------------------------------
  2458. // CMStorageUnit: ClearAllPromises
  2459. //------------------------------------------------------------------------------
  2460.  
  2461. SOM_Scope void  SOMLINK CMStorageUnitClearAllPromises(CMStorageUnit *somSelf, Environment *ev)
  2462. {
  2463.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2464.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitClearAllPromises");
  2465.  
  2466.     SOM_CATCH    return;
  2467.     FailIfInvalidRefCount();
  2468.     
  2469.     if (_fPromiseResolver->GetPromiseCount())
  2470.     {
  2471.         somSelf->Focus(ev,
  2472.                         (ODPropertyName) kODNULL, 
  2473.                         kODPosAll,
  2474.                         kODTypeAll,
  2475.                         0,
  2476.                         kODPosUndefined);
  2477.         ODULong numProperties = somSelf->CountProperties(ev);
  2478.         for (ODULong i = 0; i < numProperties; i++)
  2479.         {
  2480.             somSelf->Focus(ev,
  2481.                         (ODPropertyName) kODNULL,
  2482.                         kODPosNextSib,
  2483.                         kODTypeAll,
  2484.                         0,
  2485.                         kODPosUndefined);
  2486.             ODULong numValues = somSelf->CountValues(ev);    
  2487.             for (ODULong j = 0; j < numValues; j++)
  2488.             {
  2489.                 somSelf->Focus(ev,
  2490.                             (ODPropertyName)kODNULL,
  2491.                             kODPosSame,
  2492.                             kODTypeAll,
  2493.                             0,
  2494.                             kODPosNextSib);
  2495.                 _fPromiseResolver->ClearPromise(ev);
  2496.                 if (_fPromiseResolver->GetPromiseCount() == 0)
  2497.                     return;
  2498.             }
  2499.         }
  2500.     }
  2501. }
  2502.  
  2503. //------------------------------------------------------------------------------
  2504. // CMStorageUnit: ResolveAllPromises
  2505. //------------------------------------------------------------------------------
  2506.  
  2507. SOM_Scope void  SOMLINK CMStorageUnitResolveAllPromises(CMStorageUnit *somSelf, Environment *ev)
  2508. {
  2509.     CMStorageUnitData *somThis = CMStorageUnitGetData(somSelf);
  2510.     CMStorageUnitMethodDebug("CMStorageUnit","CMStorageUnitResolveAllPromises");
  2511.  
  2512.     SOM_CATCH    return;
  2513.  
  2514.     if (_fPromiseResolver && _fPromiseResolver->GetPromiseCount())
  2515.     {
  2516.         somSelf->Focus(ev, (ODPropertyName)kODNULL, 
  2517.                                 kODPosAll,
  2518.                                 kODTypeAll,
  2519.                                 0,
  2520.                                 kODPosUndefined);
  2521.         ODULong numProperties = somSelf->CountProperties(ev);
  2522.         for (ODULong i = 0; i < numProperties; i++)
  2523.         {
  2524.             somSelf->Focus(ev, (ODPropertyName)kODNULL,
  2525.                         kODPosNextSib,
  2526.                         kODTypeAll,
  2527.                         0,
  2528.                         kODPosUndefined);
  2529.             ODULong numValues = somSelf->CountValues(ev);    
  2530.             for (ODULong j = 0; j < numValues; j++)
  2531.             {
  2532.                 somSelf->Focus(ev, (ODPropertyName)kODNULL,
  2533.                             kODPosSame,
  2534.                             kODTypeAll,
  2535.                             0,
  2536.                             kODPosNextSib);
  2537.                 PreserveFocus* focus = new PreserveFocus(ev, somSelf);
  2538.                 _fPromiseResolver->ResolvePromise(ev);
  2539.                 delete focus;
  2540.                 numValues = somSelf->CountValues(ev);
  2541.                 numProperties = somSelf->CountProperties(ev);
  2542.                 if (_fPromiseResolver->GetPromiseCount() == 0)
  2543.                     return;
  2544.             }
  2545.         }
  2546.     }
  2547. }
  2548.  
  2549. //------------------------------------------------------------------------------
  2550. // NewODStorageUnitView
  2551. //------------------------------------------------------------------------------
  2552.  
  2553. static ODStorageUnitView* NewODStorageUnitView(ODMemoryHeapID heapID)
  2554. {
  2555.     SOMClass*    suViewClass = somNewClassReference(ODStorageUnitView);
  2556.     ODULong        size = suViewClass->somGetInstanceSize();
  2557.     ODPtr        buffer = ODNewPtr(size, heapID);
  2558.     ODStorageUnitView*    suView = (ODStorageUnitView*) suViewClass->somRenew(buffer);
  2559.     somReleaseClassReference ( suViewClass );
  2560.     
  2561.     return suView;
  2562. }
  2563.  
  2564. //------------------------------------------------------------------------------
  2565. // NewODStorageUnitCursor
  2566. //------------------------------------------------------------------------------
  2567.  
  2568. static ODStorageUnitCursor* NewODStorageUnitCursor(ODMemoryHeapID heapID)
  2569. {
  2570.     SOMClass*    suCursorClass = somNewClassReference(ODStorageUnitCursor);
  2571.     ODULong        size = suCursorClass->somGetInstanceSize();
  2572.     ODPtr        buffer = ODNewPtr(size, heapID);
  2573.     ODStorageUnitCursor*    suCursor = (ODStorageUnitCursor*) suCursorClass->somRenew(buffer);
  2574.     somReleaseClassReference ( suCursorClass );
  2575.     
  2576.     return suCursor;
  2577. }
  2578.  
  2579. //------------------------------------------------------------------------------
  2580. // NewCMStorageUnitRefIterator
  2581. //------------------------------------------------------------------------------
  2582.  
  2583. static CMStorageUnitRefIterator* NewCMStorageUnitRefIterator(ODMemoryHeapID heapID)
  2584. {
  2585.     SOMClass*    refIterClass = somNewClassReference(CMStorageUnitRefIterator);
  2586.     ODULong        size = refIterClass->somGetInstanceSize();
  2587.     ODPtr        buffer = ODNewPtr(size, heapID);
  2588.     CMStorageUnitRefIterator*    refIter = (CMStorageUnitRefIterator*) refIterClass->somRenew(buffer);
  2589.     somReleaseClassReference ( refIterClass );
  2590.     
  2591.     return refIter;
  2592. }
  2593.  
  2594.  
  2595.