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