Hi Paul and Robert,

Here is my proposal. I fixed what Paul said, added some doxygen comments, added 
the function I told about, and removed the two "find('/')"-like calls to use 
only one. BTW, is there a reason for not doing the same in other functions, 
like getFilePath(), getSimpleFileName()...? If yes, I guess this code should be 
factorized. Else, those functions may be simplified.

Cheers,

Sukender
PVLE - Lightweight cross-platform game engine - http://pvle.sourceforge.net/

----- "Sukender" <[email protected]> a écrit :

> Hi Paul and Robert,
> 
> Oh, right! The test should be (backslash!=std::npos && dot<backslash
> && forwardslash==std::npos && dot<forwardslash), I guess.
> 
> But this make me wondering if we shouldn't have two different
> functions:
> 1. getNameLessExtension() which removes one extension, stopping on
> slashes
> 2. getNameLessAllExtensions() which removes *ALL* extensions, stopping
> on slashes
> Thoughts?
> 
> Going to submit both in a moment...
> 
> Sukender
> PVLE - Lightweight cross-platform game engine -
> http://pvle.sourceforge.net/
> 
> ----- "Paul Martz" <[email protected]> a écrit :
> 
> > Hi Sukender and Robert --
> >
> > There were a sequence of commits starting with r11165 that appears
> to
> > have broken stripping the extension. Backing out FileNameUtils.cpp
> to
> > r11164 resolves the issue.
> >
> > To reproduce the problem, try this command:
> >    osgviewer cow.osg.5,5,5.trans
> >
> > getNameLessExtension is returning the original (extension intact)
> file
> > name to the trans pseudoloader, which subsequently emits an error,
> and
> > osgviewer exits.
> >
> > On svn head, getNameLessExtension stores the position of dot,
> > forwardslash, and backslash as size_type (unsigned). In this case,
> > both
> > forwareslash and backslash are npos (very large unsigned int). The
> > code
> > returns the original file name if (dot<backslash &&
> dot<forwardslash).
> > That evaluates to true in this case, so the original file name is
> > returned with the extension intact.
> >
> > I'm not sure of the exact logic you guys are after with this change,
> > so
> > I'll defer to you two to recommend a fix.
> >     -Paul
> >
> >
> >
> > Sukender wrote:
> > > You're welcome.
> > >
> > > Sukender
> > > PVLE - Lightweight cross-platform game engine -
> > http://pvle.sourceforge.net/
> > >
> > > ----- "Robert Osfield" <[email protected]> a écrit :
> > >
> > >> Hi Sukender,
> > >>
> > >>
> > >> On Fri, Mar 5, 2010 at 12:10 PM, Sukender < [email protected] >
> > wrote:
> > >>
> > >>
> > >> Here is a tiny fix for getNameLessExtension(). It does now check
> > for
> > >> the presence of slashes ('/' and '\') to avoid changing the
> string
> > >> when having a dot in a directory.
> > >> Old behaviour: "abc.d/filename_no_ext" -> "abc"
> > >> New behaviour: "abc.d/filename_no_ext" -> "abc.d/filename_no_ext"
> > >>
> > >>
> > >>
> > >> Change now merged and submitted to svn/trunk. I changed the
> > variable
> > >> antiSlash to back_slash so that it has the usual naming form this
> > type
> > >> of slash.
> > >>
> > >>
> > >> By the way, I spotted in the same file some
> > >> filename.find_first_of("://"). At first glance, it seems the goal
> > is
> > >> to find "://" substring. If so, the call isn't appropriate since
> it
> > >> finds the first occurrence of ":" or "/", and not the first
> > occurence
> > >> of the string "://".
> > >> If confirmed, it may be replaced with "find()".
> > >>
> > >>
> > >> Ooo, does look like it is a bug... I've just replaced
> > >> find_first_of("://") with find("://"), thanks for the spotting
> this
> > >> error.
> > >>
> > >> Cheers,
> > >> Robert.
> > >>
> > >>
> > >>
> > >>
> > >> _______________________________________________
> > >> osg-submissions mailing list
> > >> [email protected]
> > >>
> >
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> > > _______________________________________________
> > > osg-submissions mailing list
> > > [email protected]
> > >
> >
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> > _______________________________________________
> > osg-submissions mailing list
> > [email protected]
> >
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.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.
*/
#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 slash1 = fileName.find_last_of('/');
    std::string::size_type slash2 = fileName.find_last_of('\\');
    if (slash1==std::string::npos) 
    {
        if (slash2==std::string::npos) return std::string();
        return std::string(fileName,0,slash2);
    }
    if (slash2==std::string::npos) return std::string(fileName,0,slash1);
    return std::string(fileName, 0, slash1>slash2 ?  slash1 : slash2);
}


std::string osgDB::getSimpleFileName(const std::string& fileName)
{
    std::string::size_type slash1 = fileName.find_last_of('/');
    std::string::size_type slash2 = fileName.find_last_of('\\');
    if (slash1==std::string::npos) 
    {
        if (slash2==std::string::npos) return fileName;
        return std::string(fileName.begin()+slash2+1,fileName.end());
    }
    if (slash2==std::string::npos) return 
std::string(fileName.begin()+slash1+1,fileName.end());
    return 
std::string(fileName.begin()+(slash1>slash2?slash1:slash2)+1,fileName.end());
}


std::string osgDB::getFileExtension(const std::string& fileName)
{
    std::string::size_type dot = fileName.find_last_of('.');
    if (dot==std::string::npos) 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('.');
    if (dot==std::string::npos) 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('/',slash)) != std::string::npos)
    {
        new_fileName[slash]='\\';
    }
    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('\\',slash)) != std::string::npos)
    {
        new_fileName[slash]='/';
    }

    return new_fileName;
}

bool osgDB::isFileNameNativeStyle(const std::string& fileName)
{
#if defined(WIN32) && !defined(__CYGWIN__)
    return fileName.find('/') == std::string::npos; // return true if no unix 
style slash exist
#else
    return fileName.find('\\') == std::string::npos; // return true if no 
windows style slash 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  = '\\';
    const char delimiterForeign = '/';
#else
    const char delimiterNative  = '/';
    const char delimiterForeign = '\\';
#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.append("\\");
        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 
}

Attachment: FileNameUtils
Description: Binary data

_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to