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

Reply via email to