b5a15fb5b4
"Attached you'll find a proposal for using different protocols. The idea behind the new code is: 1.) plugins/apps register protocols which they can handle. This is done via osgDB::Registry::registerProtocol(aProtocolName). Plugins register supported protocols as usual via ReaderWriter::supportsProtocol(..), the Registry is updated accordingly. 2.) osgDB::containsServerAddress checks first for an appearance of "://" in the filename and then checks the protocol against the set of registered protocols via Registry::isProtocolRegistered(aProtocollName) 3.) the other getServer*-functions changed as well, there's even a getServerProtocol-function With these changes filenames/Urls get routed to loaded plugins even with different protocols than 'http'."
308 lines
8.8 KiB
C++
308 lines
8.8 KiB
C++
/* -*-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('.');
|
|
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_first_of("://"));
|
|
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_first_of("://"));
|
|
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_first_of("://"));
|
|
|
|
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_first_of("://"));
|
|
|
|
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
|
|
|
|
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
|
|
}
|