diff --git a/src/osgDB/FileUtils.cpp b/src/osgDB/FileUtils.cpp index 3216ec7cd..c66b59cb2 100644 --- a/src/osgDB/FileUtils.cpp +++ b/src/osgDB/FileUtils.cpp @@ -1,395 +1,9 @@ -#if defined(WIN32) &&!defined(__CYGWIN__) -#include -#include -#include -#elif !defined(macintosh) // UNIX -#include -#include -#endif - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -using namespace osg; -using namespace osgDB; - -// follows is definition of strdup for compatibility under mac, -// However, I'd prefer to migrate all the findFindInPath tools to use -// std::string's and then be able to remove the following definition. -// My objective is to minimize the number of platform #ifdef's as they -// are source of potential bugs and developer confusion. -#ifdef macintosh -#ifndef strdup -inline static char* strdup(const char *src); - -inline static char* strdup(const char *src) -{ - char *ret = (char *) std::malloc(std::strlen(src) +1); - if(!ret) return NULL; - - return std::strcpy(ret, src); -} -#endif -#endif - -#define FILEUTILS_MAX_PATH_LENGTH 2048 - -#if defined(WIN32) &&!defined(__CYGWIN__) -char *PathDelimitor = ";"; -static const char *s_default_file_path = ".;"; -static const char *s_default_dso_path = "C:/Windows/System/;"; -static char *s_filePath = ".;"; -#elif macintosh -char *PathDelimitor = " "; -static const char *s_default_file_path = ":"; -static const char *s_default_dso_path = ":"; -static char *s_filePath = ":"; -#elif __sgi -char *PathDelimitor = ":"; -static const char *s_default_file_path = ".:"; -static const char *s_default_dso_path = "/usr/lib32/:/usr/local/lib32/"; -static char *s_filePath = ".:"; -#else -char *PathDelimitor = ":"; -static const char *s_default_file_path = ".:"; -#if defined(__CYGWIN__) -static const char *s_default_dso_path = "/usr/lib/:/usr/local/lib/:"; -#else -static const char *s_default_dso_path = "/usr/lib/:/usr/local/lib/:"; -#endif // __CYGWIN__ -static char *s_filePath = ".:"; -#endif - -#if defined(WIN32) &&!defined(__CYGWIN__) -#define F_OK 4 -#endif - -static bool s_filePathInitialized = false; - -void osgDB::initFilePath( void ) -{ - char *ptr; - if( (ptr = getenv( "OSGFILEPATH" )) ) - { - notify(DEBUG_INFO) << "osgDB::Init("< -#include - -osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName) -{ - osgDB::DirectoryContents contents; - - WIN32_FIND_DATA data; - HANDLE handle = FindFirstFile((dirName + "\\*").c_str(), &data); - if (handle != INVALID_HANDLE_VALUE) - { - do - { - contents.push_back(data.cFileName); - } - while (FindNextFile(handle, &data) != 0); - - FindClose(handle); - } - return contents; -} - -#elif !defined(macintosh) // UNIX - -#include - -osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName) -{ - osgDB::DirectoryContents contents; - - DIR *handle = opendir(dirName.c_str()); - if (handle) - { - dirent *rc; - while((rc = readdir(handle))!=NULL) - { - contents.push_back(rc->d_name); - } - closedir(handle); - } - - return contents; -} + #include "FileUtils_Windows.cpp" +#elif defined(TARGET_API_MAC_CARBON) + #include "FileUtils_Mac.cpp" +#else + #include "FileUtils_Unix.cpp" #endif diff --git a/src/osgDB/FileUtils_Mac.cpp b/src/osgDB/FileUtils_Mac.cpp new file mode 100644 index 000000000..be8bb8704 --- /dev/null +++ b/src/osgDB/FileUtils_Mac.cpp @@ -0,0 +1,546 @@ +// FileUtil_Mac asses that defined(TARGET_API_MAC_CARBON) is valid. +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +using namespace osg; +using namespace osgDB; +using namespace std; + +// follows is definition of strdup for compatibility under mac, +// However, I'd prefer to migrate all the findFindInPath tools to use +// std::string's and then be able to remove the following definition. +// My objective is to minimize the number of platform #ifdef's as they +// are source of potential bugs and developer confusion. + +#define FILEUTILS_MAX_PATH_LENGTH 2048 + +char *PathDelimitor = " "; +static const char *s_default_file_path = ":"; +static const char *s_default_dso_path = ":"; +static char *s_filePath = ":"; + +static bool s_filePathInitialized = false; + +// MACOS utilities + + /** MAC Carbon only : get an FSSpec for the named file system object (file or folder) contained within the specified folder + ridiculous that this kind of thing doesn't seem to be built into carbon. or manybe I'm just not finding it ? + give me back my cocoa. + TODO : we should probably do a version of this routine that searches subfolders too + */ +static OSErr getObjectContainedInFolder(const std::string& objectName,FSSpecPtr containingFolder,FSSpecPtr theFSSpecPtr) + { + FSRef theObjectRef; + FSRef containingFolderRef; + CFStringRef unicodeObjectName; + OSErr errCode; + UniChar objectNameChars[ 255 ]; + CFIndex nameLength; + + + errCode=FSpMakeFSRef(containingFolder,&containingFolderRef); // make FSREf to containing folder + if(errCode==noErr) + { + unicodeObjectName=CFStringCreateWithCString (NULL,objectName.c_str(),kCFStringEncodingASCII); + nameLength=CFStringGetLength( unicodeObjectName ); + CFStringGetCharacters( unicodeObjectName, CFRangeMake( 0, nameLength ), &objectNameChars[0] ); + errCode=FSMakeFSRefUnicode (&containingFolderRef,nameLength,objectNameChars,CFStringGetSystemEncoding(),&theObjectRef); + CFRelease(unicodeObjectName); + if(errCode==noErr) + {// the object exists, so we just have to make an FSSpec from the FSRef. + return FSGetCatalogInfo (&theObjectRef, kFSCatInfoNone, NULL,NULL,theFSSpecPtr,NULL); + } + } + return errCode; + } + + /** MAC Carbon only : get an FSSpec for the named file system object (file or folder) contained within the specified folder + this just makes an FSSpec and calls the getObjectContainedInFolder +*/ + + static OSErr getObjectContainedInFolder(const std::string& objectName,SInt16 containingFolderVolRef, SInt32 containingFolderDirID,FSSpecPtr theFSSpecPtr) + { + FSSpec container; + OSErr errCode; + errCode=FSMakeFSSpec(containingFolderVolRef,containingFolderDirID,(ConstStr255Param)"",&container); + if(errCode==noErr) + { + errCode=getObjectContainedInFolder(objectName,&container,theFSSpecPtr); + } + return errCode; +} +/** MAC Carbon only : get an FSSpec for the current application package. + this is mostly useful for finding the Plug-ins directory if the application chooses to store plugins in a folder next + to the application in the "old fashioned" way. + This code directly taken from Apple technote TN2015 (locating application support files under OSX) + TODO - this currently only supports applications that are built as a bundle, not simple unix style exectutables. + The technote above describes how to support this situation and we should probably add support for that at some point. But I need to sleep now. +*/ +static OSErr getApplicationFSSpec(FSSpecPtr theFSSpecPtr) + { + OSErr err = fnfErr; + CFBundleRef myAppsBundle = CFBundleGetMainBundle(); + if (myAppsBundle == NULL) return err; + CFURLRef myBundleURL = CFBundleCopyBundleURL(myAppsBundle); + if (myBundleURL == NULL) return err; + + FSRef myBundleRef; + Boolean ok = CFURLGetFSRef(myBundleURL, &myBundleRef); + CFRelease(myBundleURL); + if (!ok) return err; + + return FSGetCatalogInfo(&myBundleRef, kFSCatInfoNone, NULL, NULL, theFSSpecPtr, NULL); + } + +/** MAC Carbon only : returns an FSSpec for the folder containing the specified file system object +*/ + static OSErr getParentFolder(FSSpecPtr theFSSpec, FSSpecPtr theParentSpec) + { + FSRef theSubjectRef; + FSRef theParentRef; + OSErr theErr; + + theErr=FSpMakeFSRef(theFSSpec,&theSubjectRef); + if(theErr==noErr) + { + theErr=FSGetCatalogInfo(&theSubjectRef, kFSCatInfoNone, NULL, NULL, NULL, &theParentRef); + if(theErr==noErr) + { + theErr=FSGetCatalogInfo(&theParentRef, kFSCatInfoNone, NULL, NULL, theParentSpec, NULL); + } + } + return theErr; + } + + /** MAC Carbon only : get an FSSpec for the folder containing the current application package. + this is mostly useful for finding the Plug-ins directory if the application chooses to store plugins in a folder next + to the application in the "old fashioned" way. +*/ +static OSErr getApplicationParentFolderFSSpec(FSSpecPtr theFolder) +{ + FSSpec theApp; + OSErr theErr; + + theErr=getApplicationFSSpec(&theApp); + if(theErr==noErr) + { + theErr=getParentFolder(&theApp,theFolder); + } + return theErr; +} + + +/** MAC Carbon only : get an FSSpect for a sub folder of the parent folder of the current application. + this is mostly useful for finding things like "plug-in" directories. Note that the proper place to put this kind of + thing is now supposed to be the "Application Support" folder. +*/ +static OSErr getApplicationPeerFolderFSSpec(const std::string& folderName,FSSpecPtr theFSSpecPtr) + { + FSSpec applicationFolder; + OSErr errCode; + + errCode=getApplicationParentFolderFSSpec(&applicationFolder); + if(errCode==noErr) + { + return getObjectContainedInFolder(folderName,&applicationFolder,theFSSpecPtr); + } + return errCode; // file not found error + } + + /** MAC carbon only : returns the posix style path to a file specified in an FSSpec + returns NULL if the file object pointed to by the FSSpec doesn't exist + */ +static char * pathFromFSSpec(FSSpecPtr theFSSpec) + { + FSRef theObjectRef; + char pathTmp[1024]; + char *path=NULL; + CFURLRef theObjectURL; + OSErr errCode; + + errCode=FSpMakeFSRef(theFSSpec,&theObjectRef); + if(errCode==noErr) + { + theObjectURL=CFURLCreateFromFSRef(NULL,&theObjectRef); + if(theObjectURL!=NULL) + { + CFStringRef thePath=CFURLCopyFileSystemPath(theObjectURL,kCFURLPOSIXPathStyle); // maybe should be HFS style on OS9 ? + CFStringGetCString(thePath,pathTmp,1024,kCFStringEncodingASCII); + path=strdup( pathTmp ); + CFRelease(theObjectURL);CFRelease(thePath); + } + } + return path; + } + + /** MAC Carbon only : checks for the existance of a file (replaces unix access() for OS8/9 platform) +*/ +static bool checkFileExists(const char *filePath) +{ + CFURLRef fileURL; + FSRef fileRef; + bool fileExists; + //if(gestalt(gestaltFSAttr)==noErr) + //{ + // if(gestaltReply & gestaltFSUsesPOSIXPathsForConversion) + //CFURLCreateWithFileSystemPath(ilePath, kCFURLPOSIXPathStyle, Boolean isDirectory); + // FSPathMakeRef is only implemented on OSX, so can't use that. + + fileURL=CFURLCreateFromFileSystemRepresentation(NULL,(const UInt8 *)filePath,strlen(filePath),false); // hopefully this isolates us from dealing with what form the path is in - i think it should assume the native path format for the platfrom we're running on. + fileExists=CFURLGetFSRef(fileURL,&fileRef); + CFRelease(fileURL); + return fileExists; +} + + /** MAC carbon only : returns the file path of a CFURLRef as a C string. + you're responsible for disposing of the string when you're done +*/ +static char *pathFromCFURL(CFURLRef theURL) +{ + UInt8 pathTmp[1024]; // temporary buffer for path + char *path=NULL; + if(theURL!=NULL) + { + CFURLGetFileSystemRepresentation(theURL,false,pathTmp,1024); // TODO this can fail somehow - not sure what to do if it does + path=strdup( (char*)pathTmp ); + } + return path; // phew +} + +/** MAC carbon only : searches the given bundle for a named resource and returns the path to it if it exists, otherwise NULL +*/ +static char *getPathOfResourceInBundle(const std::string& resourceName,CFBundleRef theBundle) +{ + CFStringRef fileNameString=CFStringCreateWithCString (NULL,resourceName.c_str(),kCFStringEncodingASCII); + CFURLRef fileURL=CFBundleCopyResourceURL( theBundle, fileNameString, NULL, NULL); // look for a resource with the specified name + CFRelease(fileNameString); + if(fileURL!=NULL) + { + notify( DEBUG_INFO ) << "found file:" << resourceName << " as a bundle resource" << endl; + char *thePath=pathFromCFURL(fileURL); + CFRelease(fileURL); + return thePath; + } + return NULL; +} + +/** MAC carbon only : returns the path to a resource in the Application bundle as a string + returns NULL if the resource doesn't exist +*/ +static char *getPathOfApplicationResource(const std::string& resourceName) +{ + CFBundleRef theSearchBundle=CFBundleGetMainBundle(); + char *thePath=getPathOfResourceInBundle(resourceName,theSearchBundle); + return thePath; +} + +// end mac utilites + +void osgDB::initFilePath( void ) +{ + char *ptr; + if( (ptr = getenv( "OSGFILEPATH" )) ) + { + notify(DEBUG_INFO) << "osgDB::Init("< +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +using namespace osg; +using namespace osgDB; + + +#define FILEUTILS_MAX_PATH_LENGTH 2048 + +#if __sgi +char *PathDelimitor = ":"; +static const char *s_default_file_path = ".:"; +static const char *s_default_dso_path = "/usr/lib32/:/usr/local/lib32/"; +static char *s_filePath = ".:"; +#else +char *PathDelimitor = ":"; +static const char *s_default_file_path = ".:"; +#if defined(__CYGWIN__) +static const char *s_default_dso_path = "/usr/lib/:/usr/local/lib/:"; +#else +static const char *s_default_dso_path = "/usr/lib/:/usr/local/lib/:"; +#endif // __CYGWIN__ +static char *s_filePath = ".:"; +#endif + +static bool s_filePathInitialized = false; + +void osgDB::initFilePath( void ) +{ + char *ptr; + if( (ptr = getenv( "OSGFILEPATH" )) ) + { + notify(DEBUG_INFO) << "osgDB::Init("< +osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName) +{ + osgDB::DirectoryContents contents; + + DIR *handle = opendir(dirName.c_str()); + if (handle) + { + dirent *rc; + while((rc = readdir(handle))!=NULL) + { + contents.push_back(rc->d_name); + } + closedir(handle); + } + + return contents; +} diff --git a/src/osgDB/FileUtils_Windows.cpp b/src/osgDB/FileUtils_Windows.cpp new file mode 100644 index 000000000..fdc367059 --- /dev/null +++ b/src/osgDB/FileUtils_Windows.cpp @@ -0,0 +1,241 @@ +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +using namespace osg; +using namespace osgDB; + + +#define FILEUTILS_MAX_PATH_LENGTH 2048 + +char *PathDelimitor = ";"; +static const char *s_default_file_path = ".;"; +static const char *s_default_dso_path = "C:/Windows/System/;"; +static char *s_filePath = ".;"; + +#define F_OK 4 + +static bool s_filePathInitialized = false; + +void osgDB::initFilePath( void ) +{ + char *ptr; + if( (ptr = getenv( "OSGFILEPATH" )) ) + { + notify(DEBUG_INFO) << "osgDB::Init("< +#include + +osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName) +{ + osgDB::DirectoryContents contents; + + WIN32_FIND_DATA data; + HANDLE handle = FindFirstFile((dirName + "\\*").c_str(), &data); + if (handle != INVALID_HANDLE_VALUE) + { + do + { + contents.push_back(data.cFileName); + } + while (FindNextFile(handle, &data) != 0); + + FindClose(handle); + } + return contents; +}