Hi Robert,
I applied your changes but then when I ran even something simple like
osgviewer cow.osg I got an seg fault, with what looks like a recursive
loop in the findFileInPath code. I haven't dived in to see why this
might be occurring, but since your the author I though perhaps the
code hasn't been tested well enough yet, perhaps there is a platform
portability issue that you've introduced. Either way, as it the
submission isn't in a shape to merge yet.
Sorry, I realized that my change to isFileNameNativeStyle() was
braindead. The logic was reversed, and it would return false if the path
contained no separators at all, on all platforms... This would indeed
lead to an infinite loop in findFileInPath() for cow.osg, because of this:
if (!isFileNameNativeStyle(filename))
return findFileInPath(convertFileNameToNativeStyle(filename),
filepath, caseSensitivity);
Sorry about this. I've introduced getUnixPathSeparator() and
getWindowsPathSeparator() and fixed isFileNameNativeStyle(). Please give
the attached files a try. All other files from the original submission
(FileUtils header and cpp, and osgvolume.cpp) are still good.
Thanks,
J-S
--
______________________________________________________
Jean-Sebastien Guay [email protected]
http://www.cm-labs.com/
http://whitestar02.webhop.org/
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#ifndef OSGDB_FILENAMEUTILS
#define OSGDB_FILENAMEUTILS 1
#include <osgDB/Export>
#include <string>
namespace osgDB {
/** Gets the parent path from full name (Ex: /a/b/c.Ext => /a/b). */
extern OSGDB_EXPORT std::string getFilePath(const std::string& filename);
/** Gets the extension without dot (Ex: /a/b/c.Ext => Ext). */
extern OSGDB_EXPORT std::string getFileExtension(const std::string& filename);
/** Gets the extension including dot (Ex: /a/b/c.Ext => .Ext). */
extern OSGDB_EXPORT std::string getFileExtensionIncludingDot(const std::string&
filename);
/** Gets the lowercase extension without dot (Ex: /a/b/c.Ext => ext). */
extern OSGDB_EXPORT std::string getLowerCaseFileExtension(const std::string&
filename);
/** Gets file name with extension (Ex: /a/b/c.Ext => c.Ext). */
extern OSGDB_EXPORT std::string getSimpleFileName(const std::string& fileName);
/** Gets file path without last extension (Ex: /a/b/c.Ext => /a/b/c ;
file.ext1.ext2 => file.ext1). */
extern OSGDB_EXPORT std::string getNameLessExtension(const std::string&
fileName);
/** Gets file path without \b all extensions (Ex: /a/b/c.Ext => /a/b/c ;
file.ext1.ext2 => file). */
extern OSGDB_EXPORT std::string getNameLessAllExtensions(const std::string&
fileName);
/** Gets file name without last extension (Ex: /a/b/c.Ext => c ; file.ext1.ext2
=> file.ext1). */
extern OSGDB_EXPORT std::string getStrippedName(const std::string& fileName);
/** Converts forward slashes (/) to back slashes (\). */
extern OSGDB_EXPORT std::string convertFileNameToWindowsStyle(const
std::string& fileName);
/** Converts back slashes (\) to forward slashes (/). */
extern OSGDB_EXPORT std::string convertFileNameToUnixStyle(const std::string&
fileName);
extern OSGDB_EXPORT std::string convertToLowerCase(const std::string& fileName);
/** Get the path separator for Unix. */
extern OSGDB_EXPORT char getUnixPathSeparator();
/** Get the path separator for Windows. */
extern OSGDB_EXPORT char getWindowsPathSeparator();
/** Get the path separator for the current platform. */
extern OSGDB_EXPORT char getNativePathSeparator();
/** Check if the path contains only the current platform's path separators. */
extern OSGDB_EXPORT bool isFileNameNativeStyle(const std::string& fileName);
/** Convert the path to contain only the current platform's path separators. */
extern OSGDB_EXPORT std::string convertFileNameToNativeStyle(const std::string&
fileName);
extern OSGDB_EXPORT bool equalCaseInsensitive(const std::string& lhs,const
std::string& rhs);
extern OSGDB_EXPORT bool equalCaseInsensitive(const std::string& lhs,const
char* rhs);
extern OSGDB_EXPORT bool containsServerAddress(const std::string& filename);
extern OSGDB_EXPORT std::string getServerProtocol(const std::string& filename);
extern OSGDB_EXPORT std::string getServerAddress(const std::string& filename);
extern OSGDB_EXPORT std::string getServerFileName(const std::string& filename);
/** Concatenates two paths */
extern OSGDB_EXPORT std::string concatPaths(const std::string& left, const
std::string& right);
/** Removes .. and . dirs in a path */
extern OSGDB_EXPORT std::string getRealPath(const std::string& path);
}
#endif
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*/
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#ifdef WIN32
#define _WIN32_WINNT 0x0500
#include <windows.h>
#endif
#if defined(__sgi)
#include <ctype.h>
#elif defined(__GNUC__) || !defined(WIN32) || defined(__MWERKS__)
#include <cctype>
using std::tolower;
#endif
using namespace std;
std::string osgDB::getFilePath(const std::string& fileName)
{
std::string::size_type slash = fileName.find_last_of("/\\");
if (slash==std::string::npos) return std::string();
else return std::string(fileName, 0, slash);
}
std::string osgDB::getSimpleFileName(const std::string& fileName)
{
std::string::size_type slash = fileName.find_last_of("/\\");
if (slash==std::string::npos) return fileName;
else return std::string(fileName.begin()+slash+1,fileName.end());
}
std::string osgDB::getFileExtension(const std::string& fileName)
{
std::string::size_type dot = fileName.find_last_of('.');
std::string::size_type slash = fileName.find_last_of("/\\");
if (dot==std::string::npos || (slash!=std::string::npos && dot<slash))
return std::string("");
return std::string(fileName.begin()+dot+1,fileName.end());
}
std::string osgDB::getFileExtensionIncludingDot(const std::string& fileName)
{
std::string::size_type dot = fileName.find_last_of('.');
std::string::size_type slash = fileName.find_last_of("/\\");
if (dot==std::string::npos || (slash!=std::string::npos && dot<slash))
return std::string("");
return std::string(fileName.begin()+dot,fileName.end());
}
std::string osgDB::convertFileNameToWindowsStyle(const std::string& fileName)
{
std::string new_fileName(fileName);
std::string::size_type slash = 0;
while( (slash=new_fileName.find_first_of(getUnixPathSeparator(),slash)) !=
std::string::npos)
{
new_fileName[slash]=getWindowsPathSeparator();
}
return new_fileName;
}
std::string osgDB::convertFileNameToUnixStyle(const std::string& fileName)
{
std::string new_fileName(fileName);
std::string::size_type slash = 0;
while( (slash=new_fileName.find_first_of(getWindowsPathSeparator(),slash))
!= std::string::npos)
{
new_fileName[slash]=getUnixPathSeparator();
}
return new_fileName;
}
char osgDB::getUnixPathSeparator()
{
return '/';
}
char osgDB::getWindowsPathSeparator()
{
return '\\';
}
char osgDB::getNativePathSeparator()
{
#if defined(WIN32) && !defined(__CYGWIN__)
return getWindowsPathSeparator();
#else
return getUnixPathSeparator();
#endif
}
bool osgDB::isFileNameNativeStyle(const std::string& fileName)
{
#if defined(WIN32) && !defined(__CYGWIN__)
return fileName.find(getUnixPathSeparator()) == std::string::npos; //
return true if no unix style slash exist
#else
return fileName.find(getWindowsPathSeparator()) == std::string::npos; //
return true if no windows style backslash exist
#endif
}
std::string osgDB::convertFileNameToNativeStyle(const std::string& fileName)
{
#if defined(WIN32) && !defined(__CYGWIN__)
return convertFileNameToWindowsStyle(fileName);
#else
return convertFileNameToUnixStyle(fileName);
#endif
}
std::string osgDB::getLowerCaseFileExtension(const std::string& filename)
{
return convertToLowerCase(osgDB::getFileExtension(filename));
}
std::string osgDB::convertToLowerCase(const std::string& str)
{
std::string lowcase_str(str);
for(std::string::iterator itr=lowcase_str.begin();
itr!=lowcase_str.end();
++itr)
{
*itr = tolower(*itr);
}
return lowcase_str;
}
// strip one level of extension from the filename.
std::string osgDB::getNameLessExtension(const std::string& fileName)
{
std::string::size_type dot = fileName.find_last_of('.');
std::string::size_type slash = fileName.find_last_of("/\\"); //
Finds forward slash *or* back slash
if (dot==std::string::npos || (slash!=std::string::npos && dot<slash))
return fileName;
return std::string(fileName.begin(),fileName.begin()+dot);
}
// strip all extensions from the filename.
std::string osgDB::getNameLessAllExtensions(const std::string& fileName)
{
// Finds start serach position: from last slash, or the begining of the
string if none found
std::string::size_type startPos = fileName.find_last_of("/\\");
// Finds forward slash *or* back slash
if (startPos == std::string::npos) startPos = 0;
std::string::size_type dot = fileName.find_first_of('.', startPos);
// Finds *FIRST* dot from start pos
if (dot==std::string::npos) return fileName;
return std::string(fileName.begin(),fileName.begin()+dot);
}
std::string osgDB::getStrippedName(const std::string& fileName)
{
std::string simpleName = getSimpleFileName(fileName);
return getNameLessExtension( simpleName );
}
bool osgDB::equalCaseInsensitive(const std::string& lhs,const std::string& rhs)
{
if (lhs.size()!=rhs.size()) return false;
std::string::const_iterator litr = lhs.begin();
std::string::const_iterator ritr = rhs.begin();
while (litr!=lhs.end())
{
if (tolower(*litr)!=tolower(*ritr)) return false;
++litr;
++ritr;
}
return true;
}
bool osgDB::equalCaseInsensitive(const std::string& lhs,const char* rhs)
{
if (rhs==NULL || lhs.size()!=strlen(rhs)) return false;
std::string::const_iterator litr = lhs.begin();
const char* cptr = rhs;
while (litr!=lhs.end())
{
if (tolower(*litr)!=tolower(*cptr)) return false;
++litr;
++cptr;
}
return true;
}
bool osgDB::containsServerAddress(const std::string& filename)
{
// need to check for ://
std::string::size_type pos(filename.find("://"));
if (pos == std::string::npos)
return false;
std::string proto(filename.substr(0, pos));
return Registry::instance()->isProtocolRegistered(proto);
}
std::string osgDB::getServerProtocol(const std::string& filename)
{
std::string::size_type pos(filename.find("://"));
if (pos != std::string::npos)
return filename.substr(0,pos);
return "";
}
std::string osgDB::getServerAddress(const std::string& filename)
{
std::string::size_type pos(filename.find("://"));
if (pos != std::string::npos)
{
std::string::size_type pos_slash = filename.find_first_of('/',pos+3);
if (pos_slash!=std::string::npos)
{
return filename.substr(pos+3,pos_slash-pos-3);
}
else
{
return filename.substr(pos+3,std::string::npos);
}
}
return "";
}
std::string osgDB::getServerFileName(const std::string& filename)
{
std::string::size_type pos(filename.find("://"));
if (pos != std::string::npos)
{
std::string::size_type pos_slash = filename.find_first_of('/',pos+3);
if (pos_slash!=std::string::npos)
{
return filename.substr(pos_slash+1,std::string::npos);
}
else
{
return "";
}
}
return filename;
}
std::string osgDB::concatPaths(const std::string& left, const std::string&
right)
{
#if defined(WIN32) && !defined(__CYGWIN__)
const char delimiterNative = getWindowsPathSeparator();
const char delimiterForeign = getUnixPathSeparator();
#else
const char delimiterNative = getUnixPathSeparator();
const char delimiterForeign = getWindowsPathSeparator();
#endif
if(left.empty())
{
return(right);
}
char lastChar = left[left.size() - 1];
if(lastChar == delimiterNative)
{
return left + right;
}
else if(lastChar == delimiterForeign)
{
return left.substr(0, left.size() - 1) + delimiterNative + right;
}
else // lastChar != a delimiter
{
return left + delimiterNative + right;
}
}
std::string osgDB::getRealPath(const std::string& path)
{
#if defined(WIN32) && !defined(__CYGWIN__)
// Not unicode compatible should give an error if UNICODE defined
char retbuf[MAX_PATH + 1];
char tempbuf1[MAX_PATH + 1];
GetFullPathName(path.c_str(), sizeof(retbuf), retbuf, NULL);
// Force drive letter to upper case
if ((retbuf[1] == ':') && islower(retbuf[0]))
retbuf[0] = _toupper(retbuf[0]);
if (fileExists(std::string(retbuf)))
{
// Canonicalise the full path
GetShortPathName(retbuf, tempbuf1, sizeof(tempbuf1));
GetLongPathName(tempbuf1, retbuf, sizeof(retbuf));
return std::string(retbuf);
}
else
{
// Canonicalise the directories
std::string FilePath = getFilePath(retbuf);
char tempbuf2[MAX_PATH + 1];
if (0 == GetShortPathName(FilePath.c_str(), tempbuf1, sizeof(tempbuf1)))
return std::string(retbuf);
if (0 == GetLongPathName(tempbuf1, tempbuf2, sizeof(tempbuf2)))
return std::string(retbuf);
FilePath = std::string(tempbuf2);
FilePath += getWindowsPathSeparator();
FilePath.append(getSimpleFileName(std::string(retbuf)));
return FilePath;
}
#else
char resolved_path[PATH_MAX];
char* result = realpath(path.c_str(), resolved_path);
if (result) return std::string(resolved_path);
else return path;
#endif
}
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org