372 lines
12 KiB
C++
372 lines
12 KiB
C++
/*
|
|
* Copyright 2001 Perforce Software. All rights reserved.
|
|
*
|
|
* This file is part of Perforce - the FAST SCM System.
|
|
*/
|
|
|
|
/*
|
|
* macfile.h - Abstract file layer to handle the many differences on Mac OS X and
|
|
* Classic Mac OS
|
|
*
|
|
* NOTE: -----------------------------------------------------------------
|
|
*
|
|
* Some of the following documentation is obsolete but is left for
|
|
* historical purposes. The need for Mac OS 9 compatibility has gone
|
|
* as has the need for an abstraction that works both with FSRef and FSSpec.
|
|
*
|
|
* MacFile is now a single class with no subclasses and deals solely with
|
|
* FSRefs. Supporting 'apple' files is more of a legacy compatibility
|
|
* feature of Perforce so these classes have been simplified.
|
|
*
|
|
* TextEncodingConverter is no longer needed and the path delimiter is
|
|
* always '/'
|
|
*
|
|
* In the platform table below, the only platform left is MOSX.
|
|
*
|
|
* Okay, on with the docs...
|
|
*
|
|
* -----------------------------------------------------------------------
|
|
*
|
|
* On the Macintosh, there are many different kinds of system apis available that
|
|
* depend on what version of the OS is running, whether or not it is the Classic
|
|
* Mac OS or Mac OS X, and finally, if you are using Carbon, certain APIs expect
|
|
* different input based on if the Carbon app is running on Classic Mac OS or
|
|
* Mac OS X.
|
|
*
|
|
* Some concepts and terminology:
|
|
* ------------------------------
|
|
* FSSpec API - the old file API from Apple that was limited to < 32 char,
|
|
* system codepage filenames.
|
|
*
|
|
* FSRef API - the new file API from Apple that allow
|
|
* for < 256 char, Unicode filenames.
|
|
*
|
|
* CFURL API - the API from Apple that allows us to interchange different
|
|
* path styles (ie: colons on Classic Mac and '/' on MOSX).
|
|
* Requires the use of CFStrings.
|
|
*
|
|
* CFString API - the API from Apple that allows easy manipulation of
|
|
* strings between different codepages and Unicode.
|
|
* Also allows modification of a string as an object.
|
|
*
|
|
* TextEncodingConverter - the API from Apple that allows conversion of
|
|
* different runs of characters from one
|
|
* codepage to another. The big difference between
|
|
* it and CFString is it only works on raw byte arrays.
|
|
* There is no concept of a string object. It is super
|
|
* lo level.
|
|
* Here is a table:
|
|
* ----------------
|
|
* 3 Binaries of P4 builds: Classic, Carbonized, Mac OS X
|
|
*
|
|
* 'MOS8.6' = Standard Mac 8.6 install running Classic P4
|
|
* 'Carbon MOS' = MacOS 8.6/9 with Carbon running Carbon P4
|
|
* 'MOS9' = Standard Mac OS 9 install running Classic P4
|
|
* 'Carbon MOSX' = Mac OS X running Carbon P4
|
|
* 'MOSX' = Mac OS X running Mac OS X P4 (partial Std-C/Carbon calls (for speed))
|
|
*
|
|
* | MOS8.6 | Carbon MOS | MOS9 | Carbon MOSX | MOSX
|
|
*----------------------------------------------------------------------------
|
|
* File API | FSSpec | FSRef | FSRef | FSRef | FSRef
|
|
* Path delimiter | ':' | ':' | ':' | '/' | '/'
|
|
* CFURL? | | X | | X | X
|
|
* CFString? | | X | | X | X
|
|
* TextEncodingConverter? | X | X | X | X | X
|
|
* Perforce Path Delimiter | ':' | ':' | ':' | ':' | '/'
|
|
*
|
|
* There are many different compile options (static) and many different
|
|
* cases to handle as the code runs (dynamic).
|
|
*
|
|
* Static
|
|
* ------
|
|
* - Should use on CFString, CFURL? (yes, with Carbon/MOSX )
|
|
* - What is the path delimiter from Perforce?
|
|
* - Should only use FSRef (yes, with Carbon/MOSX)
|
|
*
|
|
* Dynamic
|
|
* -------
|
|
* - Path delimiter of System (For Carbon)
|
|
* - Are FSRefs available? Fallback to FSSpec (For Classic)
|
|
*
|
|
*
|
|
* Public methods:
|
|
*
|
|
* MACFILE
|
|
* -------------
|
|
* MacFile is an object that represents a file on the disk. You can use this
|
|
* to read and write resource and data forks, set and get comment info, get and
|
|
* set additional Finder Info, and set and get type and creator info (although
|
|
* you can do that with the Finder Info as well).
|
|
*
|
|
* Creation
|
|
* --------
|
|
* GetFromPath() - takes a path, a style, and an encoding and returns an object to
|
|
* represent it. Returns NULL if no object could be made from the path.
|
|
* GetFromFSRef() - If you alread have an FSRef, you can make a MacFile from it.
|
|
* CreateFromPath() - takes a path, style, and encoding and creates a file (or
|
|
* directory) on the disk where the path points. It will not
|
|
* create subdirectories automatically. Returns NULL if no object
|
|
* could be made from the path.
|
|
*
|
|
* GetFileSystem
|
|
* -------------
|
|
* GetFileSystem() - Get the kind of file system the file is on. This only makes
|
|
* sense on Mac OS X.
|
|
* IsDir
|
|
* --------
|
|
* IsDir() - Let's you know if the file is a firectory or not. Some methods should
|
|
* not be called if the file is a directory.
|
|
*
|
|
* Metadata
|
|
* --------
|
|
* GetFInfo() - returns the finder information for this file
|
|
* SetFInfo() - sets the finder information for this file
|
|
* GetFXInfo() - gets the extended finder information for this file
|
|
* SetFXInfo() - sets the extended finder information for this file
|
|
*
|
|
* IsHidden() - determines if the file has its hidden attribute set
|
|
* CreateBundle() - Creates a Core Foundation Bundle from this file. Returns
|
|
* NULL if there is no bundle for this file.
|
|
* IsUnbundledApp() - determines if the file is an application in a single file
|
|
* (the traditional Mac way of making an app)
|
|
* IsBundledApp() - determines if the file is an application directory. (the new
|
|
* way of packaging an application. Like the ".app" programs
|
|
* you get on Mac OS X)
|
|
*
|
|
* IsLocked() - determines if the file has its immutable bit set
|
|
* SetLocked() - sets the file's locked attribute
|
|
*
|
|
* GetTypeAndCreator() - retrieves the type and creator. You can pass NULL if you are
|
|
* not interested in one of them.
|
|
* SetTypeAndCreator() - sets the type and creator.
|
|
*
|
|
* GetComment() - returns the comment and the length.
|
|
* SetComment() - fills in the file comment with the bytes. You pass in the buffer
|
|
* and the size of it
|
|
*
|
|
* Reading and Writing
|
|
* -------------------
|
|
* HasDataFork() - returns if the file has a data fork
|
|
* GetDataForkSize() - returns the size in bytes of the data fork
|
|
* OpenDataFork() - opens the data fork for writing
|
|
* ReadDataFork() - reads data out of the fork. Tries to read requestCount bytes
|
|
* into buffer and returns actualCount bytes as the number acutally
|
|
* read.
|
|
* WriteDataFork() - reads data out of the fork. Tries to write requestCount bytes
|
|
* from buffer and returns actualCount bytes as the number acutally
|
|
* written.
|
|
* SetDataForkPosition() - sets the position relative to the beginning of the file.
|
|
* CloseDataFork() - closes the data for for writing.
|
|
*
|
|
* HasResourceFork() - returns if the file has a rsrc fork
|
|
* GetResourceForkSize() - returns the size in bytes of the rsrc fork
|
|
* OpenResourceFork() - opens the rsrc fork for writing
|
|
* ReadResourceFork() - reads data out of the fork. Tries to read requestCount bytes
|
|
* into buffer and returns actualCount bytes as the number
|
|
* acutally read.
|
|
* WriteResourceFork() - reads data out of the fork. Tries to write requestCount
|
|
* bytes from buffer and returns actualCount bytes as the
|
|
* number acutally written.
|
|
* CloseResourceFork() - closes the fork for for writing.
|
|
*
|
|
* Misc
|
|
* ----
|
|
* GetPrintableFullPath() - returns a C String that you can use for printing which is
|
|
* in the native path format and encoding for the filesystem.
|
|
* GetFSSpec() - returns an FSSpec for the file. If you want a const one, you can
|
|
* capture the return value. If you want a changeable one, pass it in
|
|
* to the method. You can pass NULL (0) in if you like.
|
|
* GetFSRef() - returns an GetFSRef for the file. Can return NULL if one is not
|
|
* available. If you want a const one, you can capture the return value.
|
|
* If you want a changeable one, pass it in to the method. You can
|
|
* pass NULL (0) in if you like.
|
|
*
|
|
*
|
|
*/
|
|
|
|
# if defined (OS_MACOSX)
|
|
|
|
# ifndef __MACFILE_H__
|
|
# define __MACFILE_H__
|
|
|
|
# include <CoreServices/CoreServices.h>
|
|
|
|
# define kMacPathStylePerforce kCFURLPOSIXPathStyle
|
|
|
|
// This switch prefers the 64-bit compatible FSIORefNum type (OS 10.5 and
|
|
// later) to the standard SInt16 type (OS 10.4 and earlier)
|
|
|
|
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED
|
|
#if __MAC_OS_X_VERSION_MIN_ALLOWED <= 1050
|
|
# define P4IORefNum FSIORefNum
|
|
# else
|
|
# define P4IORefNum SInt16
|
|
# endif
|
|
# else
|
|
# define P4IORefNum SInt16
|
|
#endif
|
|
/* ============================= *\
|
|
*
|
|
* ABSTRACT BASE CLASSES
|
|
*
|
|
\* ============================= */
|
|
|
|
class MacFile
|
|
{
|
|
|
|
public:
|
|
|
|
enum {
|
|
FS_HFS = 0,
|
|
FS_UFS,
|
|
FS_NFS
|
|
};
|
|
|
|
//
|
|
// Creation
|
|
//
|
|
static MacFile *
|
|
GetFromPath(
|
|
const char * path,
|
|
OSErr * error );
|
|
|
|
static MacFile *
|
|
GetFromFSRef(
|
|
const FSRef * ref,
|
|
OSErr * error );
|
|
|
|
static MacFile *
|
|
CreateFromPath(
|
|
const char * path,
|
|
Boolean isDirectory,
|
|
OSErr * error );
|
|
|
|
static MacFile *
|
|
CreateFromDirAndName(
|
|
const FSRef & dir,
|
|
CFStringRef name,
|
|
Boolean isDirectory,
|
|
OSErr * outErr );
|
|
|
|
virtual ~MacFile();
|
|
|
|
//
|
|
// File Deletion
|
|
//
|
|
|
|
OSErr Delete();
|
|
|
|
//
|
|
// Determing the file system.
|
|
//
|
|
int GetFileSystemType() const;
|
|
|
|
//
|
|
// Is Directory
|
|
//
|
|
Boolean IsDir() const;
|
|
|
|
//
|
|
// Metadata
|
|
//
|
|
const FInfo * GetFInfo() const;
|
|
OSErr SetFInfo( const FInfo * );
|
|
static void SwapFInfo( FInfo * );
|
|
const FXInfo * GetFXInfo() const;
|
|
OSErr SetFXInfo( const FXInfo * );
|
|
static void SwapFXInfo( FXInfo * );
|
|
|
|
Boolean IsHidden() const;
|
|
CFBundleRef CreateBundle() const;
|
|
Boolean IsUnbundledApp() const;
|
|
Boolean IsBundledApp() const;
|
|
|
|
Boolean IsLocked() const;
|
|
OSErr SetLocked( Boolean lock );
|
|
|
|
OSErr GetTypeAndCreator( UInt32 * type, UInt32 * creator ) const;
|
|
OSErr SetTypeAndCreator( UInt32 type, UInt32 creator );
|
|
|
|
const char * GetComment( int *bufferLength ) const;
|
|
OSErr SetComment( char * buffer, int bufferLength );
|
|
|
|
//
|
|
// Reading and Writing
|
|
//
|
|
Boolean HasDataFork() const;
|
|
ByteCount GetDataForkSize() const;
|
|
OSErr OpenDataFork( SInt8 permissions );
|
|
|
|
OSErr ReadDataFork( ByteCount requestCount, void * buffer,
|
|
ByteCount * actualCount );
|
|
|
|
OSErr WriteDataFork( ByteCount requestCount, const void * buffer,
|
|
ByteCount * actualCount );
|
|
|
|
OSErr SetDataForkPosition( ByteCount offset );
|
|
OSErr CloseDataFork();
|
|
|
|
|
|
Boolean HasResourceFork() const;
|
|
ByteCount GetResourceForkSize() const;
|
|
OSErr OpenResourceFork( SInt8 permissions );
|
|
|
|
OSErr ReadResourceFork( ByteCount requestCount, void * buffer,
|
|
ByteCount * actualCount );
|
|
|
|
OSErr WriteResourceFork( ByteCount requestCount, const void * buffer,
|
|
ByteCount * actualCount );
|
|
|
|
OSErr CloseResourceFork();
|
|
|
|
//
|
|
// Misc
|
|
//
|
|
const char * GetPrintableFullPath() const;
|
|
const FSRef * GetFSRef( FSRef * spec ) const;
|
|
|
|
|
|
private:
|
|
|
|
MacFile( FSRef * file );
|
|
|
|
OSErr LoadCatalogInfo() const;
|
|
OSErr SaveCatalogInfo();
|
|
OSErr PreloadComment() const;
|
|
|
|
|
|
char * fullPath;
|
|
FSRef * file;
|
|
|
|
mutable FSCatalogInfo fileInfo;
|
|
FSCatalogInfoBitmap changedInfoBitmap;
|
|
|
|
P4IORefNum dataForkRef;
|
|
P4IORefNum rsrcForkRef;
|
|
|
|
mutable char * comment;
|
|
mutable short commentLength;
|
|
};
|
|
|
|
|
|
|
|
|
|
/* ============================= *\
|
|
*
|
|
* UTILIY METHODS
|
|
*
|
|
\* ============================= */
|
|
|
|
UniChar GetSystemFileSeparator();
|
|
|
|
CFURLPathStyle GetSystemPathStyle();
|
|
|
|
char * FSRefToPath( const FSRef * ref );
|
|
|
|
|
|
|
|
# endif // __MACFILE_H__
|
|
|
|
|
|
# endif // defined (OS_MACOSX)
|