commit
259fd2df2d
|
@ -42,13 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* Implements a filter system to filter calls to Exists() and Open()
|
* Implements a filter system to filter calls to Exists() and Open()
|
||||||
* in order to improve the success rate of file opening ...
|
* in order to improve the success rate of file opening ...
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
#ifndef AI_FILESYSTEMFILTER_H_INC
|
#ifndef AI_FILESYSTEMFILTER_H_INC
|
||||||
#define AI_FILESYSTEMFILTER_H_INC
|
#define AI_FILESYSTEMFILTER_H_INC
|
||||||
|
|
||||||
#include "../include/assimp/IOSystem.hpp"
|
#include <assimp/IOSystem.hpp>
|
||||||
#include "../include/assimp/DefaultLogger.hpp"
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include "../include/assimp/fast_atof.h"
|
#include <assimp/fast_atof.h>
|
||||||
#include "../include/assimp/ParsingUtils.h"
|
#include <assimp/ParsingUtils.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -64,90 +65,89 @@ class FileSystemFilter : public IOSystem
|
||||||
public:
|
public:
|
||||||
/** Constructor. */
|
/** Constructor. */
|
||||||
FileSystemFilter(const std::string& file, IOSystem* old)
|
FileSystemFilter(const std::string& file, IOSystem* old)
|
||||||
: wrapped (old)
|
: mWrapped (old)
|
||||||
, src_file (file)
|
, mSrc_file(file)
|
||||||
, sep(wrapped->getOsSeparator())
|
, sep(mWrapped->getOsSeparator()) {
|
||||||
{
|
ai_assert(nullptr != mWrapped);
|
||||||
ai_assert(NULL != wrapped);
|
|
||||||
|
|
||||||
// Determine base directory
|
// Determine base directory
|
||||||
base = src_file;
|
mBase = mSrc_file;
|
||||||
std::string::size_type ss2;
|
std::string::size_type ss2;
|
||||||
if (std::string::npos != (ss2 = base.find_last_of("\\/"))) {
|
if (std::string::npos != (ss2 = mBase.find_last_of("\\/"))) {
|
||||||
base.erase(ss2,base.length()-ss2);
|
mBase.erase(ss2,mBase.length()-ss2);
|
||||||
}
|
} else {
|
||||||
else {
|
mBase = "";
|
||||||
base = "";
|
|
||||||
// return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the directory is terminated properly
|
// make sure the directory is terminated properly
|
||||||
char s;
|
char s;
|
||||||
|
|
||||||
if (base.length() == 0) {
|
if ( mBase.empty() ) {
|
||||||
base = ".";
|
mBase = ".";
|
||||||
base += getOsSeparator();
|
mBase += getOsSeparator();
|
||||||
}
|
} else if ((s = *(mBase.end()-1)) != '\\' && s != '/') {
|
||||||
else if ((s = *(base.end()-1)) != '\\' && s != '/') {
|
mBase += getOsSeparator();
|
||||||
base += getOsSeparator();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultLogger::get()->info("Import root directory is \'" + base + "\'");
|
DefaultLogger::get()->info("Import root directory is \'" + mBase + "\'");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destructor. */
|
/** Destructor. */
|
||||||
~FileSystemFilter()
|
~FileSystemFilter() {
|
||||||
{
|
// empty
|
||||||
// haha
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Tests for the existence of a file at the given path. */
|
/** Tests for the existence of a file at the given path. */
|
||||||
bool Exists( const char* pFile) const
|
bool Exists( const char* pFile) const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
|
|
||||||
std::string tmp = pFile;
|
std::string tmp = pFile;
|
||||||
|
|
||||||
// Currently this IOSystem is also used to open THE ONE FILE.
|
// Currently this IOSystem is also used to open THE ONE FILE.
|
||||||
if (tmp != src_file) {
|
if (tmp != mSrc_file) {
|
||||||
BuildPath(tmp);
|
BuildPath(tmp);
|
||||||
Cleanup(tmp);
|
Cleanup(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrapped->Exists(tmp);
|
return mWrapped->Exists(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the directory separator. */
|
/** Returns the directory separator. */
|
||||||
char getOsSeparator() const
|
char getOsSeparator() const {
|
||||||
{
|
|
||||||
return sep;
|
return sep;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Open a new file with a given path. */
|
/** Open a new file with a given path. */
|
||||||
IOStream* Open( const char* pFile, const char* pMode = "rb")
|
IOStream* Open( const char* pFile, const char* pMode = "rb") {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
ai_assert(pFile);
|
if ( nullptr == pFile || nullptr == pMode ) {
|
||||||
ai_assert(pMode);
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ai_assert( nullptr != pFile );
|
||||||
|
ai_assert( nullptr != pMode );
|
||||||
|
|
||||||
// First try the unchanged path
|
// First try the unchanged path
|
||||||
IOStream* s = wrapped->Open(pFile,pMode);
|
IOStream* s = mWrapped->Open(pFile,pMode);
|
||||||
|
|
||||||
if (!s) {
|
if (nullptr == s) {
|
||||||
std::string tmp = pFile;
|
std::string tmp = pFile;
|
||||||
|
|
||||||
// Try to convert between absolute and relative paths
|
// Try to convert between absolute and relative paths
|
||||||
BuildPath(tmp);
|
BuildPath(tmp);
|
||||||
s = wrapped->Open(tmp,pMode);
|
s = mWrapped->Open(tmp,pMode);
|
||||||
|
|
||||||
if (!s) {
|
if (nullptr == s) {
|
||||||
// Finally, look for typical issues with paths
|
// Finally, look for typical issues with paths
|
||||||
// and try to correct them. This is our last
|
// and try to correct them. This is our last
|
||||||
// resort.
|
// resort.
|
||||||
tmp = pFile;
|
tmp = pFile;
|
||||||
Cleanup(tmp);
|
Cleanup(tmp);
|
||||||
BuildPath(tmp);
|
BuildPath(tmp);
|
||||||
s = wrapped->Open(tmp,pMode);
|
s = mWrapped->Open(tmp,pMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,76 +156,75 @@ public:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Closes the given file and releases all resources associated with it. */
|
/** Closes the given file and releases all resources associated with it. */
|
||||||
void Close( IOStream* pFile)
|
void Close( IOStream* pFile) {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->Close(pFile);
|
return mWrapped->Close(pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Compare two paths */
|
/** Compare two paths */
|
||||||
bool ComparePaths (const char* one, const char* second) const
|
bool ComparePaths (const char* one, const char* second) const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->ComparePaths (one,second);
|
return mWrapped->ComparePaths (one,second);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Pushes a new directory onto the directory stack. */
|
/** Pushes a new directory onto the directory stack. */
|
||||||
bool PushDirectory(const std::string &path)
|
bool PushDirectory(const std::string &path ) {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->PushDirectory(path);
|
return mWrapped->PushDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the top directory from the stack. */
|
/** Returns the top directory from the stack. */
|
||||||
const std::string &CurrentDirectory() const
|
const std::string &CurrentDirectory() const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->CurrentDirectory();
|
return mWrapped->CurrentDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the number of directories stored on the stack. */
|
/** Returns the number of directories stored on the stack. */
|
||||||
size_t StackSize() const
|
size_t StackSize() const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->StackSize();
|
return mWrapped->StackSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Pops the top directory from the stack. */
|
/** Pops the top directory from the stack. */
|
||||||
bool PopDirectory()
|
bool PopDirectory() {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->PopDirectory();
|
return mWrapped->PopDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Creates an new directory at the given path. */
|
/** Creates an new directory at the given path. */
|
||||||
bool CreateDirectory(const std::string &path)
|
bool CreateDirectory(const std::string &path) {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->CreateDirectory(path);
|
return mWrapped->CreateDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Will change the current directory to the given path. */
|
/** Will change the current directory to the given path. */
|
||||||
bool ChangeDirectory(const std::string &path)
|
bool ChangeDirectory(const std::string &path) {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->ChangeDirectory(path);
|
return mWrapped->ChangeDirectory(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Delete file. */
|
/** Delete file. */
|
||||||
bool DeleteFile(const std::string &file)
|
bool DeleteFile(const std::string &file) {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
return wrapped->DeleteFile(file);
|
return mWrapped->DeleteFile(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Build a valid path from a given relative or absolute path.
|
/** Build a valid path from a given relative or absolute path.
|
||||||
*/
|
*/
|
||||||
void BuildPath (std::string& in) const
|
void BuildPath (std::string& in) const {
|
||||||
{
|
ai_assert( nullptr != mWrapped );
|
||||||
// if we can already access the file, great.
|
// if we can already access the file, great.
|
||||||
if (in.length() < 3 || wrapped->Exists(in)) {
|
if (in.length() < 3 || mWrapped->Exists(in)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,8 +232,8 @@ private:
|
||||||
if (in[1] != ':') {
|
if (in[1] != ':') {
|
||||||
|
|
||||||
// append base path and try
|
// append base path and try
|
||||||
const std::string tmp = base + in;
|
const std::string tmp = mBase + in;
|
||||||
if (wrapped->Exists(tmp)) {
|
if (mWrapped->Exists(tmp)) {
|
||||||
in = tmp;
|
in = tmp;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -256,7 +255,7 @@ private:
|
||||||
std::string::size_type last_dirsep = std::string::npos;
|
std::string::size_type last_dirsep = std::string::npos;
|
||||||
|
|
||||||
while(true) {
|
while(true) {
|
||||||
tmp = base;
|
tmp = mBase;
|
||||||
tmp += sep;
|
tmp += sep;
|
||||||
|
|
||||||
std::string::size_type dirsep = in.rfind('/', last_dirsep);
|
std::string::size_type dirsep = in.rfind('/', last_dirsep);
|
||||||
|
@ -272,7 +271,7 @@ private:
|
||||||
last_dirsep = dirsep-1;
|
last_dirsep = dirsep-1;
|
||||||
|
|
||||||
tmp += in.substr(dirsep+1, in.length()-pos);
|
tmp += in.substr(dirsep+1, in.length()-pos);
|
||||||
if (wrapped->Exists(tmp)) {
|
if (mWrapped->Exists(tmp)) {
|
||||||
in = tmp;
|
in = tmp;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -285,15 +284,14 @@ private:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Cleanup the given path
|
/** Cleanup the given path
|
||||||
*/
|
*/
|
||||||
void Cleanup (std::string& in) const
|
void Cleanup (std::string& in) const {
|
||||||
{
|
|
||||||
char last = 0;
|
|
||||||
if(in.empty()) {
|
if(in.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove a very common issue when we're parsing file names: spaces at the
|
// Remove a very common issue when we're parsing file names: spaces at the
|
||||||
// beginning of the path.
|
// beginning of the path.
|
||||||
|
char last = 0;
|
||||||
std::string::iterator it = in.begin();
|
std::string::iterator it = in.begin();
|
||||||
while (IsSpaceOrNewLine( *it ))++it;
|
while (IsSpaceOrNewLine( *it ))++it;
|
||||||
if (it != in.begin()) {
|
if (it != in.begin()) {
|
||||||
|
@ -323,9 +321,7 @@ private:
|
||||||
it = in.erase(it);
|
it = in.erase(it);
|
||||||
--it;
|
--it;
|
||||||
}
|
}
|
||||||
}
|
} else if (*it == '%' && in.end() - it > 2) {
|
||||||
else if (*it == '%' && in.end() - it > 2) {
|
|
||||||
|
|
||||||
// Hex sequence in URIs
|
// Hex sequence in URIs
|
||||||
if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) {
|
if( IsHex((&*it)[0]) && IsHex((&*it)[1]) ) {
|
||||||
*it = HexOctetToDecimal(&*it);
|
*it = HexOctetToDecimal(&*it);
|
||||||
|
@ -339,8 +335,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
IOSystem* wrapped;
|
IOSystem *mWrapped;
|
||||||
std::string src_file, base;
|
std::string mSrc_file, mBase;
|
||||||
char sep;
|
char sep;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue