home *** CD-ROM | disk | FTP | other *** search
- /*
- File: FileCtr.cpp
-
- Contains: Implementation of ODFileContainer class.
-
- Owned by: Vincent Lo
-
- Copyright: © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 1/15/96 TJ Cleaned Up
- <23> 10/24/95 jpa 1293441: DM/VL: Bento memory reserve &
- fatal container err.
- <22> 10/8/95 TJ Fixes Recomended by Refball
- <21> 8/24/95 EL 1276818: move Bento container suite
- property to BentoDef.h
- <20> 8/12/95 TÇ 1276806 Optimization: use kODFalse instead
- of kODTrue in comparisons
- <19> 8/3/95 RR #1257260: Collapse B classes. Remove
- somInit methods. Don't call IsInitialized
- or SubclassResponsibility
- <18> 7/21/95 VL 1270320: Create ba on stack in GetID.
- <17> 5/26/95 VL 1251403: Multithreading naming support.
- <16> 5/25/95 jpa Fixed usage of ODDebug. [1253321]
- <15> 4/25/95 VL 1240737: Make sure that the returned ID
- from GetID is set to the right _length.
- <14> 4/15/95 VL 1240014: Modifiy id->_length in
- InitContainer to reflect the real length.
- <13> 4/7/95 EL 1225905: Do SetModDate here rather than in
- handler.
- <12> 3/24/95 EL 1209355: open container r/w instead of
- update because CMTakeSnapShot does not work
- with update yet.
- <11> 3/23/95 VL 1230357: Implemented Purge.
- <10> 3/6/95 EL 1225905: Call RestoreModDate if file
- container to be aborted.
- <9> 2/21/95 EL 1182275: Garbage collect embedded values
- with zero length.
- <8> 2/10/95 VL 1205627: Check to see if a file is locked.
- If so, open it read-only.
- <7> 11/14/94 VL 1188257: Use Bento errors in BenotDef.h.
- <6> 11/1/94 VL 1185688: Added SOM_CATCH.
- <5> 9/23/94 VL 1184272: ContainerID is now a sequence of
- octets. 1184166: Implemented GetName and
- SetName.
- <4> 8/26/94 EL #1182275 Include code (not yet active) for
- merging of container.
- <3> 8/5/94 VL 1171603: Use somSelf->GetCMSession instead
- of depending on ODStorageSystem.
- <2> 8/3/94 VL 1153123: Storage to ODStor.
- <1> 6/30/94 CC first checked in
- <0> 6/28/94 SV SOMverted
- <2> 4/13/94 VL 1157028: StorageM.h does not include
- CMAPI.h anymore, so GetCMSession returns
- ODULong.
- <1> 3/24/94 VL first checked in
- <15> 2/8/94 VL Use new exception macros.
- <14> 1/21/94 CG Added include for BentoCtr.h.
- <13> 1/19/94 EL Use kCMNextGeneration when opening new
- container for update.
- <12> 1/12/94 VL Init changes.
- <11> 1/6/94 EL Reuse free space in the file.
- <10> 12/3/93 TÇ Stop including ODError.h, it is included
- as ErrorDef.h inside Except.h
- <9> 11/23/93 VL Made FileContainer pool-aware.
- <8> 9/9/93 VL Moved Session Global code to ODDraft.
- <7> 8/9/93 VL Moved error code to ODError.h.
- <6> 8/6/93 VL fContainer is now fCMContainer and is
- protected.
- <5> 6/30/93 VL Typecasted ODType to CMGlobalName for CM
- calls.
- <4> 6/22/93 VL Used RefCount from ODRefCntObject.
- <3> 6/15/93 VL This class is now a subclass of
- ODBentoContainer. Stripped some code and
- put it in ODBentoContainer.
- <2> 6/1/93 VL Delete fID (PlatformFile object) in the
- destructor. Open should SetMetaHandlers to
- target and use CMOpenNewContainer instead
- of CMOpenContainer.
- <1> 5/27/93 VL first checked in
-
- */
-
- #define ODFileContainer_Class_Source
-
- #define VARIABLE_MACROS
-
- #include <FileCtr.xih>
-
- #ifndef _PLFMDEF_
- #include "PlfmDef.h"
- #endif
-
- #ifndef _BENTODEF_
- #include "BentoDef.h"
- #endif
-
- #ifndef SOM_ODStorageSystem_xh
- #include <ODStor.xh>
- #endif
-
- #ifndef _FSHDR_
- #include "FSHdr.h"
- #endif
-
- #ifndef _TARGTHDR_
- #include "TargtHdr.h"
- #endif
-
- #ifndef _INDHDR_
- #include "IndHdr.h"
- #endif
-
- #ifndef __CM_API__
- #include "CMAPI.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef SOM_Module_OpenDoc_Errors_defined
- #include "ErrorDef.xh"
- #endif
-
- #ifndef _ODNEW_
- #include <ODNew.h>
- #endif
-
- #ifndef _PLFMFILE_
- #include <PlfmFile.h>
- #endif
-
- #ifndef _ITEXT_
- #include <IText.h>
- #endif
-
- #ifndef _BARRAY_
- #include <BArray.h>
- #endif
-
- #ifndef __ALIASES__
- #include <Aliases.h>
- #endif
-
- #ifdef DebugRefCount
- #include "Stdio.h"
- #endif
-
- #if ODDebug
- // #define ODDebug_ODFileContainer 1
- #endif
-
- #pragma segment ODFileContainer
-
- //==============================================================================
- // ODFileContainer
- //==============================================================================
-
- //------------------------------------------------------------------------------
- // ODFileContainer: ~ODFileContainer
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODFileContainersomUninit(ODFileContainer *somSelf)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","somUninit");
-
- #ifdef DebugRefCount
- printf("~ODFileContainer %x CMContainer %x RefCount %d\n", somSelf, _fCMContainer, _fRefCount);
- fflush(stdout);
- #endif
-
- TRY{
- Environment *ev = somGetGlobalEnvironment ();
-
- if (_fCMContainer != kODNULL)
- somSelf->Close(ev);
-
- if (_fHandlers != kODNULL)
- delete _fHandlers;
-
- if (_fPlatformFile != kODNULL)
- delete _fPlatformFile;
-
- if (_fAlias != kODNULL)
- ODDisposeHandle((ODHandle) _fAlias);
- }CATCH_ALL{
- // Ignore exceptions
- }ENDTRY
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: InitContainer
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODFileContainerInitContainer(ODFileContainer *somSelf, Environment *ev,
- ODStorageSystem* storage, ODContainerID* id)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","InitContainer");
-
- SOM_CATCH return;
-
- /* Moved from somInit. SOM itself sets fields to zero
- _fCMContainer = kODNULL;
- _fHandlers = kODNULL;
- _fAlias = kODNULL;
- _fPlatformFile = kODNULL;
- */
-
- OSErr err = NewAlias(kODNULL, (FSSpec*) id->_buffer, &_fAlias);
- if (err != noErr)
- THROW(kODErrCannotCreateContainer);
-
- // Change id to exclude any garbage before FSSpec.name.
- // struct FSSpec {
- // short vRefNum;
- // long parID;
- // Str63 name;
- // };
- id->_length = sizeof(short) + sizeof(long) + ((FSSpec*) id->_buffer)->name[0] + 1;
-
- // Call parent with the updated id
- parent_InitContainer(somSelf, ev, storage, id);
-
- _fPlatformFile = new PlatformFile();
- _fPlatformFile->Specify((ODFileSpec*) id->_buffer);
-
- _fHandlers = new(somSelf->GetHeap(ev)) ODFSBentoHandlers(somSelf->GetCMSession(ev),
- _fPlatformFile);
- _fHandlers->Initialize();
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: GetID
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainerID SOMLINK ODFileContainerGetID(ODFileContainer *somSelf, Environment *ev)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","GetName");
-
- ODByteArray ba;
-
- SOM_TRY
-
- ODBoolean dummyWasChanged;
- ODFileSpec* fsSpec = (ODFileSpec*) ODNewPtrClear(sizeof(ODFileSpec));
-
- OSErr err = ResolveAlias(kODNULL, _fAlias, fsSpec, &dummyWasChanged);
- if (err != noErr) {
- *fsSpec = _fPlatformFile->GetFileSpec();
- }
- ba._buffer = (octet*) fsSpec;
- ba._maximum = sizeof(ODFileSpec);
- ba._length = sizeof(short) + sizeof(long) + ((FSSpec*) ba._buffer)->name[0] + 1;
-
- SOM_CATCH_ALL
- ba._buffer = kODNULL;
- ba._maximum = ba._length = 0;
- SOM_ENDTRY
-
- return ba;
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: GetName
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainerName SOMLINK ODFileContainerGetName(ODFileContainer *somSelf, Environment *ev)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","GetName");
-
- ODFileSpec fsSpec;
- ODContainerName* name = kODNULL;
- ODBoolean dummyWasChanged;
-
- SOM_TRY
-
- OSErr err = ResolveAlias(kODNULL, _fAlias, &fsSpec, &dummyWasChanged);
- if (err != noErr) {
- name = _fPlatformFile->GetName();
- }
- else {
- name = CreateIText(0, 0, (StringPtr) &fsSpec.name);
- }
-
- SOM_CATCH_ALL
- SOM_ENDTRY
-
- return *name;
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: SetName
- //------------------------------------------------------------------------------
-
- SOM_Scope void SOMLINK ODFileContainerSetName(ODFileContainer *somSelf, Environment *ev,
- ODContainerName* name)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","SetName");
-
- SOM_CATCH return;
-
- StringPtr fileName = GetPStringFromIText(name);
- _fPlatformFile->Rename(fileName);
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: Create
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODFileContainerCreate(ODFileContainer *somSelf, Environment *ev)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","Create");
-
- SOM_CATCH return somSelf;
-
- if (_fCMContainer == kODNULL) {
-
- somSelf->SetModDate(ev, _fPlatformFile->GetFileModDate());
-
- CMSession cmSession = somSelf->GetCMSession(ev);
-
- CMSetMetaHandler(cmSession,
- (CMGlobalName)CMTargetHandlersTypeName,
- targetContainerMetahandler);
-
- _fCMContainer = CMOpenNewContainer(cmSession,
- _fHandlers,
- (CMGlobalName) kODBentoFileTypeName,
- (CMContainerUseMode) (kCMWriting),
- 1, kCMDefaultEndian);
- if (_fCMContainer == kODNULL)
- THROW(kODErrCannotCreateContainer);
- }
-
- return somSelf;
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: Open
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODFileContainerOpen(ODFileContainer *somSelf, Environment *ev)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","Open");
-
- SOM_CATCH return somSelf;
-
- if (_fCMContainer == kODNULL) {
-
- somSelf->SetModDate(ev, _fPlatformFile->GetFileModDate());
-
- CMSession cmSession = somSelf->GetCMSession(ev);
-
- CMSetMetaHandler(cmSession,
- (CMGlobalName)CMTargetHandlersTypeName,
- targetContainerMetahandler);
-
- _fCMContainer = CMOpenContainer(cmSession,
- _fHandlers,
- (CMGlobalName) kODBentoFileTypeName,
- (CMContainerUseMode) kCMReuseFreeSpace);
- if (_fCMContainer == kODNULL)
- THROW(kODErrCannotOpenContainer);
- }
-
- return somSelf;
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: Close
- //------------------------------------------------------------------------------
-
- SOM_Scope ODContainer* SOMLINK ODFileContainerClose(ODFileContainer *somSelf, Environment *ev)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","Close");
-
- SOM_CATCH return somSelf;
-
- if (_fCMContainer != kODNULL) {
- SOM_TRY
- if (somSelf->GetDirtyFlag(ev) != kODFalse) {
- CMObject currObj, nextObj;
- CMProperty embedProp;
- CMType embedType;
- CMValue currValue;
- CMSize valueSize;
-
- embedProp = CMRegisterProperty(_fCMContainer, kODPropVersionList);
- currObj = CMGetNextObjectWithProperty(_fCMContainer, kODNULL, embedProp);
- CMKeepObject(currObj);
- embedProp = CMRegisterProperty(_fCMContainer, kODEmbeddedContainerProperty); // "OpenDoc:EmbeddedContainer"
- embedType = CMRegisterType(_fCMContainer, kODEmbeddedContainerType); // "OpenDoc:EmbeddedContainerType"
- currObj = CMGetNextObjectWithProperty(_fCMContainer, kODNULL, embedProp);
- while (currObj) {
- nextObj = CMGetNextObjectWithProperty(_fCMContainer, currObj, embedProp);
- currValue = CMUseValue(currObj, embedProp, embedType);
- if (currValue) {
- valueSize = CMGetValueSize(currValue);
- CMReleaseValue(currValue);
- if (valueSize) /* no need to keep it unless length is not zero */
- CMKeepObject(currObj);
- }
- currObj = nextObj;
- };
- CMCloseContainer(_fCMContainer);
- #if ODDebug_ODFileContainer
- somPrintf("FileContainer Close: Close\n");
- #endif
- }
- else {
- CMAbortContainer(_fCMContainer);
- #if ODDebug_ODFileContainer
- somPrintf("FileContainer Close: Abort\n");
- #endif
- }
- _fPlatformFile->SetFileModDate(somSelf->GetModDate(ev));
- SOM_CATCH_ALL
- if (ErrorCode() == kODErrBentoErr)
- SetErrorCode(kODErrFatalContainerError);
- SOM_ENDTRY
- _fCMContainer = kODNULL;
- }
-
- return ODFileContainer_parent_ODBentoContainer_Close(somSelf, ev);
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: Purge
- //------------------------------------------------------------------------------
-
- SOM_Scope ODSize SOMLINK ODFileContainerPurge(ODFileContainer *somSelf, Environment *ev,
- ODSize size)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","Purge");
-
- ODSize freed = 0; ODVolatile(freed);
-
- SOM_TRY
- freed = parent_Purge(somSelf, ev, size);
- SOM_CATCH_ALL
- WARN("Error %ld trying to purge in ODFileContainerPurge",ErrorCode());
- SetErrorCode(kODNoError); // dh - Eat the exception; Purge should not
- // propagate it because clients function
- // fine whether memory was purged or not.
- // Also, don't return 0 if an exception
- // was thrown. Initialized counter should
- // suffice to give correct return value.
- SOM_ENDTRY
-
- return freed;
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: GetCMContainer
- //------------------------------------------------------------------------------
-
- SOM_Scope CMContainer SOMLINK ODFileContainerGetCMContainer(ODFileContainer *somSelf, Environment *ev)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","GetCMContainer");
-
- return _fCMContainer;
- }
-
- //------------------------------------------------------------------------------
- // ODFileContainer: GetHandlers
- //------------------------------------------------------------------------------
-
- SOM_Scope ODBentoHandlers* SOMLINK ODFileContainerGetHandlers(ODFileContainer *somSelf, Environment *ev)
- {
- ODFileContainerData *somThis = ODFileContainerGetData(somSelf);
- ODFileContainerMethodDebug("ODFileContainer","GetHandlers");
-
- return _fHandlers;
- }
-
-