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
}
FileNameUtils
Description: Binary data
_______________________________________________ osg-submissions mailing list [email protected] http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
