diff options
Diffstat (limited to 'src/3rdparty/assimp/code/FileSystemFilter.h')
-rw-r--r-- | src/3rdparty/assimp/code/FileSystemFilter.h | 480 |
1 files changed, 241 insertions, 239 deletions
diff --git a/src/3rdparty/assimp/code/FileSystemFilter.h b/src/3rdparty/assimp/code/FileSystemFilter.h index 6f5d46065..3370589d6 100644 --- a/src/3rdparty/assimp/code/FileSystemFilter.h +++ b/src/3rdparty/assimp/code/FileSystemFilter.h @@ -5,8 +5,8 @@ Open Asset Import Library (assimp) Copyright (c) 2006-2008, assimp team All rights reserved. -Redistribution and use of this software in source and binary forms, -with or without modification, are permitted provided that the +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above @@ -23,16 +23,16 @@ following conditions are met: derived from this software without specific prior written permission of the assimp team. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------- @@ -40,257 +40,259 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. /** @file FileSystemFilter.h * Implements a filter system to filter calls to Exists() and Open() - * in order to improve the sucess rate of file opening ... + * in order to improve the success rate of file opening ... */ #ifndef AI_FILESYSTEMFILTER_H_INC #define AI_FILESYSTEMFILTER_H_INC #include "../include/assimp/IOSystem.hpp" +#include "../include/assimp/DefaultLogger.hpp" #include "fast_atof.h" #include "ParsingUtils.h" -namespace Assimp { + +namespace Assimp { inline bool IsHex(char s) { - return (s>='0' && s<='9') || (s>='a' && s<='f') || (s>='A' && s<='F'); + return (s>='0' && s<='9') || (s>='a' && s<='f') || (s>='A' && s<='F'); } // --------------------------------------------------------------------------- -/** File system filter +/** File system filter */ class FileSystemFilter : public IOSystem { public: - /** Constructor. */ - FileSystemFilter(const std::string& file, IOSystem* old) - : wrapped (old) - , src_file (file) - , sep(wrapped->getOsSeparator()) - { - ai_assert(NULL != wrapped); - - // Determine base directory - base = src_file; - std::string::size_type ss2; - if (std::string::npos != (ss2 = base.find_last_of("\\/"))) { - base.erase(ss2,base.length()-ss2); - } - else { - base = ""; - // return; - } - - // make sure the directory is terminated properly - char s; - - if (base.length() == 0) { - base = "."; - base += getOsSeparator(); - } - else if ((s = *(base.end()-1)) != '\\' && s != '/') { - base += getOsSeparator(); - } - - DefaultLogger::get()->info("Import root directory is \'" + base + "\'"); - } - - /** Destructor. */ - ~FileSystemFilter() - { - // haha - } - - // ------------------------------------------------------------------- - /** Tests for the existence of a file at the given path. */ - bool Exists( const char* pFile) const - { - std::string tmp = pFile; - - // Currently this IOSystem is also used to open THE ONE FILE. - if (tmp != src_file) { - BuildPath(tmp); - Cleanup(tmp); - } - - return wrapped->Exists(tmp); - } - - // ------------------------------------------------------------------- - /** Returns the directory separator. */ - char getOsSeparator() const - { - return sep; - } - - // ------------------------------------------------------------------- - /** Open a new file with a given path. */ - IOStream* Open( const char* pFile, const char* pMode = "rb") - { - ai_assert(pFile); - ai_assert(pMode); - - // First try the unchanged path - IOStream* s = wrapped->Open(pFile,pMode); - - if (!s) { - std::string tmp = pFile; - - // Try to convert between absolute and relative paths - BuildPath(tmp); - s = wrapped->Open(tmp,pMode); - - if (!s) { - // Finally, look for typical issues with paths - // and try to correct them. This is our last - // resort. - tmp = pFile; - Cleanup(tmp); - BuildPath(tmp); - s = wrapped->Open(tmp,pMode); - } - } - - return s; - } - - // ------------------------------------------------------------------- - /** Closes the given file and releases all resources associated with it. */ - void Close( IOStream* pFile) - { - return wrapped->Close(pFile); - } - - // ------------------------------------------------------------------- - /** Compare two paths */ - bool ComparePaths (const char* one, const char* second) const - { - return wrapped->ComparePaths (one,second); - } + /** Constructor. */ + FileSystemFilter(const std::string& file, IOSystem* old) + : wrapped (old) + , src_file (file) + , sep(wrapped->getOsSeparator()) + { + ai_assert(NULL != wrapped); + + // Determine base directory + base = src_file; + std::string::size_type ss2; + if (std::string::npos != (ss2 = base.find_last_of("\\/"))) { + base.erase(ss2,base.length()-ss2); + } + else { + base = ""; + // return; + } + + // make sure the directory is terminated properly + char s; + + if (base.length() == 0) { + base = "."; + base += getOsSeparator(); + } + else if ((s = *(base.end()-1)) != '\\' && s != '/') { + base += getOsSeparator(); + } + + DefaultLogger::get()->info("Import root directory is \'" + base + "\'"); + } + + /** Destructor. */ + ~FileSystemFilter() + { + // haha + } + + // ------------------------------------------------------------------- + /** Tests for the existence of a file at the given path. */ + bool Exists( const char* pFile) const + { + std::string tmp = pFile; + + // Currently this IOSystem is also used to open THE ONE FILE. + if (tmp != src_file) { + BuildPath(tmp); + Cleanup(tmp); + } + + return wrapped->Exists(tmp); + } + + // ------------------------------------------------------------------- + /** Returns the directory separator. */ + char getOsSeparator() const + { + return sep; + } + + // ------------------------------------------------------------------- + /** Open a new file with a given path. */ + IOStream* Open( const char* pFile, const char* pMode = "rb") + { + ai_assert(pFile); + ai_assert(pMode); + + // First try the unchanged path + IOStream* s = wrapped->Open(pFile,pMode); + + if (!s) { + std::string tmp = pFile; + + // Try to convert between absolute and relative paths + BuildPath(tmp); + s = wrapped->Open(tmp,pMode); + + if (!s) { + // Finally, look for typical issues with paths + // and try to correct them. This is our last + // resort. + tmp = pFile; + Cleanup(tmp); + BuildPath(tmp); + s = wrapped->Open(tmp,pMode); + } + } + + return s; + } + + // ------------------------------------------------------------------- + /** Closes the given file and releases all resources associated with it. */ + void Close( IOStream* pFile) + { + return wrapped->Close(pFile); + } + + // ------------------------------------------------------------------- + /** Compare two paths */ + bool ComparePaths (const char* one, const char* second) const + { + return wrapped->ComparePaths (one,second); + } private: - // ------------------------------------------------------------------- - /** Build a valid path from a given relative or absolute path. - */ - void BuildPath (std::string& in) const - { - // if we can already access the file, great. - if (in.length() < 3 || wrapped->Exists(in)) { - return; - } - - // Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows). - if (in[1] != ':') { - - // append base path and try - const std::string tmp = base + in; - if (wrapped->Exists(tmp)) { - in = tmp; - return; - } - } - - // Chop of the file name and look in the model directory, if - // this fails try all sub paths of the given path, i.e. - // if the given path is foo/bar/something.lwo, try - // <base>/something.lwo - // <base>/bar/something.lwo - // <base>/foo/bar/something.lwo - std::string::size_type pos = in.rfind('/'); - if (std::string::npos == pos) { - pos = in.rfind('\\'); - } - - if (std::string::npos != pos) { - std::string tmp; - std::string::size_type last_dirsep = std::string::npos; - - while(true) { - tmp = base; - tmp += sep; - - std::string::size_type dirsep = in.rfind('/', last_dirsep); - if (std::string::npos == dirsep) { - dirsep = in.rfind('\\', last_dirsep); - } - - if (std::string::npos == dirsep || dirsep == 0) { - // we did try this already. - break; - } - - last_dirsep = dirsep-1; - - tmp += in.substr(dirsep+1, in.length()-pos); - if (wrapped->Exists(tmp)) { - in = tmp; - return; - } - } - } - - // hopefully the underlying file system has another few tricks to access this file ... - } - - // ------------------------------------------------------------------- - /** Cleanup the given path - */ - void Cleanup (std::string& in) const - { - char last = 0; - if(in.empty()) { - return; - } - - // Remove a very common issue when we're parsing file names: spaces at the - // beginning of the path. - std::string::iterator it = in.begin(); - while (IsSpaceOrNewLine( *it ))++it; - if (it != in.begin()) { - in.erase(in.begin(),it+1); - } - - const char sep = getOsSeparator(); - for (it = in.begin(); it != in.end(); ++it) { - // Exclude :// and \\, which remain untouched. - // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 - if ( !strncmp(&*it, "://", 3 )) { - it += 3; - continue; - } - if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) { - it += 2; - continue; - } - - // Cleanup path delimiters - if (*it == '/' || (*it) == '\\') { - *it = sep; - - // And we're removing double delimiters, frequent issue with - // incorrectly composited paths ... - if (last == *it) { - it = in.erase(it); - --it; - } - } - else if (*it == '%' && in.end() - it > 2) { - - // Hex sequence in URIs - if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) { - *it = HexOctetToDecimal(&*it); - it = in.erase(it+1,it+2); - --it; - } - } - - last = *it; - } - } + // ------------------------------------------------------------------- + /** Build a valid path from a given relative or absolute path. + */ + void BuildPath (std::string& in) const + { + // if we can already access the file, great. + if (in.length() < 3 || wrapped->Exists(in)) { + return; + } + + // Determine whether this is a relative path (Windows-specific - most assets are packaged on Windows). + if (in[1] != ':') { + + // append base path and try + const std::string tmp = base + in; + if (wrapped->Exists(tmp)) { + in = tmp; + return; + } + } + + // Chop of the file name and look in the model directory, if + // this fails try all sub paths of the given path, i.e. + // if the given path is foo/bar/something.lwo, try + // <base>/something.lwo + // <base>/bar/something.lwo + // <base>/foo/bar/something.lwo + std::string::size_type pos = in.rfind('/'); + if (std::string::npos == pos) { + pos = in.rfind('\\'); + } + + if (std::string::npos != pos) { + std::string tmp; + std::string::size_type last_dirsep = std::string::npos; + + while(true) { + tmp = base; + tmp += sep; + + std::string::size_type dirsep = in.rfind('/', last_dirsep); + if (std::string::npos == dirsep) { + dirsep = in.rfind('\\', last_dirsep); + } + + if (std::string::npos == dirsep || dirsep == 0) { + // we did try this already. + break; + } + + last_dirsep = dirsep-1; + + tmp += in.substr(dirsep+1, in.length()-pos); + if (wrapped->Exists(tmp)) { + in = tmp; + return; + } + } + } + + // hopefully the underlying file system has another few tricks to access this file ... + } + + // ------------------------------------------------------------------- + /** Cleanup the given path + */ + void Cleanup (std::string& in) const + { + char last = 0; + if(in.empty()) { + return; + } + + // Remove a very common issue when we're parsing file names: spaces at the + // beginning of the path. + std::string::iterator it = in.begin(); + while (IsSpaceOrNewLine( *it ))++it; + if (it != in.begin()) { + in.erase(in.begin(),it+1); + } + + const char sep = getOsSeparator(); + for (it = in.begin(); it != in.end(); ++it) { + // Exclude :// and \\, which remain untouched. + // https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632 + if ( !strncmp(&*it, "://", 3 )) { + it += 3; + continue; + } + if (it == in.begin() && !strncmp(&*it, "\\\\", 2)) { + it += 2; + continue; + } + + // Cleanup path delimiters + if (*it == '/' || (*it) == '\\') { + *it = sep; + + // And we're removing double delimiters, frequent issue with + // incorrectly composited paths ... + if (last == *it) { + it = in.erase(it); + --it; + } + } + else if (*it == '%' && in.end() - it > 2) { + + // Hex sequence in URIs + if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) { + *it = HexOctetToDecimal(&*it); + it = in.erase(it+1,it+2); + --it; + } + } + + last = *it; + } + } private: - IOSystem* wrapped; - std::string src_file, base; - char sep; + IOSystem* wrapped; + std::string src_file, base; + char sep; }; } //!ns Assimp |