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 / FileCtr.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  12.7 KB  |  469 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        FileCtr.cpp
  3.  
  4.     Contains:    Implementation of ODFileContainer class.
  5.  
  6.     Owned by:    Vincent Lo
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <7>     8/13/96    DM        1376080: TempSuppressFatalBentoError
  13.                                     spelling
  14.          <6>     5/24/96    jpa        1246074: SOM_CATCH --> SOM_TRY..SOM_ENDTRY
  15.          <4>     5/23/96    DH        1344338: Force quit of document when
  16.                                     dragging 'Bad' file or Container. Turned
  17.                                     off fatal Bento errors for Open and Create
  18.                                     container operations.1333189: When a drag
  19.                                     of an OpenDoc document fails, document is
  20.                                     left open. If document fails to open, manually
  21.                                     close the file.
  22.          <2>     1/15/96    TJ        Cleaned Up
  23.     In Progress:
  24.         
  25. */
  26.  
  27. #define ODFileContainer_Class_Source
  28.  
  29. #define VARIABLE_MACROS
  30.  
  31. #include <FileCtr.xih>
  32.  
  33. #ifndef _PLFMDEF_
  34. #include "PlfmDef.h"
  35. #endif
  36.  
  37. #ifndef _BENTODEF_
  38. #include "BentoDef.h"
  39. #endif
  40.  
  41. #ifndef SOM_ODStorageSystem_xh
  42. #include <ODStor.xh>
  43. #endif
  44.  
  45. #ifndef _FSHDR_
  46. #include "FSHdr.h"
  47. #endif
  48.  
  49. #ifndef _TARGTHDR_
  50. #include "TargtHdr.h"
  51. #endif
  52.  
  53. #ifndef _INDHDR_
  54. #include "IndHdr.h"
  55. #endif
  56.  
  57. #ifndef __CM_API__
  58. #include "CMAPI.h"
  59. #endif
  60.  
  61. #ifndef _EXCEPT_
  62. #include "Except.h"
  63. #endif
  64.  
  65. #ifndef SOM_Module_OpenDoc_Errors_defined
  66. #include "ErrorDef.xh"
  67. #endif
  68.  
  69. #ifndef _ODNEW_
  70. #include <ODNew.h>
  71. #endif
  72.  
  73. #ifndef _PLFMFILE_
  74. #include <PlfmFile.h>
  75. #endif
  76.  
  77. #ifndef _ITEXT_
  78. #include <IText.h>
  79. #endif
  80.  
  81. #ifndef _BARRAY_
  82. #include <BArray.h>
  83. #endif
  84.  
  85. #ifndef __ALIASES__
  86. #include <Aliases.h>
  87. #endif
  88.  
  89. #ifdef DebugRefCount
  90. #include "Stdio.h"
  91. #endif
  92.  
  93. #ifndef _BENTOSUPPRESS_
  94. #include <BentoSuppress.h>
  95. #endif
  96.  
  97. #if ODDebug
  98. // #define ODDebug_ODFileContainer 1
  99. #endif
  100.  
  101. #pragma segment ODFileContainer
  102.  
  103. //==============================================================================
  104. // ODFileContainer
  105. //==============================================================================
  106.  
  107. //------------------------------------------------------------------------------
  108. // ODFileContainer: ~ODFileContainer
  109. //------------------------------------------------------------------------------
  110.  
  111. SOM_Scope void  SOMLINK ODFileContainersomUninit(ODFileContainer *somSelf)
  112. {
  113.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  114.     ODFileContainerMethodDebug("ODFileContainer","somUninit");
  115.  
  116. #ifdef DebugRefCount
  117.     printf("~ODFileContainer %x CMContainer %x RefCount %d\n", somSelf, _fCMContainer, _fRefCount);
  118.     fflush(stdout);
  119. #endif
  120.  
  121.     TRY{
  122.         Environment *ev = somGetGlobalEnvironment ();
  123.     
  124.         if (_fCMContainer != kODNULL)
  125.             somSelf->Close(ev);
  126.     
  127.         if (_fHandlers != kODNULL)
  128.             delete _fHandlers;
  129.     
  130.         if (_fPlatformFile != kODNULL)
  131.             delete _fPlatformFile;
  132.             
  133.         if (_fAlias != kODNULL)
  134.             ODDisposeHandle((ODHandle) _fAlias);
  135.     }CATCH_ALL{
  136.         // Ignore exceptions
  137.     }ENDTRY
  138. }
  139.  
  140. //------------------------------------------------------------------------------
  141. // ODFileContainer: InitContainer
  142. //------------------------------------------------------------------------------
  143.  
  144. SOM_Scope void  SOMLINK ODFileContainerInitContainer(ODFileContainer *somSelf, Environment *ev,
  145.         ODStorageSystem* storage, ODContainerID* id)
  146. {
  147.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  148.     ODFileContainerMethodDebug("ODFileContainer","InitContainer");
  149.     
  150.     SOM_TRY
  151.  
  152.     /* Moved from somInit. SOM itself sets fields to zero
  153.     _fCMContainer = kODNULL;
  154.     _fHandlers = kODNULL;
  155.     _fAlias = kODNULL;
  156.     _fPlatformFile = kODNULL;
  157.     */
  158.     
  159.     OSErr err = NewAlias(kODNULL, (FSSpec*) id->_buffer, &_fAlias);
  160.     if (err != noErr)
  161.         THROW(kODErrCannotCreateContainer);
  162.  
  163.     // Change id to exclude any garbage before FSSpec.name.
  164.     // struct FSSpec {
  165.     //     short                            vRefNum;
  166.     //     long                            parID;
  167.     //     Str63                            name;
  168.     // };
  169.     id->_length = sizeof(short) + sizeof(long) + ((FSSpec*) id->_buffer)->name[0] + 1;
  170.     
  171.     // Call parent with the updated id
  172.     parent_InitContainer(somSelf, ev, storage, id);
  173.     
  174.     _fPlatformFile = new PlatformFile();
  175.     _fPlatformFile->Specify((ODFileSpec*) id->_buffer);
  176.         
  177.     _fHandlers = new(somSelf->GetHeap(ev)) ODFSBentoHandlers(somSelf->GetCMSession(ev),
  178.                                                             _fPlatformFile);
  179.     _fHandlers->Initialize();
  180.  
  181.     SOM_CATCH_ALL
  182.     SOM_ENDTRY
  183. }
  184.  
  185. //------------------------------------------------------------------------------
  186. // ODFileContainer: GetID
  187. //------------------------------------------------------------------------------
  188.  
  189. SOM_Scope ODContainerID  SOMLINK ODFileContainerGetID(ODFileContainer *somSelf, Environment *ev)
  190. {
  191.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  192.     ODFileContainerMethodDebug("ODFileContainer","GetName");
  193.     
  194.     ODByteArray ba;
  195.  
  196.     SOM_TRY
  197.     
  198.     ODBoolean    dummyWasChanged;
  199.     ODFileSpec*    fsSpec = (ODFileSpec*) ODNewPtrClear(sizeof(ODFileSpec));
  200.     
  201.     OSErr err = ResolveAlias(kODNULL, _fAlias, fsSpec, &dummyWasChanged);
  202.     if (err != noErr) {
  203.         *fsSpec = _fPlatformFile->GetFileSpec();
  204.     }
  205.     ba._buffer = (octet*) fsSpec;
  206.     ba._maximum = sizeof(ODFileSpec);
  207.     ba._length = sizeof(short) + sizeof(long) + ((FSSpec*) ba._buffer)->name[0] + 1;
  208.     
  209.     SOM_CATCH_ALL
  210.         ba._buffer = kODNULL;
  211.         ba._maximum = ba._length = 0;
  212.     SOM_ENDTRY
  213.     
  214.     return ba;
  215. }
  216.  
  217. //------------------------------------------------------------------------------
  218. // ODFileContainer: GetName
  219. //------------------------------------------------------------------------------
  220.  
  221. SOM_Scope ODContainerName  SOMLINK ODFileContainerGetName(ODFileContainer *somSelf, Environment *ev)
  222. {
  223.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  224.     ODFileContainerMethodDebug("ODFileContainer","GetName");
  225.  
  226.     ODFileSpec            fsSpec;
  227.     ODContainerName*    name = kODNULL;
  228.     ODBoolean            dummyWasChanged;
  229.     
  230.     SOM_TRY
  231.     
  232.     OSErr err = ResolveAlias(kODNULL, _fAlias, &fsSpec, &dummyWasChanged);
  233.     if (err != noErr) {
  234.         name = _fPlatformFile->GetName();
  235.     }
  236.     else {
  237.         name = CreateIText(0, 0, (StringPtr) &fsSpec.name);
  238.     }
  239.     
  240.     SOM_CATCH_ALL
  241.     SOM_ENDTRY
  242.     
  243.     return *name;    
  244. }
  245.  
  246. //------------------------------------------------------------------------------
  247. // ODFileContainer: SetName
  248. //------------------------------------------------------------------------------
  249.  
  250. SOM_Scope void  SOMLINK ODFileContainerSetName(ODFileContainer *somSelf, Environment *ev,
  251.         ODContainerName* name)
  252. {
  253.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  254.     ODFileContainerMethodDebug("ODFileContainer","SetName");
  255.  
  256.     SOM_TRY
  257.     
  258.     StringPtr fileName = GetPStringFromIText(name);
  259.     _fPlatformFile->Rename(fileName);
  260.  
  261.     SOM_CATCH_ALL
  262.     SOM_ENDTRY
  263. }
  264.  
  265. //------------------------------------------------------------------------------
  266. // ODFileContainer: Create
  267. //------------------------------------------------------------------------------
  268.  
  269. SOM_Scope ODContainer*  SOMLINK ODFileContainerCreate(ODFileContainer *somSelf, Environment *ev)
  270. {
  271.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  272.     ODFileContainerMethodDebug("ODFileContainer","Create");
  273.  
  274.     SOM_TRY
  275.  
  276.     if (_fCMContainer == kODNULL) {
  277.     
  278.         somSelf->SetModDate(ev, _fPlatformFile->GetFileModDate());
  279.  
  280.         CMSession cmSession = somSelf->GetCMSession(ev);
  281.  
  282.         CMSetMetaHandler(cmSession,
  283.                         (CMGlobalName)CMTargetHandlersTypeName,
  284.                         targetContainerMetahandler);
  285.  
  286.         {    
  287.             TempSuppressFatalBentoError temp;
  288.                 
  289.             _fCMContainer = CMOpenNewContainer(cmSession,
  290.                                             _fHandlers,
  291.                                             (CMGlobalName) kODBentoFileTypeName,
  292.                                             (CMContainerUseMode) (kCMWriting),
  293.                                             1, kCMDefaultEndian);
  294.         }
  295.         if (_fCMContainer == kODNULL)
  296.             THROW(kODErrCannotCreateContainer);
  297.     }
  298.  
  299.     return somSelf;
  300.  
  301.     SOM_CATCH_ALL
  302.     SOM_ENDTRY
  303.     return somSelf;
  304. }
  305.  
  306. //------------------------------------------------------------------------------
  307. // ODFileContainer: Open
  308. //------------------------------------------------------------------------------
  309.  
  310. SOM_Scope ODContainer*  SOMLINK ODFileContainerOpen(ODFileContainer *somSelf, Environment *ev)
  311. {
  312.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  313.     ODFileContainerMethodDebug("ODFileContainer","Open");
  314.  
  315.     SOM_TRY
  316.  
  317.     if (_fCMContainer == kODNULL) {
  318.     
  319.         somSelf->SetModDate(ev, _fPlatformFile->GetFileModDate());
  320.  
  321.         CMSession cmSession = somSelf->GetCMSession(ev);
  322.         
  323.         CMSetMetaHandler(cmSession,
  324.                         (CMGlobalName)CMTargetHandlersTypeName,
  325.                         targetContainerMetahandler);
  326.         {    // Suppress fatal Bento errors.
  327.             TempSuppressFatalBentoError temp;
  328.                                 
  329.             TRY
  330.                 _fCMContainer = CMOpenContainer(cmSession,
  331.                                                 _fHandlers,
  332.                                                 (CMGlobalName) kODBentoFileTypeName,
  333.                                                 (CMContainerUseMode) kCMReuseFreeSpace);
  334.             CATCH_ALL
  335.                 // At this point there was some problem with opening the Container.
  336.                 // Unfortunately, Bento will not cleanup after determining there is a
  337.                 // problem, which leaves the file open in the file system. We must 
  338.                 // close it manually then.
  339.                 _fPlatformFile->Close();
  340.                 return kODNULL;   // Propogate the error by not clearing it here and
  341.                                   // immediately exiting.
  342.             ENDTRY
  343.         }    
  344.         if (_fCMContainer == kODNULL)
  345.             THROW(kODErrCannotOpenContainer);
  346.     }
  347.  
  348.     return somSelf;
  349.  
  350.     SOM_CATCH_ALL
  351.     SOM_ENDTRY
  352.     return somSelf;
  353. }
  354.  
  355. //------------------------------------------------------------------------------
  356. // ODFileContainer: Close
  357. //------------------------------------------------------------------------------
  358.  
  359. SOM_Scope ODContainer*  SOMLINK ODFileContainerClose(ODFileContainer *somSelf, Environment *ev)
  360. {
  361.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  362.     ODFileContainerMethodDebug("ODFileContainer","Close");
  363.  
  364.     SOM_TRY
  365.  
  366.     if (_fCMContainer != kODNULL) {
  367.         SOM_TRY
  368.             if (somSelf->GetDirtyFlag(ev) != kODFalse) {
  369.                 CMObject    currObj, nextObj;
  370.                 CMProperty    embedProp;
  371.                 CMType        embedType;
  372.                 CMValue        currValue;
  373.                 CMSize        valueSize;
  374.     
  375.                 embedProp = CMRegisterProperty(_fCMContainer, kODPropVersionList);
  376.                 currObj = CMGetNextObjectWithProperty(_fCMContainer, kODNULL, embedProp);
  377.                 CMKeepObject(currObj);
  378.                 embedProp = CMRegisterProperty(_fCMContainer, kODEmbeddedContainerProperty); // "OpenDoc:EmbeddedContainer"
  379.                 embedType = CMRegisterType(_fCMContainer, kODEmbeddedContainerType); // "OpenDoc:EmbeddedContainerType"
  380.                 currObj = CMGetNextObjectWithProperty(_fCMContainer, kODNULL, embedProp);
  381.                 while (currObj) {
  382.                     nextObj = CMGetNextObjectWithProperty(_fCMContainer, currObj, embedProp);
  383.                     currValue = CMUseValue(currObj, embedProp, embedType);
  384.                     if (currValue) {
  385.                         valueSize =  CMGetValueSize(currValue);
  386.                         CMReleaseValue(currValue);
  387.                         if (valueSize)    /* no need to keep it unless length is not zero */
  388.                             CMKeepObject(currObj);
  389.                     } 
  390.                     currObj = nextObj;
  391.                 };
  392.                 CMCloseContainer(_fCMContainer);
  393. #if ODDebug_ODFileContainer
  394. somPrintf("FileContainer Close: Close\n");
  395. #endif
  396.             }
  397.             else {
  398.                 CMAbortContainer(_fCMContainer);
  399. #if ODDebug_ODFileContainer
  400. somPrintf("FileContainer Close: Abort\n");
  401. #endif
  402.             }
  403.             _fPlatformFile->SetFileModDate(somSelf->GetModDate(ev));
  404.         SOM_CATCH_ALL
  405.             if (ErrorCode() == kODErrBentoErr)
  406.                 SetErrorCode(kODErrFatalContainerError);
  407.         SOM_ENDTRY
  408.         _fCMContainer = kODNULL;
  409.     }
  410.     
  411.     return ODFileContainer_parent_ODBentoContainer_Close(somSelf, ev);
  412.  
  413.     SOM_CATCH_ALL
  414.     SOM_ENDTRY
  415.     return somSelf;
  416. }
  417.  
  418. //------------------------------------------------------------------------------
  419. // ODFileContainer: Purge
  420. //------------------------------------------------------------------------------
  421.  
  422. SOM_Scope ODSize  SOMLINK ODFileContainerPurge(ODFileContainer *somSelf, Environment *ev,
  423.         ODSize size)
  424. {
  425.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  426.     ODFileContainerMethodDebug("ODFileContainer","Purge");
  427.  
  428.     ODSize freed = 0;    ODVolatile(freed);
  429.  
  430.     SOM_TRY
  431.          freed = parent_Purge(somSelf, ev, size);
  432.     SOM_CATCH_ALL
  433.         WARN("Error %ld trying to purge in ODFileContainerPurge",ErrorCode());
  434.         SetErrorCode(kODNoError);        // dh - Eat the exception; Purge should not 
  435.                                         // propagate it because clients function
  436.                                         // fine whether memory was purged or not.
  437.                                         // Also, don't return 0 if an exception
  438.                                         // was thrown. Initialized counter should
  439.                                         // suffice to give correct return value.
  440.     SOM_ENDTRY
  441.     
  442.     return freed;
  443. }
  444.  
  445. //------------------------------------------------------------------------------
  446. // ODFileContainer: GetCMContainer
  447. //------------------------------------------------------------------------------
  448.  
  449. SOM_Scope CMContainer  SOMLINK ODFileContainerGetCMContainer(ODFileContainer *somSelf, Environment *ev)
  450. {
  451.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  452.     ODFileContainerMethodDebug("ODFileContainer","GetCMContainer");
  453.  
  454.     return _fCMContainer;
  455. }
  456.  
  457. //------------------------------------------------------------------------------
  458. // ODFileContainer: GetHandlers
  459. //------------------------------------------------------------------------------
  460.  
  461. SOM_Scope ODBentoHandlers*  SOMLINK ODFileContainerGetHandlers(ODFileContainer *somSelf, Environment *ev)
  462. {
  463.     ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
  464.     ODFileContainerMethodDebug("ODFileContainer","GetHandlers");
  465.  
  466.     return _fHandlers;
  467. }
  468.  
  469.