home *** CD-ROM | disk | FTP | other *** search
- /*
- File: PlfmFile.cpp
-
- Contains: Implmentation for PlatformFile class
-
- Owned by: Vincent Lo
-
- Copyright: © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <10> 7/28/96 DH Bug#1372834: Cyberdog: Drag to Finder fails
- when MacOS scraptype used.
- <9> 6/4/96 EL Remove debug statement left in from last
- check in.
- <8> 6/4/96 EL 1289557: Truncate comment but don't split
- two byte character if comment is too long.
- <7> 5/31/96 JA CW68K: Fixed mem leak/app-heap usage in
- GetCustomIconFamily.
- <6> 5/31/96 jpa T10012: Added IsOpenDocDocument.
- <5> 5/23/96 DH 1352221: Document Info dialog is
- disabled/acts flaky. Fixed GetCustomIcon so
- that it doesn't manually fiddle with the
- resource fork of the file.
- <4> 5/8/96 NP 1282265: saving as stationery looks like
- document
- <3> 3/15/96 DH 1329039 - OpenDoc's routine
- PlatformFile::HasCustomIcon() does not
- work.
- <2> 3/1/96 JP 1314798: Made CreateResFile get type &
- creator first
-
- To Do:
- In Progress:
-
- */
-
- #ifndef _ODTYPES_
- #include "ODTypes.h"
- #endif
-
- #ifndef _PLFMFILE_
- #include "PlfmFile.h"
- #endif
-
- #ifndef _ODMEMORY_
- #include "ODMemory.h"
- #endif
-
- #ifndef _EXCEPT_
- #include "Except.h"
- #endif
-
- #ifndef _ODDEBUG_
- #include "ODDebug.h"
- #endif
-
- #ifndef _PASCLSTR_
- #include "PasclStr.h"
- #endif
-
- #ifndef _ITEXT_
- #include "IText.h"
- #endif
-
- #ifndef _DOCUTILS_
- #include "DocUtils.h"
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _UTILDEFS_
- #include "UtilDefs.h"
- #endif
-
- #ifndef _TEMPOBJ_
- #include "TempObj.h"
- #endif
-
- #ifndef _UTILERRS_
- #include "UtilErrs.h"
- #endif
-
- #ifndef __FILES__
- #include <Files.h>
- #endif
-
- #ifndef __FOLDERS__
- #include <Folders.h>
- #endif
-
- #ifndef __FINDER__
- #include <Finder.h>
- #endif
-
- #ifndef __ICONS__
- #include <Icons.h>
- #endif
-
- #ifndef __STRING__
- #include <string.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include "TextUtils.h"
- #endif
-
- #ifndef _USERSRCM_
- #include <UseRsrcM.h>
- #endif
-
- #ifndef __TEXTUTILS__
- #include "TextUtils.h"
- #endif
-
- #include <ctype.h> /* for islower( ) */
-
-
- #pragma segment PlatformFile
-
- //==============================================================================
- // Constants
- //==============================================================================
-
- const ODSShort kMaxFileNameSize = 64;
- const ODULong kMaxCommentSize = 199;
-
- #define kFileContainerType 'ctyp'
- #define kFileContainerTypeResID 1
-
- const ODULong kMaxCopyBufferSize = 32 * 1024L;
- const ODULong kMinCopyBufferSize = 512;
-
- static const ResType kIconType[6] = {'ICN#','icl4','icl8','ics#','ics4','ics8'};
- static const short kIconSize[6] = {256, 512, 1024, 64, 128, 256 };
-
- #define kODCyberdogSignature 'dogz'
-
- //==============================================================================
- // Scalar Types
- //==============================================================================
-
- //==============================================================================
- // Local Classes
- //==============================================================================
-
- //==============================================================================
- // Global Variables
- //==============================================================================
-
- //==============================================================================
- // Function Prototype
- //==============================================================================
-
- //==============================================================================
- // PlatformFile
- //==============================================================================
-
- const ODOSType kBogusOSType = 0; // Default type/creator value until it's read
-
- //------------------------------------------------------------------------------
- // PlatformFile::PlatformFile
- //------------------------------------------------------------------------------
- PlatformFile::PlatformFile()
- {
- fContainerType = kODNULL;
- fCreator = kBogusOSType;
- fFileType = kBogusOSType;
- fScriptTag = smSystemScript;
-
- fFileSpec.vRefNum = 0;
- fFileSpec.parID = 0;
- fFileSpec.name[0] = 0;
- fDataRefNum = 0;
- fFileID = kODNoFileID;
- fPermission = fsCurPerm;
- fResRefNum = kODNoFileRefNum;
- fResOpenStack = 0;
- fNeedToClose = kODFalse;
-
- fVolModDate = fTimeLastChecked = 0;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::~PlatformFile
- //------------------------------------------------------------------------------
- PlatformFile::~PlatformFile()
- {
- ODDisposePtr(fContainerType);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Specify
- //------------------------------------------------------------------------------
- void PlatformFile::Specify(const ODFileSpec* fileSpec)
- {
- fFileSpec = *fileSpec;
- fCreator = kBogusOSType;
- fFileType = kBogusOSType;
- fFileID = kODNoFileID;
- }
-
- void PlatformFile::SpecifyFromFile(PlatformFile* file)
- {
- const ODFileSpec &fileSpec = file->GetFileSpec();
- this->Specify(&fileSpec);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetAsciiname
- //------------------------------------------------------------------------------
- void PlatformFile::SetAsciiName(const char* asciiName)
- {
- ODSByte pname[kMaxFileNameSize+1];
- strncpy(pname,asciiName,kMaxFileNameSize);
- pname[kMaxFileNameSize] = 0;
-
- CToPascalString(pname);
- if (fFileSpec.vRefNum == 0 &&
- fFileSpec.parID == 0 &&
- fFileSpec.name[0] == 0)
- {
- FSMakeFSSpec(0, 0, (StringPtr)pname, &fFileSpec);
- }
- else
- {
- CopyPascalString(fFileSpec.name,(StringPtr)pname);
- }
- this->Specify(&fFileSpec);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::IsLocked
- //------------------------------------------------------------------------------
- ODBoolean PlatformFile::IsLocked()
- {
- CInfoPBRec pbBlock;
- ODBoolean result = kODFalse;
-
- // Check to see whether the volume is locked
-
- // Eric's original code with slight modifications.
- // Appears to be needed in the case of a locked floppy. -TÇ
- HParamBlockRec pb;
- pb.volumeParam.ioCompletion = kODNULL;
- pb.volumeParam.ioNamePtr = kODNULL;
- pb.volumeParam.ioVRefNum = fFileSpec.vRefNum;
- pb.volumeParam.ioVolIndex = 0;
-
- THROW_IF_ERROR(PBHGetVInfoSync(&pb));
-
- // <eeh> I have no clue if this "0x80"is right!!! Find out what
- // the constant is for write-access possible....
-
- result = (pb.volumeParam.ioVAtrb & 0x80) ? kODTrue : kODFalse;
-
- // Check to see whether the directory is locked
- if (result == kODFalse) {
- // first assume it is a file share volume
- HParamBlockRec paramBlk;
- paramBlk.accessParam.ioCompletion = kODNULL;
- paramBlk.accessParam.ioNamePtr = kODNULL;
- paramBlk.accessParam.ioVRefNum = fFileSpec.vRefNum;
- paramBlk.accessParam.ioDirID = fFileSpec.parID;
- paramBlk.accessParam.ioACAccess = 0;
- OSErr err = PBHGetDirAccessSync(¶mBlk);
-
- if (err == noErr) { /* it is a file share volume, look at the access right */
- if ((paramBlk.accessParam.ioACAccess & 0x04000000) == 0) /* no write access */
- result = kODTrue;
- }
- else if (err == paramErr) { /* it is not file share, look at directory */
- pbBlock.dirInfo.ioCompletion = kODNULL;
- pbBlock.dirInfo.ioNamePtr = kODNULL;
- pbBlock.dirInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.dirInfo.ioFDirIndex = -1;
- pbBlock.dirInfo.ioDrDirID = fFileSpec.parID;
- pbBlock.dirInfo.ioFlAttrib = 0;
- THROW_IF_ERROR(PBGetCatInfoSync(&pbBlock));
- if (pbBlock.dirInfo.ioFlAttrib & 1)
- result = kODTrue;
- }
- else
- THROW(err);
- }
-
- // Check to see whether the file is locked
- if (result == kODFalse) {
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fFileSpec.name;
- pbBlock.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
-
- THROW_IF_ERROR(PBGetCatInfoSync(&pbBlock));
-
- if (pbBlock.hFileInfo.ioFlAttrib & 1)
- result = kODTrue;
- }
-
- return result;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Lock
- //------------------------------------------------------------------------------
- void PlatformFile::Lock()
- {
- THROW_IF_ERROR( FSpSetFLock(&fFileSpec) );
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Unlock
- //------------------------------------------------------------------------------
- void PlatformFile::Unlock()
- {
- THROW_IF_ERROR( FSpRstFLock(&fFileSpec) );
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::IsStationery
- //------------------------------------------------------------------------------
- ODBoolean PlatformFile::IsStationery()
- {
- FInfo fileInfo;
- THROW_IF_ERROR( FSpGetFInfo(&fFileSpec,&fileInfo) );
- return (((fileInfo.fdFlags)&kIsStationary)!=0);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetStationery
- //------------------------------------------------------------------------------
-
- void PlatformFile::SetStationery(ODBoolean isStationery)
- {
- if (isStationery)
- this->SetFinderFlag(kIsStationery);
- else
- this->UnsetFinderFlag(kIsStationery);
-
- // FInfo fileInfo;
-
- // THROW_IF_ERROR( FSpGetFInfo(&fFileSpec,&fileInfo) );
- // if (isStationery)
- // (fileInfo.fdFlags) |= kIsStationery;
- // else
- // (fileInfo.fdFlags) &= ~kIsStationery;
- // THROW_IF_ERROR( FSpSetFInfo(&fFileSpec,&fileInfo) );
- // Finder bug prevents this from helping to update the icon in the Finder
- // BumpFolderModDate();
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetCustomIcon
- //------------------------------------------------------------------------------
-
- void PlatformFile::SetCustomIcon(ODBoolean hasCustomIcon)
- {
- if (hasCustomIcon)
- this->SetFinderFlag(kHasCustomIcon);
- else
- this->UnsetFinderFlag(kHasCustomIcon);
- // FInfo fileInfo;
-
- // THROW_IF_ERROR( FSpGetFInfo(&fFileSpec, &fileInfo) );
- // if (hasCustomIcon)
- // (fileInfo.fdFlags) |= kHasCustomIcon;
- // else
- // (fileInfo.fdFlags) &= ~kHasCustomIcon;
- // THROW_IF_ERROR( FSpSetFInfo(&fFileSpec, &fileInfo) );
- // BumpFolderModDate();
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetFinderFlag
- //------------------------------------------------------------------------------
-
- void PlatformFile::SetFinderFlag(ODUShort flag)
- {
- FInfo fileInfo;
-
- THROW_IF_ERROR( FSpGetFInfo(&fFileSpec, &fileInfo) );
- (fileInfo.fdFlags) |= flag;
- THROW_IF_ERROR( FSpSetFInfo(&fFileSpec, &fileInfo) );
- // if (flag != kIsStationery)
- BumpFolderModDate();
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::UnsetFinderFlag
- //------------------------------------------------------------------------------
-
- void PlatformFile::UnsetFinderFlag(ODUShort flag)
- {
- FInfo fileInfo;
-
- THROW_IF_ERROR( FSpGetFInfo(&fFileSpec, &fileInfo) );
- (fileInfo.fdFlags) &= ~flag;
- THROW_IF_ERROR( FSpSetFInfo(&fFileSpec, &fileInfo) );
- // if (flag != kIsStationery)
- BumpFolderModDate();
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::HasCustomIcon
- //------------------------------------------------------------------------------
-
- ODBoolean PlatformFile::HasCustomIcon()
- {
- FInfo fileInfo;
-
- THROW_IF_ERROR( FSpGetFInfo(&fFileSpec, &fileInfo) );
- return ( (fileInfo.fdFlags & kHasCustomIcon) ? kODTrue : kODFalse);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::IsDirectory
- //------------------------------------------------------------------------------
- ODBoolean PlatformFile::IsDirectory()
- {
- ODBoolean isDirectory = kODFalse;
-
- if( fFileID == kODNoFileID ) {
- CInfoPBRec pbBlock;
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fFileSpec.name;
- pbBlock.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- THROW_IF_ERROR(PBGetCatInfoSync(&pbBlock));
- isDirectory = pbBlock.dirInfo.ioFlAttrib & 0x10 ? kODTrue : kODFalse;
- }
- return isDirectory;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::IsEqualTo
- //------------------------------------------------------------------------------
- ODBoolean PlatformFile::IsEqualTo(PlatformFile* file)
- {
- return (fFileSpec.parID == file->fFileSpec.parID &&
- fFileSpec.vRefNum == file->fFileSpec.vRefNum &&
- EqualPascalStrings(fFileSpec.name, file->fFileSpec.name));
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetFInfoFlags
- //------------------------------------------------------------------------------
- ODUShort PlatformFile::GetFInfoFlags()
- {
- FInfo fileInfo;
-
- THROW_IF_ERROR( FSpGetFInfo(&fFileSpec, &fileInfo) );
- return fileInfo.fdFlags;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Create
- //------------------------------------------------------------------------------
- void PlatformFile::Create(ODOSType creator, ODOSType fileType, ODScriptCode scriptCode)
- {
-
- if (fDataRefNum == kODNoFileRefNum) {
- THROW_IF_ERROR( FSpCreate(&fFileSpec, creator, fileType, scriptCode) );
- }
- fCreator = creator;
- fFileType = fileType;
- fScriptTag = scriptCode;
-
- this->GetFileID();
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::CreateResFile
- //------------------------------------------------------------------------------
- void PlatformFile::CreateResFile()
- {
- if (fResRefNum == kODNoFileRefNum)
- {
- this->GetPlatformType(); // make sure the type and creator are known
- FSpCreateResFile(&fFileSpec, fCreator, fFileType, fScriptTag);
- THROW_IF_ERROR(ResError());
- }
- this->GetFileID();
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::OpenResFile
- //------------------------------------------------------------------------------
- void PlatformFile::OpenResFile()
- {
- ASSERT(fResOpenStack >= 0, kODErrAssertionFailed);
- if (fResRefNum == kODNoFileRefNum)
- {
- ASSERT(fResOpenStack == 0, fResOpenStack);
- fResRefNum = GetFirstLocalPath(PlatformFile::kODResourceFork);
- if (fResRefNum != kODNoFileRefNum)
- {
- // Resource fork is already open
- UseResFile(fResRefNum);
- fNeedToClose = kODFalse;
- }
- else
- {
- // Resource fork is closed
- fResRefNum = FSpOpenResFile(&fFileSpec, fPermission);
- if (fResRefNum == -1 && fPermission != fsRdPerm)
- {
- fResRefNum = kODNoFileRefNum;
- CreateResFile();
- fResRefNum = FSpOpenResFile(&fFileSpec, fPermission);
- }
- OSErr err = ResError();
- if (err != eofErr)
- {
- if (fResRefNum == -1)
- fResRefNum = kODNoFileRefNum;
- THROW_IF_ERROR(ResError());
- }
- if (fResRefNum == -1)
- {
- fResRefNum = kODNoFileRefNum;
- THROW(resFNotFound);
- }
- fNeedToClose = kODTrue;
- }
- }
- else
- UseResFile(fResRefNum);
- ++fResOpenStack;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::CloseResFile
- //------------------------------------------------------------------------------
- void PlatformFile::CloseResFile()
- {
- ASSERT(fResOpenStack > 0, fResOpenStack);
- if (--fResOpenStack == 0 && fNeedToClose)
- {
- ::CloseResFile(fResRefNum);
- THROW_IF_ERROR(ResError());
- fResRefNum = kODNoFileRefNum;
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetFileID
- //------------------------------------------------------------------------------
- void PlatformFile::GetFileID()
- {
- if( fFileID == kODNoFileID ) {
- CInfoPBRec pbBlock;
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fFileSpec.name;
- pbBlock.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- THROW_IF_ERROR(PBGetCatInfoSync(&pbBlock));
- fFileID = pbBlock.hFileInfo.ioDirID; /* for tracking the file later */
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::UpdateSpecFromID
- //------------------------------------------------------------------------------
- void PlatformFile::UpdateSpecFromID()
- {
- if (fFileID != kODNoFileID) { /* make sure got the latest name in file spec */
- HParamBlockRec hPB;
- hPB.fidParam.ioCompletion = kODNULL;
- hPB.fidParam.ioNamePtr = fFileSpec.name;
- hPB.fidParam.ioVRefNum = fFileSpec.vRefNum;
- hPB.fidParam.ioFileID = fFileID;
- if (PBResolveFileIDRefSync(&hPB) == noErr) /* ignore any error */
- fFileSpec.parID = hPB.fidParam.ioSrcDirID;
- }
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::Exists
- //------------------------------------------------------------------------------
- ODBoolean PlatformFile::Exists()
- {
- const ODFileSpec &filespec = this->GetFileSpec();
- FInfo ignore ;
- OSErr err = FSpGetFInfo( &filespec, &ignore );
- if ( err == noErr )
- return kODTrue ;
- else {
- if ( err != fnfErr )
- THROW( err );
- return kODFalse ;
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Open
- //------------------------------------------------------------------------------
- void PlatformFile::Open()
- {
- if (fDataRefNum == kODNoFileRefNum) {
- this->GetFileID();
- THROW_IF_ERROR(FSpOpenDF(&fFileSpec, fPermission, &fDataRefNum));
- }
- else
- THROW(kODErrFileOpened);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Close
- //------------------------------------------------------------------------------
- void PlatformFile::Close()
- {
- if (fDataRefNum != kODNoFileRefNum) {
- THROW_IF_ERROR(FSClose(fDataRefNum));
- fDataRefNum = kODNoFileRefNum;
- }
- else
- THROW(kODErrFileClosed);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Delete
- //------------------------------------------------------------------------------
- void PlatformFile::Delete()
- {
- THROW_IF_ERROR(FSpDelete(&fFileSpec));
- fFileID = kODNoFileID;
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::FlushVolume
- //------------------------------------------------------------------------------
- void PlatformFile::FlushVolume()
- {
- if (fDataRefNum != kODNoFileRefNum) {
- ParamBlockRec pb;
-
- pb.ioParam.ioCompletion = kODNULL;
- pb.ioParam.ioRefNum = fDataRefNum;
- (void) PBFlushFileSync(&pb);
- }
-
- (void) FlushVol(kODNULL, fFileSpec.vRefNum);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetFilePos
- //------------------------------------------------------------------------------
- void PlatformFile::SetFilePos(ODSShort posMode, ODSLong posOff)
- {
- THROW_IF_ERROR(SetFPos(fDataRefNum, posMode, posOff));
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetFilePos
- //------------------------------------------------------------------------------
- ODSLong PlatformFile::GetFilePos()
- {
- ODSLong posOff;
-
- THROW_IF_ERROR(GetFPos(fDataRefNum, &posOff));
- return posOff;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Read
- //------------------------------------------------------------------------------
- void PlatformFile::Read(void* buffer, ODSLong* count)
- {
- THROW_IF_ERROR(FSRead(fDataRefNum, count, buffer));
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Write
- //------------------------------------------------------------------------------
- void PlatformFile::Write(const void* buffer, ODSLong* count)
- {
- THROW_IF_ERROR(FSWrite(fDataRefNum, count, buffer));
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetEndOfFile
- //------------------------------------------------------------------------------
- ODSLong PlatformFile::GetEndOfFile()
- {
- ODSLong length;
-
- THROW_IF_ERROR(GetEOF(fDataRefNum, &length));
- return length;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetEndOfFile
- //------------------------------------------------------------------------------
- void PlatformFile::SetEndOfFile(ODSLong length)
- {
- THROW_IF_ERROR(SetEOF(fDataRefNum, length));
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetName
- //------------------------------------------------------------------------------
- ODName* PlatformFile::GetName()
- {
- this->UpdateSpecFromID();
-
- return CreateIText(fScriptTag, 0, fFileSpec.name);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetAsciiName
- //------------------------------------------------------------------------------
- void PlatformFile::GetAsciiName(char* asciiName, ODULong maxLength)
- {
- this->UpdateSpecFromID();
-
- ODULong n = fFileSpec.name[0];
- if( n > maxLength )
- n = maxLength;
- ODBlockMove(&(fFileSpec.name[1]), asciiName, n);
- asciiName[n] = '\0';
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetPlatformCreator
- //------------------------------------------------------------------------------
- ODOSType PlatformFile::GetPlatformCreator()
- {
- if (fCreator == kBogusOSType) {
- FInfo fileInfo;
- THROW_IF_ERROR(FSpGetFInfo(&fFileSpec, &fileInfo));
- fCreator = fileInfo.fdCreator;
- fFileType = fileInfo.fdType;
- }
- return fCreator;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetPlatformCreator
- //------------------------------------------------------------------------------
- void PlatformFile::SetPlatformCreator(ODOSType creator)
- {
- FInfo fileInfo;
- THROW_IF_ERROR(FSpGetFInfo(&fFileSpec, &fileInfo));
- if( fileInfo.fdCreator != creator ) {
- fileInfo.fdCreator = creator;
- THROW_IF_ERROR(FSpSetFInfo(&fFileSpec, &fileInfo));
- fCreator = creator;
- this->BumpFolderModDate();
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetPlatformType
- //------------------------------------------------------------------------------
- ODOSType PlatformFile::GetPlatformType()
- {
- if (fFileType == kBogusOSType) {
- FInfo fileInfo;
- THROW_IF_ERROR(FSpGetFInfo(&fFileSpec, &fileInfo));
- fCreator = fileInfo.fdCreator;
- fFileType = fileInfo.fdType;
- }
- return fFileType;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetPlatformType
- //------------------------------------------------------------------------------
- void PlatformFile::SetPlatformType(ODOSType fileType)
- {
- FInfo fileInfo;
- THROW_IF_ERROR(FSpGetFInfo(&fFileSpec, &fileInfo));
- if( fileInfo.fdType != fileType ) {
- fileInfo.fdType = fileType;
- THROW_IF_ERROR(FSpSetFInfo(&fFileSpec, &fileInfo));
- fFileType = fileType;
- this->BumpFolderModDate();
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::IsOpenDocDocument
- //------------------------------------------------------------------------------
- ODBoolean PlatformFile::IsOpenDocDocument( )
- {
- return IsOpenDocDocument(this->GetPlatformType(),this->GetPlatformCreator());
- }
-
- ODBoolean
- PlatformFile::IsOpenDocDocument( OSType type, OSType creator ) /* static method */
- {
- /* In OpenDoc 1.0, all documents had 'odtm' as their creator. To support
- CyberDog and container applications, we need to allow other creators.
- To support this, we define a space of filetypes that are known to be
- OpenDoc containers. The first (high-order) byte of the filetype is
- a magic constant value. */
-
- // There's some big-endian fu here but this is Mac specific code anyway.
-
- if( (type>>24)==kODMagicFileTypeChar )
- return true;
- if( ( creator==kODShellSignature || creator==kODCyberdogSignature ) && type!='APPL' && type!='shlb' )
- if( !( (type>>8)=='edt' && islower(type&0xFF) ) ) // not an edition file
- return true;
- return false;
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetContainerType
- //------------------------------------------------------------------------------
-
- ODContainerType PlatformFile::GetContainerType()
- {
- if (fContainerType == kODNULL)
- fContainerType =
- (ODContainerType)
- (this->ReadResourcePtr(kFileContainerType, kFileContainerTypeResID, kODNULL));
-
- return fContainerType;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetContainerType
- //------------------------------------------------------------------------------
-
- void PlatformFile::SetContainerType(ODContainerType containerType)
- {
- ODDisposePtr(fContainerType);
- fContainerType = containerType;
-
- this->WriteResourcePtr(kFileContainerType, kFileContainerTypeResID,
- (ODPtr)containerType, strlen(containerType)+1);
- }
-
-
- //------------------------------------------------------------------------------
- // CWithActiveResources class
- //------------------------------------------------------------------------------
-
- class CWithActiveResources :Destructo {
- public:
- CWithActiveResources( PlatformFile* );
- ~CWithActiveResources( );
- private:
- PlatformFile *fFile;
- ODFileRefNum fCurResFile;
- ODBoolean fSuccessfullyOpened;
- };
-
- CWithActiveResources::CWithActiveResources( PlatformFile *pf )
- {
- fSuccessfullyOpened = kODFalse;
- fFile = pf;
- fCurResFile = CurResFile();
- fFile->OpenResFile();
- fSuccessfullyOpened = kODTrue;
- }
-
- CWithActiveResources::~CWithActiveResources( )
- {
- if (fSuccessfullyOpened)
- fFile->CloseResFile();
- UseResFile(fCurResFile);
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::ReadResourcePtr
- //------------------------------------------------------------------------------
- ODPtr PlatformFile::ReadResourcePtr(ODPlatformType resType, ODSShort resID, ODULong* size)
- {
- ODPtr resPtr = kODNULL;
-
- TRY
- CWithActiveResources w(this); // this throws if no resfile
-
- Handle resHandle = Get1Resource(resType, resID);
- if (resHandle != kODNULL)
- {
- HNoPurge(resHandle);
- ODULong hsize = GetHandleSize(resHandle);
- if (size != kODNULL)
- *size = hsize;
- resPtr = ODNewPtrClear(hsize,0);
- ODBlockMove(*resHandle,resPtr, hsize);
- ReleaseResource(resHandle);
- } else if( ResError() != resNotFound )
- THROW_IF_ERROR(ResError());
-
- CATCH_ALL
- ENDTRY
-
- return resPtr; // Method Specific
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::WriteResourcePtr
- //------------------------------------------------------------------------------
- void PlatformFile::WriteResourcePtr(ODPlatformType resType, ODSShort resID,
- const void *resPtr, ODULong size)
- {
- ASSERT(resPtr!=kODNULL,kODErrIllegalNullInput);
-
- SetPermission(fsRdWrPerm);
- CWithActiveResources w(this);
-
- Handle resHandle = Get1Resource(resType,resID);
- if( ResError() != resNotFound )
- THROW_IF_ERROR(ResError());
-
- ODBoolean needsAdding = (resHandle == kODNULL);
- if (needsAdding)
- resHandle = ODNewHandle(size);
- else {
- HNoPurge(resHandle);
- ODSetHandleSize(resHandle, size);
- }
-
- ODBlockMove(resPtr,*resHandle, size);
-
- if (needsAdding)
- AddResource(resHandle,resType,resID,"\p");
- else
- ChangedResource(resHandle);
- THROW_IF_ERROR(ResError());
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::DeleteResource
- //------------------------------------------------------------------------------
- void PlatformFile::DeleteResource(ODPlatformType resType, ODSShort resID)
- {
- SetPermission(fsRdWrPerm);
- CWithActiveResources w(this);
-
- Handle resHandle = Get1Resource(resType, resID);
- OSErr err= ResError();
- if( resHandle ) {
- RemoveResource(resHandle);
- err= ResError();
- if( !err )
- DisposeHandle(resHandle); // After RemoveResource it's not a rsrc
- } else {
- if( err == resNotFound )
- err = noErr;
- }
- THROW_IF_ERROR(err);
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetAllocationBlockSize
- //------------------------------------------------------------------------------
- ODULong PlatformFile::GetAllocationBlockSize()
- {
- HParamBlockRec pb;
-
- pb.volumeParam.ioCompletion = kODNULL;
- pb.volumeParam.ioNamePtr = kODNULL;
- pb.volumeParam.ioVRefNum = fFileSpec.vRefNum;
- pb.volumeParam.ioVolIndex = 0;
-
- THROW_IF_ERROR(PBHGetVInfoSync(&pb));
-
- return pb.volumeParam.ioVAlBlkSiz;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::CopyFrom
- //------------------------------------------------------------------------------
- void PlatformFile::CopyFrom( PlatformFile* src )
- {
- ODBoolean srcIsOpen = (src->GetFileRefNum() != kODNoFileRefNum);
- if ( !srcIsOpen )
- src->Open();
- this->SetPermission( fsRdWrPerm ); // currently this is the default value
- if (!this->Exists())
- this->Create(src->GetPlatformCreator(), src->GetPlatformType(), 0 /*$$$$$ scriptcode?*/);
-
- this->Open();
-
- src->SetFilePos( fsFromStart, 0 );
- this->SetFilePos( fsFromStart, 0 );
-
- ODSLong bytesLeft = src->GetEndOfFile();
-
- TempODHandle hbuffer = kODNULL;
- ODSLong bufferSize = kMaxCopyBufferSize;
- if( bufferSize > bytesLeft )
- bufferSize = bytesLeft;
- for( ; bufferSize>=kMinCopyBufferSize; bufferSize /= 2 ) {
- OSErr err;
- hbuffer= TempNewHandle(bufferSize,&err);
- if( hbuffer ) break;
- }
- WASSERT(bufferSize > 0);
- THROW_IF_NULL(hbuffer);
- void *buffer = *hbuffer;
-
- ODSLong count;
-
- while( bytesLeft > 0 )
- {
- count = bytesLeft < bufferSize? bytesLeft: bufferSize ;
- WASSERT(count > 0);
- src->Read( buffer, &count );
- this->Write( buffer, &count );
- bytesLeft -= count ;
- }
-
- if ( !srcIsOpen )
- src->Close();
- this->Close();
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::MoveRename
- //------------------------------------------------------------------------------
- void PlatformFile::MoveRename( ODFileSpec* newSpec, ODBoolean isDuplicate )
- {
- // This will fail if a file with the old name already exists in the
- // target directory. MoreFiles (DTS) has a more robust version of this.
-
- ASSERT(newSpec->vRefNum == fFileSpec.vRefNum, kODErrAssertionFailed);
-
- if ( isDuplicate )
- {
- THROW_IF_ERROR( FSpDelete( newSpec ) );
- }
-
- this->Move( newSpec->parID );
- this->Rename( newSpec->name );
- } // MoveRename()
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::Move
- //------------------------------------------------------------------------------
-
- void PlatformFile::Move( ODSLong targetParID )
- {
- CMovePBRec paramBlock ;
- memset( ¶mBlock, 0, sizeof(paramBlock) );
-
- paramBlock.ioNamePtr = fFileSpec.name ;
- paramBlock.ioVRefNum = fFileSpec.vRefNum ;
- paramBlock.ioNewDirID = targetParID ;
- paramBlock.ioDirID = fFileSpec.parID ;
-
- (void) HDelete(fFileSpec.vRefNum,targetParID,fFileSpec.name); // ignore error (may not exist)
- OSErr err = PBCatMoveSync( ¶mBlock );
- THROW_IF_ERROR( err );
-
- fFileSpec.parID = targetParID ;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::UniquifyName
- // Given in this a platformfile (whose filespec only is used) that may conflict
- // with an existing file, deal with this conflict in one of two ways depending
- // on the value of action. The two values are:
- // 1. kSpecifyNewNameOnly: just change the name field of the filespec so that the
- // platform file represents a file that would be unique if created
- // 2. kRenameInPlace: this file already exists, but we want it to have a different
- // name so we can reuse this one. Find that name, and rename the actual file.
- //
- // Two string templates are expected, and the caller can either pass in their
- // resource IDs or StringHandles to the strings themselves, signifying the latter
- // with a resource ID of kODNoResourceID. The first of these strings is used
- // the first time through the renaming loop (which typically sticks something
- // like " copy" on the end of the file name, and the second is used thereafter
- // (when increasingly large numbers are put into the string in an attempt to
- // make it unique.
- //------------------------------------------------------------------------------
-
- void PlatformFile::UniquifyName( ODSShort uniquifyingStringID,
- StringHandle uniquifyingString,
- ODSShort uniquifyingNumberID,
- StringHandle uniquifyingNumberString,
- short copyCount,
- PFUniquifyAction action,
- ODBoolean forceNewName)
- {
- if ((forceNewName!=kODTryCurrentName) || this->Exists() )
- {
- PlatformFile* possibleOther = new PlatformFile;
- TempPlatformFile t = possibleOther; // save so will get deconstructed
- // possibleOther->SpecifyFromFile( this );
-
- // Get the strings to be used in substitution if they weren't passed in.
- // Assign them to tempobjs so we don't have to dispose later. Don't assign
- // if they're passed in (of course....)
- TempODHandle registerNoNumHandleIfLocal = kODNULL;
- TempODHandle registerNumHandleIfLocal = kODNULL;
- CUsingLibraryResources r;
- if ( uniquifyingStringID != kODNoResourceID )
- {
- WASSERT( !uniquifyingString );
- uniquifyingString = GetString( uniquifyingStringID );
- DetachResource( (Handle)uniquifyingString );
- registerNoNumHandleIfLocal = (Handle)uniquifyingString;
- WASSERT( uniquifyingString );
- }
- if ( uniquifyingNumberID != kODNoResourceID )
- {
- WASSERT(!uniquifyingNumberString);
- uniquifyingNumberString = GetString( uniquifyingNumberID );
- DetachResource( (Handle)uniquifyingNumberString );
- registerNumHandleIfLocal = (Handle)uniquifyingNumberString;
- }
- WASSERT(uniquifyingNumberString);
-
- ODFileSpec localCopy = this->GetFileSpec();
- // save the name (as we'll be munging localCopy)
- Str63 originalName;
- ODBlockMove( localCopy.name, originalName, localCopy.name[0]+1 );
-
- TempODHandle baseText = ODNewHandle(kMaxFileNameSize+1);
- THROW_IF_NULL(baseText);
- TempODHandle substitutionText = ODNewHandle(kMaxFileNameSize+1);
- THROW_IF_NULL(substitutionText);
-
- ODBoolean nameNeedsNumber = (uniquifyingString == kODNULL);
- // if there is no uniquifyingString, we immediately need to start using
- // the uniquifyingNumberString, or in other words nameNeedsNumber==true.
-
- for ( ; ; nameNeedsNumber = kODTrue)
- {
- // nameNeedsNumber = copyCount > 1;
- StringHandle templateToUse = nameNeedsNumber ?
- uniquifyingNumberString : uniquifyingString;
-
- short thisTemplateLen = **templateToUse;
- // <eeh> NOTE that this forces callers to have two ^number tuples in the
- // second template.
- thisTemplateLen -= nameNeedsNumber? 4 : 2;
-
- short numberLen;
- Str32 numberString;
- if ( nameNeedsNumber )
- {
- NumToString( copyCount, numberString );
- numberLen = numberString[0];
- }
- else
- numberLen = 0;
-
- // truncate the name if after appending it will be too long
- Str63 localName;
- ODBlockMove( originalName, localName, originalName[0] + 1 );
- short postAppendLen = localName[0] + thisTemplateLen + numberLen;
- if ( postAppendLen > kODMaxFileNameSize )
- ClipStringToBytes( localName,
- kODMaxFileNameSize - thisTemplateLen - numberLen, fScriptTag );
-
- // copy the template into the base handle, then pass in the possible file
- // name
- short len;
- SetHandleSize( baseText, len = **templateToUse );
- ODBlockMove( (*templateToUse)+1, *baseText, len );
- SetHandleSize( substitutionText, len = localName[0] );
- ODBlockMove( &localName[1], *substitutionText, len );
- short err = ReplaceText( baseText, substitutionText, "\p^0" );
- WASSERT( err >= 0 );
-
- if ( nameNeedsNumber ) // do same for number
- {
- SetHandleSize( substitutionText, len = numberString[0] );
- ODBlockMove( &numberString[1], *substitutionText, len );
- err = ReplaceText( baseText, substitutionText, "\p^1" );
- WASSERT( err >= 0 );
- }
-
- ODBlockMove( *baseText, &localCopy.name[1], len = GetHandleSize(baseText) );
- localCopy.name[0] = len;
-
- possibleOther->Specify( &localCopy );
- if ( !possibleOther->Exists() )
- {
- WASSERT( localCopy.name[0] <= kODMaxFileNameSize );
- if ( action == kSpecifyNewNameOnly )
- {
- // set up this so that when created it will represent a unique file
- PascalToCString( localCopy.name );
- this->SetAsciiName( (char*)localCopy.name );
- }
- else if ( action == kRenameInPlace )
- {
- // put the original file spec back in the target, then call
- // Rename passing in the new name
- WASSERT(this->Exists());
- this->Rename( localCopy.name );
- }
- else
- WARN( "unknown PFUniquifyAction" );
- break;
- }
- if (nameNeedsNumber)
- ++copyCount;
- // Gets executed after 2nd time through loop if there was a valid
- // uniquifyString.
- // Otherwise gets executed after 1st time through loop.
- }
- }
- } // UniquifyName
-
- //------------------------------------------------------------------------------
- // PlatformFile::MoveToTrash
- //------------------------------------------------------------------------------
-
- void PlatformFile::MoveToTrash()
- {
- ODSLong parID = fFileSpec.parID;
- ODSLong trashDirID;
- THROW_IF_ERROR(FindFolder(fFileSpec.vRefNum, kTrashFolderType, kCreateFolder,
- &(fFileSpec.vRefNum), &trashDirID));
-
- // Move deletes any file that may conflict with the file once moved, but
- // in this case that isn't what we want. So check if such a file exists,
- // and if so rename the conflicting file first (following the Finder's
- // model.)
- ODFileSpec possibleOtherFS = this->GetFileSpec();
- possibleOtherFS.parID = trashDirID;
- PlatformFile target; // represents a file that *may* be in the trash
- target.Specify( &possibleOtherFS );
-
- #if 1
- // if ( target.Exists() )
- {
- CUsingLibraryResources r;
- target.UniquifyName( kCopyDefaultNameNoNumStrID, kODNULL,
- kCopyDefaultNameWithNumStrID, kODNULL, 2, kRenameInPlace,
- kODTryCurrentName ) ;
- }
- #else
- Str32 uniqueName;
- if ( MakeUniqueFileName( &target, kCopyDefaultNameNoNumStrID,
- kCopyDefaultNameWithNumStrID, 31, uniqueName ) )
- target.Rename( uniqueName );
- #endif
- this->Move(trashDirID);
-
- CInfoPBRec pbRec;
- pbRec.hFileInfo.ioCompletion = NULL;
- pbRec.hFileInfo.ioNamePtr = fFileSpec.name;
- pbRec.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbRec.hFileInfo.ioFDirIndex = 0;
- pbRec.hFileInfo.ioDirID = fFileSpec.parID;
-
-
- if ( PBGetCatInfoSync( &pbRec ) == noErr )
- {
- // <eeh> stuffing this field *may* not work under Copland
- pbRec.hFileInfo.ioFlXFndrInfo.fdPutAway = parID;
- // this was changed by PBGetCatInfoSync...
- pbRec.hFileInfo.ioDirID = fFileSpec.parID;
- (void)PBSetCatInfoSync( &pbRec ); // ignore the error
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::Rename
- // This routine will not yet delete a file that will prevent the
- // renaming (as Move() does above.)
- //------------------------------------------------------------------------------
- void PlatformFile::Rename( Str63 newName )
- {
- this->UpdateSpecFromID();
-
- THROW_IF_ERROR( FSpRename( &fFileSpec, newName ) );
- CopyPascalString(fFileSpec.name, newName);
- BumpFolderModDate();
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetFileModDate
- // This routine will set the file modification date to the input parameter
- //------------------------------------------------------------------------------
- ODTime PlatformFile::GetFileModDate()
- {
- this->UpdateSpecFromID();
-
- CInfoPBRec pbBlock;
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fFileSpec.name;
- pbBlock.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- THROW_IF_ERROR(PBGetCatInfoSync(&pbBlock));
- return pbBlock.hFileInfo.ioFlMdDat;
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetFileModDate
- // This routine will set the file modification date to the input parameter
- //------------------------------------------------------------------------------
- void PlatformFile::SetFileModDate(ODTime date)
- {
- this->UpdateSpecFromID();
-
- if (!this->IsLocked()) {
- CInfoPBRec pbBlock;
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fFileSpec.name;
- pbBlock.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- if (PBGetCatInfoSync(&pbBlock) == noErr) {
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- pbBlock.hFileInfo.ioFlMdDat = date;
- (void) PBSetCatInfoSync(&pbBlock); /* who cares if it fails */
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetFileCreationDate
- // This routine will set the file creation date to the input parameter
- //------------------------------------------------------------------------------
- void PlatformFile::SetFileCreationDate(ODTime date)
- {
- this->UpdateSpecFromID();
-
- CInfoPBRec pbBlock;
-
- if (!this->IsLocked()) {
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fFileSpec.name;
- pbBlock.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- if (PBGetCatInfoSync(&pbBlock) == noErr) {
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- pbBlock.hFileInfo.ioFlCrDat = date;
- (void) PBSetCatInfoSync(&pbBlock); /* who cares if it fails */
- }
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetFileCreationDate
- // This routine will get the file creation date and return it.
- //------------------------------------------------------------------------------
- ODTime PlatformFile::GetFileCreationDate()
- {
- this->UpdateSpecFromID();
-
- CInfoPBRec pbBlock;
- pbBlock.hFileInfo.ioCompletion = kODNULL;
- pbBlock.hFileInfo.ioFDirIndex = 0;
- pbBlock.hFileInfo.ioNamePtr = fFileSpec.name;
- pbBlock.hFileInfo.ioVRefNum = fFileSpec.vRefNum;
- pbBlock.hFileInfo.ioDirID = fFileSpec.parID;
- THROW_IF_ERROR(PBGetCatInfoSync(&pbBlock));
- return pbBlock.hFileInfo.ioFlCrDat;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::BumpFolderModDate
- // This routine will set the file modification date of the parent folder
- // to the current time so as to cause the Finder to refresh the folder if
- // it is open. It only has WARNs if it errors.
- //------------------------------------------------------------------------------
- void PlatformFile::BumpFolderModDate()
- {
- CInfoPBRec theParamBlock;
-
- memset (&theParamBlock, 0, sizeof(theParamBlock));
- // ioNamePtr = 0
- theParamBlock.dirInfo.ioFDirIndex = -1;
- theParamBlock.dirInfo.ioVRefNum = fFileSpec.vRefNum;
- theParamBlock.dirInfo.ioDrDirID = fFileSpec.parID;
- OSErr err = PBGetCatInfoSync(&theParamBlock);
- if( err )
- WARN("Couldn't get dir mod date, err %hd",err);
- else
- {
- ODULong newTime;
-
- GetDateTime(&newTime);
- // set to the future if it is now
- if (theParamBlock.dirInfo.ioDrMdDat >= newTime)
- ++newTime;
- theParamBlock.dirInfo.ioDrMdDat = newTime;
- err = PBSetCatInfoSync(&theParamBlock);
- if( err )
- WARN("Couldn't bump dir mod date, err %hd",err);
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetFirstLocalPath
- //------------------------------------------------------------------------------
-
- ODFileRefNum PlatformFile::GetFirstLocalPath( ODForkType fork )
- {
- ODFileSpec* spec = &fFileSpec;
-
- OSErr result;
- FCBPBRec pb;
- short index;
- Str31 tempName;
-
- /* Get FCB name in tempName */
- pb.ioNamePtr = tempName;
-
- /* Index through the open paths on the volume specified by fFileSpec.vRefNum */
- pb.ioVRefNum = fFileSpec.vRefNum;
- index = 1;
- do
- {
- pb.ioRefNum = 0;
- pb.ioFCBIndx = index;
- result = PBGetFCBInfoSync(&pb);
- if ( result == noErr )
- {
- /*
- ** See if parent directory ID matches and
- ** file name matches and
- ** the file fork (resource or data) matches
- */
- if ( (pb.ioFCBParID == fFileSpec.parID) &&
- EqualString(fFileSpec.name, tempName, false, true) &&
- ((fork == kODResourceFork) == ((pb.ioFCBFlags & (1 << 9)) != 0)) )
- {
- return pb.ioRefNum; // Found it!
- }
- ++index; /* next FCB index */
- }
- } while ( result == noErr );
-
- return kODNoFileRefNum;
- }
-
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetLocalPaths
- //------------------------------------------------------------------------------
-
- ODError PlatformFile::GetLocalPaths(
- ODForkType fork,
- ODULong *refNumCount,
- ODFileRefNumPtr *refNums)
- {
- const ODULong kMaxFCBs = 348; /* The maximum number of local access paths under System 7 */
-
- OSErr result;
- FCBPBRec pb;
- short index;
- Str31 tempName;
- ODFileRefNumPtr tempRefNums;
-
- /* initialize returned values */
- *refNumCount = 0;
- *refNums = NULL;
-
- /* Allocate temp storage for refNum matches */
- tempRefNums = (ODFileRefNumPtr)ODNewPtr(kMaxFCBs * sizeof(short));
-
- if ( tempRefNums != NULL )
- {
- /* Get FCB name in tempName */
- pb.ioNamePtr = tempName;
-
- /* Index through the open paths on the volume specified by fFileSpec.vRefNum */
- pb.ioVRefNum = fFileSpec.vRefNum;
- index = 1;
- do
- {
- pb.ioRefNum = 0;
- pb.ioFCBIndx = index;
- result = PBGetFCBInfoSync(&pb);
- if ( result == noErr )
- {
- /*
- ** See if parent directory ID matches and
- ** file name matches and
- ** the file fork (resource or data) matches
- */
- if ( (pb.ioFCBParID == fFileSpec.parID) &&
- EqualString(fFileSpec.name, tempName, false, true) &&
- ((fork == kODResourceFork) == ((pb.ioFCBFlags & (1 << 9)) != 0)) )
- {
- /* It's a match - add it to the array of matches */
- tempRefNums[*refNumCount] = pb.ioRefNum;
- ++(*refNumCount);
- }
- ++index; /* next FCB index */
- }
- } while ( result == noErr );
-
- /* These errors are OK - they mean we hit the end of the FCB list */
- if ( (result == rfNumErr) || (result == fnOpnErr) )
- {
- result = noErr;
- }
-
- if ( (result == noErr) && (*refNumCount != 0) )
- {
- // Note: the below two lines were a gratuitous change from the tested code
- // given to me by Jim Luther. Therefore I have commented them out and returned
- // the original code. -Tantek
- //*refNums = (ODFileRefNumPtr) ODReallocate( tempRefNums, *refNumCount * sizeof(short) );
- //*tempRefNums = kODNULL;
- /* Allocate memory to return refNum matches in */
- *refNums = (ODFileRefNumPtr)ODNewPtr(*refNumCount * sizeof(short));
- if ( *refNums != NULL )
- {
- /* Move refNums from tempRefNums to *refNums */
- ODBlockMove((Ptr)tempRefNums, (Ptr)*refNums, (*refNumCount * sizeof(short)));
- }
- else
- {
- /* Couldn't allocate memory for refNum array */
- result = memFullErr;
- }
-
- }
-
- /* Free up tempRefNums storage */
- ODDisposePtr((Ptr)tempRefNums);
- }
- else
- {
- /* Couldn't allocate temp memory */
- result = memFullErr;
- }
-
- return ( result );
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetComments
- //
- // If a pointer is passed in, the text is placed there and a pointer to it is
- // returned. If the comments pointer is null, then a new pointer is allocated
- // and returned.
- //------------------------------------------------------------------------------
-
- enum {
- uppPBDTInfo = kRegisterBased
- | RESULT_SIZE(sizeof(OSErr))
- | REGISTER_RESULT_LOCATION(kRegisterD0)
-
- | REGISTER_ROUTINE_PARAMETER(1, kRegisterD1, SIZE_CODE(kTwoByteCode)) // trap word
- | REGISTER_ROUTINE_PARAMETER(2, kRegisterD0, SIZE_CODE(kTwoByteCode)) // selector
-
- | REGISTER_ROUTINE_PARAMETER(3, kRegisterA0, SIZE_CODE(sizeof(DTPBRec*)))
- | REGISTER_ROUTINE_PARAMETER(4, kRegisterA3, SIZE_CODE(sizeof(void*)))
- };
-
- #if GENERATING68K && GENERATINGCFM
- OSErr PBDTGetCommentSyncGlue(DTPBRec *pb);
- OSErr PBDTGetCommentSyncGlue(DTPBRec *pb)
- {
- void* hfsdispatch = GetOSTrapAddress(0xA260);
- return CallOSTrapUniversalProc((UniversalProcPtr) hfsdispatch,
- uppPBDTInfo,
- (short) 0xA260, // trap word
- (short) 0x002A, // selector
- pb, // a1, the param block ptr
- pb // a3 should be ignored
- );
- }
- #endif
-
- #if GENERATING68K && GENERATINGCFM
- OSErr PBDTSetCommentSyncGlue(DTPBRec *pb);
- OSErr PBDTSetCommentSyncGlue(DTPBRec *pb)
- {
- void* hfsdispatch = GetOSTrapAddress(0xA260);
- return CallOSTrapUniversalProc((UniversalProcPtr) hfsdispatch,
- uppPBDTInfo,
- (short) 0xA260, // trap word
- (short) 0x0028, // selector
- pb, // a1, the param block ptr
- pb // a3 should be ignored
- );
- }
- #endif
-
- ODIText* PlatformFile::GetComments(ODIText* comments)
- {
- DTPBRec pb;
- memset( &pb, 0, sizeof(pb) );
-
- pb.ioVRefNum = fFileSpec.vRefNum;
- OSErr err = PBDTGetPath(&pb);
- if (err == noErr)
- {
- pb.ioNamePtr = fFileSpec.name;
- pb.ioDirID = fFileSpec.parID;
- char buffer[256];
- pb.ioDTBuffer = buffer;
-
- // avoid the crash on 68K if the PlatformFile is remote
- #if GENERATING68K && GENERATINGCFM
- err = PBDTGetCommentSyncGlue(&pb);
- #else
- err = PBDTGetCommentSync(&pb);
- #endif
- if (err == noErr) {
- buffer[pb.ioDTActCount] = 0; // make it a c string
- if (comments == kODNULL)
- {
- ODScriptCode script = FontToScript( GetSysFont() );
- comments = CreateITextCString(script,
- GetScriptVariable( script, smScriptLang ), buffer);
- }
- else
- SetITextCString(comments, buffer);
- }
- }
-
- return comments;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetComments
- //------------------------------------------------------------------------------
-
- void
- PlatformFile::SetComments(ODIText* comments)
- {
- DTPBRec pb;
- OSErr err = noErr; // PBDTGetPath seems not to return anything,
- // so must init
-
- pb.ioNamePtr = kODNULL;
- pb.ioVRefNum = fFileSpec.vRefNum;
- err = PBDTGetPath(&pb);
- if (err == noErr)
- {
- Str255 commentStr;
-
- pb.ioNamePtr = fFileSpec.name;
- pb.ioDirID = fFileSpec.parID;
- pb.ioDTBuffer = (char *)&commentStr[1];
- if (comments) {
-
- ODULong numBytes = GetITextStringLength(comments);
- if (numBytes > kMaxCommentSize) {
- GetITextPString(comments, commentStr);
- pb.ioDTReqCount = ClipStringToBytes(commentStr, kMaxCommentSize,
- GetITextScriptCode(comments) );
- } else {
- pb.ioDTBuffer = GetITextPtr(comments);
- pb.ioDTReqCount = numBytes;
- }
- }
- else
- pb.ioDTReqCount = 0;
- // avoid the crash on 68K if the PlatformFile is remote
- #if GENERATING68K && GENERATINGCFM
- err = PBDTSetCommentSyncGlue(&pb);
- #else
- err = PBDTSetCommentSync(&pb);
- #endif
- }
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::GetCustomIconFamily
- //------------------------------------------------------------------------------
-
- ODIconFamily
- PlatformFile::GetCustomIconFamily()
- {
- ODIconFamily icons = kODNULL; ODVolatile(icons);
-
- if (HasCustomIcon())
- {
- // read icons from the file
- SetPermission(fsRdPerm);
- // OpenResFile();
- TRY
- for( long i=5; i>=0; i-- )
- {
- ODULong size;
- TempODPtr ptr = this->ReadResourcePtr(kIconType[i], kCustomIconResource, &size);
- if (ptr != kODNULL)
- {
- if (icons == kODNULL)
- THROW_IF_ERROR( NewIconSuite(&icons) );
- Handle icon = (Handle) ODNewHandle(size);
- ODBlockMove(ptr,*icon,size);
- OSErr err = AddIconToSuite(icon, icons, kIconType[i]);
- if( err ) {
- ODDisposePtr(icon);
- THROW(err);
- }
- }
- }
- CATCH_ALL
- WARN("Ignoring error %ld",ErrorCode());
- if( icons ) DisposeIconSuite(icons,kODTrue);
- ENDTRY
- // CloseResFile();
- }
- return icons;
- }
-
- //------------------------------------------------------------------------------
- // PlatformFile::SetCustomIconFamily
- //------------------------------------------------------------------------------
-
- void
- PlatformFile::SetCustomIconFamily(ODIconFamily icons)
- {
- // set with kODNULL as the icons to delete the custom icons
- TRY
- if (!icons)
- {
- // check to see if there's a resFile so that we don't
- // create one while trying to delete nonexistant icons
- SetPermission(fsRdPerm);
- OpenResFile(); // THROW if no resFile
- CloseResFile();
- }
- // write icons to the file
- SetPermission(fsRdWrPerm);
- OpenResFile();
- for( long i=5; i>=0; i-- )
- {
- Handle icon;
- char state;
-
- if( icons )
- THROW_IF_ERROR( GetIconFromSuite(&icon, icons, kIconType[i]) );
- else
- icon = kODNULL;
- if (icon)
- {
- state = HGetState(icon);
- HLock(icon);
- WASSERT(GetHandleSize(icon) == kIconSize[i]);
- WriteResourcePtr(kIconType[i], kCustomIconResource, *icon, kIconSize[i]);
- HSetState(icon, state);
- } else
- DeleteResource(kIconType[i], kCustomIconResource);
- }
- CloseResFile();
- CATCH_ALL
- ENDTRY
- SetCustomIcon(icons != kODNULL);
- }
-