Rewrote the FileUtils support for data and library file paths, moving the

storage of the path lists into osgDB::Registry, and changed the data
structor from a char* to a std::deque.  Changed a names of couple of the
convinience functions in osgDB/FileUtils to better reflect the two
public FilePathList's - DataFilePathList and the LibraryFilePathList.

Added support into the osgDB::Registry::readNode/Image/Object methods
for pushing and popping the path of the current file being loaded.
This commit is contained in:
Robert Osfield 2002-06-17 21:50:37 +00:00
parent 27412c27c9
commit 6767dd49d0
17 changed files with 502 additions and 714 deletions

View File

@ -5,36 +5,22 @@
#ifndef OSGDB_FILEUTILS
#define OSGDB_FILEUTILS 1
#include <osgDB/Export>
#include <osgDB/Registry>
#include <vector>
#include <deque>
#include <string>
namespace osgDB {
/** initialize the data file path,
* uses OSGFILEPATH environmental
* variable to defined.*/
OSGDB_EXPORT extern void initFilePath( void );
/** set the data file path.*/
OSGDB_EXPORT extern void setFilePath( const char *_path );
/** return true if a file exisits. */
OSGDB_EXPORT extern bool fileExists(const std::string& filename);
/** set the data file path.*/
OSGDB_EXPORT extern const char* getFilePath();
/** find specified file if specified file path.*/
OSGDB_EXPORT extern char *findFileInPath( const char *_file, const char * filePath );
/** find specified file on the set data file path.*/
OSGDB_EXPORT extern char *findFile( const char *file );
/** find specified dso/dll.*/
OSGDB_EXPORT extern char *findDSO( const char *name );
/** simple list of names to represent a directory's contents. */
typedef std::vector<std::string> DirectoryContents;
/** find specified file in specified file path.*/
OSGDB_EXPORT extern std::string findFileInPath(const std::string& filename, const FilePathList& filePath);
/** return the directory/filename of a file if its is contained within specified directory.
* return "" if directory does not contain file. If caseInsensitive is set to true then
@ -43,11 +29,50 @@ typedef std::vector<std::string> DirectoryContents;
*/
OSGDB_EXPORT extern std::string findFileInDirectory(const std::string& fileName,const std::string& dirName,bool caseInsensitive=false);
/** simple list of names to represent a directory's contents. */
typedef std::vector<std::string> DirectoryContents;
/** return the contents of a directory.
* returns an empty array on any error.*/
OSGDB_EXPORT extern DirectoryContents getDirectoryContents(const std::string& dirName);
inline void setDataFilePathList(const FilePathList& filepath) { osgDB::Registry::instance()->setDataFilePathList(filepath); }
inline void setDataFilePathList(const std::string& paths) { osgDB::Registry::instance()->setDataFilePathList(paths); }
inline FilePathList& getDataFilePathList() { return osgDB::Registry::instance()->getDataFilePathList(); }
OSGDB_EXPORT extern std::string findDataFile(const std::string& filename);
/** Convinience class for pushing a path on construction, and popping the path
* and destruction. This helps keep the addition of a path local to a block
* of code, even in the presence of exceptions.*/
class PushAndPopDataPath
{
public:
PushAndPopDataPath(const std::string& path)
{
getDataFilePathList().push_front(path);
}
~PushAndPopDataPath()
{
getDataFilePathList().pop_front();
}
};
inline void setLibraryFilePathList(const FilePathList& filepaths) { osgDB::Registry::instance()->setLibraryFilePathList(filepaths); }
inline void setLibraryFilePathList(const std::string& paths) { osgDB::Registry::instance()->setLibraryFilePathList(paths); }
inline FilePathList& getLibraryFilePathList() { return osgDB::Registry::instance()->getLibraryFilePathList(); }
OSGDB_EXPORT extern std::string findLibraryFile(const std::string& filename);
}
#endif

View File

@ -5,19 +5,24 @@
#ifndef OSGDB_REGISTRY
#define OSGDB_REGISTRY 1
#include <vector>
#include <map>
#include <string>
#include <osg/ref_ptr>
#include <osgDB/DynamicLibrary>
#include <osgDB/ReaderWriter>
#include <osgDB/DotOsgWrapper>
#include <vector>
#include <map>
#include <string>
#include <deque>
namespace osgDB {
/** list of directories to search through which searching for files. */
typedef std::deque<std::string> FilePathList;
/**
Registry is a singleton factory which stores
the reader/writers which are linked in
@ -97,6 +102,46 @@ class OSGDB_EXPORT Registry
const ReaderWriter::Options* getOptions() const { return _options.get(); }
/** initilize both the Data and Library FilePaths, by default called by the
* constructor, so it should only be required if you want to force
* the re-reading of environmental variables.*/
void initFilePathLists() { initDataFilePathList(); initLibraryFilePathList(); }
/** initilize the Data FilePath by reading the OSG_FILE_PATH environmental variable.*/
void initDataFilePathList();
/** Set the data file path using a list of paths stored in a FilePath, which is used when search for data files.*/
void setDataFilePathList(const FilePathList& filepath) { _dataFilePath = filepath; }
/** Set the data file path using a single string deliminated either with ';' (Windows) or ':' (All other platforms), which is used when search for data files.*/
void setDataFilePathList(const std::string& paths) { _dataFilePath.clear(); convertStringPathIntoFilePathList(paths,_dataFilePath); }
/** get the data file path which is used when search for data files.*/
FilePathList& getDataFilePathList() { return _dataFilePath; }
/** get the const data file path which is used when search for data files.*/
const FilePathList& getDataFilePathList() const { return _dataFilePath; }
/** initilize the Library FilePath by reading the OSG_LIBRARY_PATH
* and the appropriate system environmental variables*/
void initLibraryFilePathList();
/** Set the library file path using a list of paths stored in a FilePath, which is used when search for data files.*/
void setLibraryFilePathList(const FilePathList& filepath) { _libraryFilePath = filepath; }
/** Set the library file path using a single string deliminated either with ';' (Windows) or ':' (All other platforms), which is used when search for data files.*/
void setLibraryFilePathList(const std::string& paths) { _libraryFilePath.clear(); convertStringPathIntoFilePathList(paths,_libraryFilePath); }
/** get the library file path which is used when search for library (dso/dll's) files.*/
FilePathList& getLibraryFilePathList() { return _libraryFilePath; }
/** get the const library file path which is used when search for library (dso/dll's) files.*/
const FilePathList& getLibraryFilePathList() const { return _libraryFilePath; }
/** convert a string containing a list of paths deliminated either with ';' (Windows) or ':' (All other platforms) into FilePath represetation.*/
static void convertStringPathIntoFilePathList(const std::string& paths,FilePathList& filepath);
private:
typedef std::map<std::string,osg::ref_ptr<DotOsgWrapper> > DotOsgWrapperMap;
@ -138,6 +183,9 @@ class OSGDB_EXPORT Registry
// options to pass to reader writers.
osg::ref_ptr<ReaderWriter::Options> _options;
FilePathList _dataFilePath;
FilePathList _libraryFilePath;
};

View File

@ -36,15 +36,15 @@ DynamicLibrary::~DynamicLibrary()
DynamicLibrary* DynamicLibrary::loadLibrary(const std::string& libraryName)
{
char* fullLibraryName = osgDB::findDSO( libraryName.c_str() );
if (fullLibraryName==NULL) return NULL;
std::string fullLibraryName = osgDB::findLibraryFile(libraryName);
if (fullLibraryName.empty()) return NULL;
#if defined(WIN32) && !defined(__CYGWIN__)
HANDLE handle = LoadLibrary( fullLibraryName );
HANDLE handle = LoadLibrary( fullLibraryName.c_str() );
if (handle) return osgNew DynamicLibrary(libraryName,handle);
notify(WARN) << "DynamicLibrary::failed loading "<<fullLibraryName<<std::endl;
#elif !defined(macintosh)
HANDLE handle = dlopen( fullLibraryName, RTLD_LAZY );
HANDLE handle = dlopen( fullLibraryName.c_str(), RTLD_LAZY );
if (handle) return osgNew DynamicLibrary(libraryName,handle);
notify(WARN) << "DynamicLibrary::failed loading "<<fullLibraryName<<std::endl;
notify(WARN) << "DynamicLibrary::error "<<dlerror()<<std::endl;

View File

@ -18,9 +18,9 @@ std::string osgDB::getFilePath(const std::string& fileName)
{
// then try windows directory slash.
slash = fileName.find_last_of('\\');
if (slash==std::string::npos) return std::string("");
if (slash==std::string::npos) return std::string();
}
return std::string(fileName.begin(),fileName.begin()+slash+1);
return std::string(fileName,0,slash);
}

View File

@ -1,9 +1,181 @@
// moved each platforms file access definitions into their own file
// to make it easier to manage them.
#if defined(WIN32) && !defined(__CYGWIN__)
#include "FileUtils_Windows.cpp"
#elif defined(TARGET_API_MAC_CARBON)
#ifdef TARGET_API_MAC_CARBON
#include "FileUtils_Mac.cpp"
#else
#include "FileUtils_Unix.cpp"
// implementations for Windows and all Unix's except Mac when TARGET_API_MAC_CARBON defined.
#include <osg/Notify>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
#if defined(WIN32) && !defined(__CYGWIN__)
#include <Io.h>
#include <Windows.h>
#include <Winbase.h>
// set up for windows so acts just like unix access().
#define F_OK 4
#else
// unix.
#include <unistd.h>
#include <dlfcn.h>
#endif
bool osgDB::fileExists(const std::string& filename)
{
return access( filename.c_str(), F_OK ) == 0;
}
std::string osgDB::findFileInPath(const std::string& filename, const FilePathList& filepath)
{
if (filename.empty()) return filename;
if(fileExists(filename)) return filename;
for(FilePathList::const_iterator itr=filepath.begin();
itr!=filepath.end();
++itr)
{
std::string path = *itr + '/'+ filename;
osg::notify(osg::DEBUG_INFO) << "FindFileInPath() : trying " << path << " ...\n";
if(fileExists(path)) return path;
}
return std::string();
}
std::string osgDB::findDataFile(const std::string& filename)
{
if (filename.empty()) return filename;
const FilePathList& filepath = Registry::instance()->getDataFilePathList();
std::string fileFound = findFileInPath(filename, filepath);
if (!fileFound.empty()) return fileFound;
// if a directory is included in the filename, get just the (simple) filename itself and try that
std::string simpleFileName = getSimpleFileName(filename);
if (simpleFileName!=filename)
{
std::string fileFound = findFileInPath(simpleFileName, filepath);
if (!fileFound.empty()) return fileFound;
}
// return empty string.
return std::string();
}
std::string osgDB::findLibraryFile(const std::string& filename)
{
if (filename.empty()) return filename;
const FilePathList& filepath = Registry::instance()->getLibraryFilePathList();
std::string fileFound = findFileInPath(filename, filepath);
if (!fileFound.empty()) return fileFound;
// if a directory is included in the filename, get just the (simple) filename itself and try that
std::string simpleFileName = getSimpleFileName(filename);
if (simpleFileName!=filename)
{
std::string fileFound = findFileInPath(simpleFileName, filepath);
if (!fileFound.empty()) return fileFound;
}
// failed with direct paths,
// now try prepending the filename with "osgPlugins/"
return findFileInPath("osgPlugins/"+simpleFileName,filepath);
}
std::string osgDB::findFileInDirectory(const std::string& fileName,const std::string& dirName,bool caseInsensitive)
{
bool needFollowingBackslash = false;
bool needDirectoryName = true;
osgDB::DirectoryContents dc;
if (dirName.empty())
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else if (dirName=="." || dirName=="./" || dirName==".\\")
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else
{
dc = osgDB::getDirectoryContents(dirName);
char lastChar = dirName[dirName.size()-1];
if (lastChar=='/') needFollowingBackslash = false;
else if (lastChar=='\\') needFollowingBackslash = false;
else needFollowingBackslash = true;
needDirectoryName = true;
}
for(osgDB::DirectoryContents::iterator itr=dc.begin();
itr!=dc.end();
++itr)
{
if ((caseInsensitive && osgDB::equalCaseInsensitive(fileName,*itr)) ||
(fileName==*itr))
{
if (!needDirectoryName) return *itr;
else if (needFollowingBackslash) return dirName+'/'+*itr;
else return dirName+*itr;
}
}
return "";
}
#if defined(WIN32) && !defined(__CYGWIN)
#include <io.h>
#include <direct.h>
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;
}
#else
#include <dirent.h>
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;
}
#endif // unix getDirectoryContexts
#endif // ! target mac carbon

View File

@ -498,49 +498,7 @@ char *osgDB::findDSO( const char *name )
}
std::string osgDB::findFileInDirectory(const std::string& fileName,const std::string& dirName,bool caseInsensitive)
{
bool needFollowingBackslash = false;
bool needDirectoryName = true;
osgDB::DirectoryContents dc;
if (dirName.empty())
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else if (dirName=="." || dirName=="./" || dirName==".\\")
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else
{
dc = osgDB::getDirectoryContents(dirName);
char lastChar = dirName[dirName.size()-1];
if (lastChar=='/') needFollowingBackslash = false;
else if (lastChar=='\\') needFollowingBackslash = false;
else needFollowingBackslash = true;
needDirectoryName = true;
}
for(osgDB::DirectoryContents::iterator itr=dc.begin();
itr!=dc.end();
++itr)
{
if ((caseInsensitive && osgDB::equalCaseInsensitive(fileName,*itr)) ||
(fileName==*itr))
{
if (!needDirectoryName) return *itr;
else if (needFollowingBackslash) return dirName+'/'+*itr;
else return dirName+*itr;
}
}
return "";
}
/***************************************************************************/
// TODO
osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName)
@ -549,3 +507,28 @@ osgDB::DirectoryContents osgDB::getDirectoryContents(const std::string& dirName)
notify(WARN)<<"Warning : MAC implementation doesn't implement getDirectoryContents yet"<<endl;
return contents;
}
std::string osg::findFileInPath(const std::string& filename, const FilePath& filePath)
{
notify(WARN)<<"Warning : MAC implementation doesn't findFileInPath yet"<<endl;
return std::string;
}
std::string osg::findLibraryInPath(const std::string& filename, const FilePath& filePath)
{
notify(WARN)<<"Warning : MAC implementation doesn't findLibraryInPath yet"<<endl;
return std::string;
}
bool osgDB::fileExists(const std::string& filename)
{
CFURLRef fileURL;
FSRef fileRef;
bool fileExists;
fileURL=CFURLCreateFromFileSystemRepresentation(NULL,(const UInt8 *)filename.c_str(),filename.size(),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;
}

View File

@ -1,330 +0,0 @@
#include <unistd.h>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <osg/Notify>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
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 = ".:";
#elif defined(__CYGWIN__)
char *PathDelimitor = ":";
static const char *s_default_file_path = ".:";
static const char *s_default_dso_path = "/usr/bin/:/usr/local/bin/:";
static char *s_filePath = ".:";
#else
char *PathDelimitor = ":";
static const char *s_default_file_path = ".:";
static const char *s_default_dso_path = "/usr/lib/:/usr/local/lib/:";
static char *s_filePath = ".:";
#endif
static bool s_filePathInitialized = false;
void osgDB::initFilePath( void )
{
char *ptr;
if( (ptr = getenv( "OSG_FILE_PATH" )) )
{
notify(DEBUG_INFO) << "osgDB::Init("<<ptr<<")"<<std::endl;
setFilePath( ptr );
}
else if( (ptr = getenv( "OSGFILEPATH" )) )
{
notify(DEBUG_INFO) << "osgDB::Init("<<ptr<<")"<<std::endl;
setFilePath( ptr );
}
else
{
notify(DEBUG_INFO) << "osgDB::Init(NULL)"<<std::endl;
}
s_filePathInitialized = true;
}
void osgDB::setFilePath( const char *_path )
{
char buff[FILEUTILS_MAX_PATH_LENGTH];
notify(DEBUG_INFO) << "In osgDB::setFilePath("<<_path<<")"<<std::endl;
buff[0] = 0;
if( s_filePath != s_default_file_path )
{
strcpy( buff, s_filePath );
}
strcat( buff, PathDelimitor );
strcat( buff, _path );
s_filePath = strdup( buff );
s_filePathInitialized = true;
}
const char* osgDB::getFilePath()
{
return s_filePath;
}
char *osgDB::findFileInPath( const char *_file, const char * filePath )
{
char pathbuff[FILEUTILS_MAX_PATH_LENGTH];
char *tptr, *tmppath;
char *path = 0L;
notify(DEBUG_INFO) << "FindFileInPath() : trying " << _file << " ...\n";
if( access( _file, F_OK ) == 0 )
{
return strdup(_file);
}
tptr = strdup( filePath );
tmppath = strtok( tptr, PathDelimitor );
if (!tmppath) return NULL;
do
{
sprintf( pathbuff, "%s/%s", tmppath, _file );
notify(DEBUG_INFO) << "FindFileInPath() : trying " << pathbuff << " ...\n";
if( access( pathbuff, F_OK ) == 0 ) break;
} while( (tmppath = strtok( 0, PathDelimitor )) );
if( tmppath != (char *)0L )
path = strdup( pathbuff );
::free(tptr);
if (path) notify( DEBUG_INFO ) << "FindFileInPath() : returning " << path << std::endl;
else notify( DEBUG_INFO ) << "FindFileInPath() : returning NULL" << std::endl;
return path;
}
char *osgDB::findFile( const char *file )
{
if (!file) return NULL;
if (!s_filePathInitialized) initFilePath();
char* newFileName = findFileInPath( file, s_filePath );
if (newFileName) return newFileName;
// need to check here to see if file has a path on it.
// now strip the file of an previous path if one exists.
std::string simpleFileName = getSimpleFileName(file);
newFileName = findFileInPath( simpleFileName.c_str(), s_filePath );
return newFileName;
}
/*
Order of precedence for
Under UNIX.
./
OSG_LD_LIBRARY_PATH
s_default_dso_path
LD_LIBRARY*_PATH
Under Windows
./
OSG_LD_LIBRARY_PATH
s_default_dso_path
PATH
*/
char *osgDB::findDSO( const char *name )
{
#if defined(__linux) || defined(__CYGWIN__)
if( access( name, F_OK ) == 0 )
{
if (name[0]!='/')
{
char pathbuff[FILEUTILS_MAX_PATH_LENGTH];
sprintf( pathbuff,"./%s", name );
return (char *)strdup(pathbuff);
}
else
{
return (char *)strdup(name);
}
}
#endif
char path[FILEUTILS_MAX_PATH_LENGTH];
char *ptr;
strcpy( path, "./" );
if((ptr = getenv( "OSG_LD_LIBRARY_PATH" )))
{
strcat( path, PathDelimitor );
strcat( path, ptr );
}
strcat( path, PathDelimitor );
strcat( path, s_default_dso_path );
#ifdef __sgi
// bloody mess see rld(1) man page
#if (_MIPS_SIM == _MIPS_SIM_ABI32)
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
{
strcat( path, PathDelimitor );
strcat( path, ptr );
}
#elif (_MIPS_SIM == _MIPS_SIM_NABI32)
if( !(ptr = getenv( "LD_LIBRARYN32_PATH" )))
ptr = getenv( "LD_LIBRARY_PATH" );
if( ptr )
{
strcat( path, PathDelimitor );
strcat( path, ptr );
}
#elif (_MIPS_SIM == _MIPS_SIM_ABI64)
if( !(ptr = getenv( "LD_LIBRARY64_PATH" )))
ptr = getenv( "LD_LIBRARY_PATH" );
if( ptr )
{
strcat( path, PathDelimitor );
strcat( path, ptr );
}
#endif
#elif defined(__CYGWIN__)
if ((ptr = getenv( "PATH" )))
{
notify(DEBUG_INFO) << "PATH = "<<ptr<<std::endl;
strcat( path, PathDelimitor );
strcat( path, ptr );
}
#else
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
{
strcat( path, PathDelimitor );
strcat( path, ptr );
}
#endif
// check existance of dso assembled direct paths.
char* fileFound = NULL;
fileFound = findFileInPath( name , path );
if (fileFound) return fileFound;
// failed with direct paths,
// now try prepending the filename with "osgPlugins/"
char* prependosgPlugins = osgNew char[strlen(name)+12];
strcpy(prependosgPlugins,"osgPlugins/");
strcat(prependosgPlugins,name);
fileFound = findFileInPath( prependosgPlugins , path );
osgDelete [] prependosgPlugins;
return fileFound;
}
std::string osgDB::findFileInDirectory(const std::string& fileName,const std::string& dirName,bool caseInsensitive)
{
bool needFollowingBackslash = false;
bool needDirectoryName = true;
osgDB::DirectoryContents dc;
if (dirName.empty())
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else if (dirName=="." || dirName=="./" || dirName==".\\")
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else
{
dc = osgDB::getDirectoryContents(dirName);
char lastChar = dirName[dirName.size()-1];
if (lastChar=='/') needFollowingBackslash = false;
else if (lastChar=='\\') needFollowingBackslash = false;
else needFollowingBackslash = true;
needDirectoryName = true;
}
for(osgDB::DirectoryContents::iterator itr=dc.begin();
itr!=dc.end();
++itr)
{
if ((caseInsensitive && osgDB::equalCaseInsensitive(fileName,*itr)) ||
(fileName==*itr))
{
if (!needDirectoryName) return *itr;
else if (needFollowingBackslash) return dirName+'/'+*itr;
else return dirName+*itr;
}
}
return "";
}
#include <dirent.h>
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;
}

View File

@ -1,262 +0,0 @@
#include <Io.h>
#include <Windows.h>
#include <Winbase.h>
#include <stdio.h>
#include <stdlib.h>
#include <osg/Notify>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osgDB/FileUtils>
#include <osgDB/FileNameUtils>
#include <osgDB/Registry>
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( "OSG_FILE_PATH" )) )
{
notify(DEBUG_INFO) << "osgDB::Init("<<ptr<<")"<<std::endl;
setFilePath( ptr );
}
else if( (ptr = getenv( "OSGFILEPATH" )) )
{
notify(DEBUG_INFO) << "osgDB::Init("<<ptr<<")"<<std::endl;
setFilePath( ptr );
}
else
{
notify(DEBUG_INFO) << "osgDB::Init(NULL)"<<std::endl;
}
s_filePathInitialized = true;
}
void osgDB::setFilePath( const char *_path )
{
char buff[FILEUTILS_MAX_PATH_LENGTH];
notify(DEBUG_INFO) << "In osgDB::setFilePath("<<_path<<")"<<std::endl;
buff[0] = 0;
if( s_filePath != s_default_file_path )
{
strcpy( buff, s_filePath );
}
strcat( buff, PathDelimitor );
strcat( buff, _path );
s_filePath = strdup( buff );
s_filePathInitialized = true;
}
const char* osgDB::getFilePath()
{
return s_filePath;
}
char *osgDB::findFileInPath( const char *_file, const char * filePath )
{
char pathbuff[FILEUTILS_MAX_PATH_LENGTH];
char *tptr, *tmppath;
char *path = 0L;
notify(DEBUG_INFO) << "FindFileInPath() : trying " << _file << " ...\n";
if( access( _file, F_OK ) == 0 )
{
return strdup(_file);
}
tptr = strdup( filePath );
tmppath = strtok( tptr, PathDelimitor );
if (!tmppath) return NULL;
do
{
sprintf( pathbuff, "%s/%s", tmppath, _file );
notify(DEBUG_INFO) << "FindFileInPath() : trying " << pathbuff << " ...\n";
if( access( pathbuff, F_OK ) == 0 ) break;
} while( (tmppath = strtok( 0, PathDelimitor )) );
if( tmppath != (char *)0L )
path = strdup( pathbuff );
::free(tptr);
if (path) notify( DEBUG_INFO ) << "FindFileInPath() : returning " << path << std::endl;
else notify( DEBUG_INFO ) << "FindFileInPath() : returning NULL" << std::endl;
return path;
}
char *osgDB::findFile( const char *file )
{
if (!file) return NULL;
if (!s_filePathInitialized) initFilePath();
char* newFileName = findFileInPath( file, s_filePath );
if (newFileName) return newFileName;
// need to check here to see if file has a path on it.
// now strip the file of an previous path if one exists.
std::string simpleFileName = getSimpleFileName(file);
newFileName = findFileInPath( simpleFileName.c_str(), s_filePath );
return newFileName;
}
/*
Order of precedence for
Under UNIX.
./
OSG_LD_LIBRARY_PATH
s_default_dso_path
LD_LIBRARY*_PATH
Under Windows
./
OSG_LD_LIBRARY_PATH
s_default_dso_path
PATH
*/
char *osgDB::findDSO( const char *name )
{
char path[FILEUTILS_MAX_PATH_LENGTH];
char *ptr;
strcpy( path, "./" );
if((ptr = getenv( "OSG_LD_LIBRARY_PATH" )))
{
strcat( path, PathDelimitor );
strcat( path, ptr );
}
strcat( path, PathDelimitor );
strcat( path, s_default_dso_path );
if ((ptr = getenv( "PATH" )))
{
notify(DEBUG_INFO) << "PATH = "<<ptr<<std::endl;
strcat( path, PathDelimitor );
strcat( path, ptr );
}
// check existance of dso assembled direct paths.
char* fileFound = NULL;
fileFound = findFileInPath( name , path );
if (fileFound) return fileFound;
// failed with direct paths,
// now try prepending the filename with "osgPlugins/"
char* prependosgPlugins = osgNew char[strlen(name)+12];
strcpy(prependosgPlugins,"osgPlugins/");
strcat(prependosgPlugins,name);
fileFound = findFileInPath( prependosgPlugins , path );
osgDelete [] prependosgPlugins;
return fileFound;
}
std::string osgDB::findFileInDirectory(const std::string& fileName,const std::string& dirName,bool caseInsensitive)
{
bool needFollowingBackslash = false;
bool needDirectoryName = true;
osgDB::DirectoryContents dc;
if (dirName.empty())
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else if (dirName=="." || dirName=="./" || dirName==".\\")
{
dc = osgDB::getDirectoryContents(".");
needFollowingBackslash = false;
needDirectoryName = false;
}
else
{
dc = osgDB::getDirectoryContents(dirName);
char lastChar = dirName[dirName.size()-1];
if (lastChar=='/') needFollowingBackslash = false;
else if (lastChar=='\\') needFollowingBackslash = false;
else needFollowingBackslash = true;
needDirectoryName = true;
}
for(osgDB::DirectoryContents::iterator itr=dc.begin();
itr!=dc.end();
++itr)
{
if ((caseInsensitive && osgDB::equalCaseInsensitive(fileName,*itr)) ||
(fileName==*itr))
{
if (!needDirectoryName) return *itr;
else if (needFollowingBackslash) return dirName+'/'+*itr;
else return dirName+*itr;
}
}
return "";
}
#include <io.h>
#include <direct.h>
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;
}

View File

@ -18,6 +18,15 @@
using namespace osg;
using namespace osgDB;
void PrintFilePathList(ostream& stream,const FilePathList& filepath)
{
for(FilePathList::const_iterator itr=filepath.begin();
itr!=filepath.end();
++itr)
{
stream << " "<< *itr<<std::endl;
}
}
class RegistryPtr
{
@ -47,7 +56,7 @@ Registry::Registry()
_createNodeFromImage = true;
_openingLibrary = false;
osgDB::initFilePath();
initFilePathLists();
// register file extension alias.
addFileExtensionAlias("rgba", "rgb");
@ -62,6 +71,7 @@ Registry::Registry()
addFileExtensionAlias("geo", "lwo");
addFileExtensionAlias("lw", "lwo");
}
@ -71,6 +81,114 @@ Registry::~Registry()
void Registry::initDataFilePathList()
{
//
// set up data file paths
//
char *ptr;
if( (ptr = getenv( "OSG_FILE_PATH" )) )
{
notify(DEBUG_INFO) << "OSG_FILE_PATH("<<ptr<<")"<<std::endl;
setDataFilePathList(ptr);
}
else if( (ptr = getenv( "OSGFILEPATH" )) )
{
notify(DEBUG_INFO) << "OSGFILEPATH("<<ptr<<")"<<std::endl;
setDataFilePathList(ptr);
}
osg::notify(INFO)<<"Data FilePathList"<<std::endl;
PrintFilePathList(osg::notify(INFO),getDataFilePathList());
}
void Registry::initLibraryFilePathList()
{
//
// set up library paths
//
char* ptr;
if( (ptr = getenv( "OSG_LIBRARY_PATH")) )
{
notify(DEBUG_INFO) << "OSG_LIBRARY_PATH("<<ptr<<")"<<std::endl;
setLibraryFilePathList(ptr);
}
else if( (ptr = getenv( "OSG_LD_LIBRARY_PATH")) )
{
notify(DEBUG_INFO) << "OSG_LD_LIBRARY_PATH("<<ptr<<")"<<std::endl;
setLibraryFilePathList(ptr);
}
#ifdef __sgi
convertStringPathIntoFilePathList("/usr/lib32/:/usr/local/lib32/",_libraryFilePath);
// bloody mess see rld(1) man page
#if (_MIPS_SIM == _MIPS_SIM_ABI32)
if( (ptr = getenv( "LD_LIBRARY_PATH" )))
{
convertStringPathIntoFilePathList(ptr,_libraryFilePath);
}
#elif (_MIPS_SIM == _MIPS_SIM_NABI32)
if( !(ptr = getenv( "LD_LIBRARYN32_PATH" )))
ptr = getenv( "LD_LIBRARY_PATH" );
{
convertStringPathIntoFilePathList(ptr,_libraryFilePath);
}
#elif (_MIPS_SIM == _MIPS_SIM_ABI64)
if( !(ptr = getenv( "LD_LIBRARY64_PATH" )))
ptr = getenv( "LD_LIBRARY_PATH" );
if( ptr )
{
convertStringPathIntoFilePathList(ptr,_libraryFilePath);
}
#endif
#elif defined(__CYGWIN__)
if ((ptr = getenv( "PATH" )))
{
convertStringPathIntoFilePathList(ptr,_libraryFilePath);
}
convertStringPathIntoFilePathList("/usr/bin/:/usr/local/bin/",_libraryFilePath);
#elif defined(WIN32)
if ((ptr = getenv( "PATH" )))
{
convertStringPathIntoFilePathList(ptr,_libraryFilePath);
}
convertStringPathIntoFilePathList("C:/Windows/System/",_libraryFilePath);
#else
if( (ptr = getenv( "LD_LIBRARY_PATH" )) )
{
convertStringPathIntoFilePathList(ptr,_libraryFilePath);
}
convertStringPathIntoFilePathList("/usr/lib/:/usr/local/lib/",_libraryFilePath);
#endif
osg::notify(INFO)<<"Library FilePathList"<<std::endl;
PrintFilePathList(osg::notify(INFO),getLibraryFilePathList());
}
void Registry::readCommandLine(std::vector<std::string>& commandLine)
{
@ -749,8 +867,10 @@ bool Registry::writeObject(const osg::Object& obj,Output& fw)
//
ReaderWriter::ReadResult Registry::readObject(const std::string& fileName)
{
char *file = findFile( fileName.c_str() );
if (file==NULL) return ReaderWriter::ReadResult("Warning: file \""+fileName+"\" not found.");
std::string file = findDataFile( fileName );
if (file.empty()) return ReaderWriter::ReadResult("Warning: file \""+fileName+"\" not found.");
PushAndPopDataPath tmpfile(getFilePath(fileName));
// record the existing reader writer.
std::set<ReaderWriter*> rwOriginal;
@ -845,8 +965,10 @@ ReaderWriter::WriteResult Registry::writeObject(const Object& obj,const std::str
ReaderWriter::ReadResult Registry::readImage(const std::string& fileName)
{
char *file = findFile( fileName.c_str() );
if (file==NULL) return ReaderWriter::ReadResult("Warning: file \""+fileName+"\" not found.");
std::string file = findDataFile( fileName );
if (file.empty()) return ReaderWriter::ReadResult("Warning: file \""+fileName+"\" not found.");
PushAndPopDataPath tmpfile(getFilePath(fileName));
// record the existing reader writer.
std::set<ReaderWriter*> rwOriginal;
@ -941,8 +1063,10 @@ ReaderWriter::WriteResult Registry::writeImage(const Image& image,const std::str
ReaderWriter::ReadResult Registry::readNode(const std::string& fileName)
{
char *file = findFile( fileName.c_str() );
if (file==NULL) return ReaderWriter::ReadResult("Warning: file \""+fileName+"\" not found.");
std::string file = findDataFile( fileName );
if (file.empty()) return ReaderWriter::ReadResult("Warning: file \""+fileName+"\" not found.");
PushAndPopDataPath tmpfile(getFilePath(fileName));
// record the existing reader writer.
std::set<ReaderWriter*> rwOriginal;
@ -1041,3 +1165,26 @@ ReaderWriter::WriteResult Registry::writeNode(const Node& node,const std::string
return results.front();
}
void Registry::convertStringPathIntoFilePathList(const std::string& paths,FilePathList& filepath)
{
#ifdef WIN32
char delimitor = ';';
#else
char delimitor = ':';
#endif
if (!paths.empty())
{
std::string::size_type start = 0;
std::string::size_type end;
while ((end = paths.find_first_of(delimitor,start))!=std::string::npos)
{
filepath.push_back(std::string(paths,start,end-start));
start = end+1;
}
filepath.push_back(std::string(paths,start));
}
}

View File

@ -114,10 +114,10 @@ bool FltFile::readFile(const std::string& fileName)
if (!fin.open(fileName))
{
// havn't found file, look in OSGFILEPATH
char* newFileName = osgDB::findFile(fileName.c_str());
std::string foundFileName = osgDB::findDataFile(fileName);
if (!newFileName) return false;
if (!fin.open(newFileName)) return false;
if (foundFileName.empty()) return false;
if (!fin.open(foundFileName)) return false;
}
osg::notify(osg::INFO) << "Loading " << fileName << " ... " << std::endl;

View File

@ -56,10 +56,10 @@ bool FileInput::open(const std::string& fileName)
if (_file == NULL)
{
// ok havn't found file, resort to using findFile...
char* newFileName = osgDB::findFile(fileName.c_str());
std::string newFileName = osgDB::findDataFile(fileName);
if (!newFileName) return false;
_file=::fopen( newFileName, "rb");
if (newFileName.empty()) return false;
_file=::fopen( newFileName.c_str(), "rb");
if (_file == NULL) return false;
}
_eof = false;

View File

@ -71,7 +71,8 @@ class sgReaderWriterOSGTGZ : public osgDB::ReaderWriter
system( command );
osg::Group *grp = new osg::Group;
osgDB::setFilePath( dirname );
osgDB::PushAndPopDataPath tmppath(dirname );
osgDB::DirectoryContents contents = osgDB::getDirectoryContents(dirname);
for(osgDB::DirectoryContents::iterator itr = contents.begin();

View File

@ -70,7 +70,8 @@ class ReaderWriterTGZ : public osgDB::ReaderWriter
system( command );
osg::Group *grp = new osg::Group;
osgDB::setFilePath( dirname );
osgDB::PushAndPopDataPath tmppath(dirname );
// deactivate the automatic generation of images to geode's.
bool prevCreateNodeFromImage = osgDB::Registry::instance()->getCreateNodeFromImage();

View File

@ -32,7 +32,7 @@ public:
{
Group* ret = 0;
// search the SGL data path
std::string foundname = osgDB::findFile(filename.c_str());
std::string foundname = osgDB::findDataFile(filename);
if( !foundname.empty())
{
if (archive.OpenFile(foundname.c_str()))

View File

@ -57,7 +57,9 @@ bool TrPageArchive::OpenFile(const char* file)
SetDirectory(".");
else
{
osgDB::setFilePath(m_alternate_path.c_str());
// push the path to the front of the list so that all subsequenct
// files get loaded relative to this if possible.
osgDB::getDataFilePathList().push_front(m_alternate_path);
SetDirectory(m_alternate_path.c_str());
}

View File

@ -61,7 +61,8 @@ class ReaderWriterZIP : public osgDB::ReaderWriter
#endif
osg::Group *grp = new osg::Group;
osgDB::setFilePath( dirname );
osgDB::PushAndPopDataPath tmppath(dirname );
bool prevCreateNodeFromImage = osgDB::Registry::instance()->getCreateNodeFromImage();
osgDB::Registry::instance()->setCreateNodeFromImage(false);

View File

@ -29,38 +29,38 @@
using namespace osg;
using namespace osgText;
// define the default paths to look for fonts.
// note delimator is : for unix, ; for windows.
#if defined(__linux) || defined(__FreeBSD__) || defined (__sgi) || defined (__DARWIN_OSX__)
static char* s_FontFilePath = ".:/usr/share/fonts/ttf:/usr/share/fonts/ttf/western:/usr/share/fonts/ttf/decoratives";
#elif defined(WIN32)
static char* s_FontFilePath = ".;C:/winnt/fonts;C:/windows/fonts";
#else
static char* s_FontFilePath = ".:";
#endif
std::string findFontFile(const std::string& str)
{
// try looking in OSGFILEPATH etc first for fonts.
char* filename = osgDB::findFile(str.c_str());
if (filename) return std::string(filename);
std::string filename = osgDB::findDataFile(str);
if (!filename.empty()) return std::string(filename);
#if defined(WIN32)
// try windir environment
char *ptr;
if ((ptr = getenv( "windir" )))
{
static std::string osPath(ptr);
s_FontFilePath = const_cast<char*>(osPath.c_str());
}
#endif
// else fallback into the standard font file paths.
if (s_FontFilePath)
static osgDB::FilePathList s_FontFilePath;
static bool initialized = false;
if (!initialized)
{
filename = osgDB::findFileInPath(str.c_str(),s_FontFilePath);
if (filename) return std::string(filename);
initialized = true;
#if defined(WIN32)
osgDB::Registry::convertStringPathIntoFilePathList(
".;C:/winnt/fonts;C:/windows/fonts",
s_FontFilePath);
char *ptr;
if ((ptr = getenv( "windir" )))
{
s_FontFilePath.push_back(ptr);
}
#else
osgDB::Registry::convertStringPathIntoFilePathList(
".:/usr/share/fonts/ttf:/usr/share/fonts/ttf/western:/usr/share/fonts/ttf/decoratives",
s_FontFilePath);
#endif
}
filename = osgDB::findFileInPath(str,s_FontFilePath);
if (!filename.empty()) return filename;
osg::notify(osg::WARN)<<"Warning: font file \""<<str<<"\" not found."<<std::endl;
return std::string();
}