// Copyright (C) 2002-2012 Nikolaus Gebhardt // This file is part of the "Irrlicht Engine". // For conditions of distribution and use, see copyright notice in irrlicht.h #ifndef __IRR_CORE_UTIL_H_INCLUDED__ #define __IRR_CORE_UTIL_H_INCLUDED__ #include "irrString.h" #include "path.h" namespace irr { namespace core { /*! \file coreutil.h \brief File containing useful basic utility functions */ // ----------- some basic quite often used string functions ----------------- //! search if a filename has a proper extension inline s32 isFileExtension ( const io::path& filename, const io::path& ext0, const io::path& ext1, const io::path& ext2) { s32 extPos = filename.findLast ( '.' ); if ( extPos < 0 ) return 0; extPos += 1; if ( filename.equals_substring_ignore_case ( ext0, extPos ) ) return 1; if ( filename.equals_substring_ignore_case ( ext1, extPos ) ) return 2; if ( filename.equals_substring_ignore_case ( ext2, extPos ) ) return 3; return 0; } //! search if a filename has a proper extension inline bool hasFileExtension ( const io::path& filename, const io::path& ext0, const io::path& ext1 = "", const io::path& ext2 = "") { return isFileExtension ( filename, ext0, ext1, ext2 ) > 0; } //! cut the filename extension from a source file path and store it in a dest file path inline io::path& cutFilenameExtension ( io::path &dest, const io::path &source ) { s32 endPos = source.findLast ( '.' ); dest = source.subString ( 0, endPos < 0 ? source.size () : endPos ); return dest; } //! get the filename extension from a file path inline io::path& getFileNameExtension ( io::path &dest, const io::path &source ) { s32 endPos = source.findLast ( '.' ); if ( endPos < 0 ) dest = ""; else dest = source.subString ( endPos, source.size () ); return dest; } //! delete path from filename inline io::path& deletePathFromFilename(io::path& filename) { // delete path from filename const fschar_t* s = filename.c_str(); const fschar_t* p = s + filename.size(); // search for path separator or beginning while ( *p != '/' && *p != '\\' && p != s ) p--; if ( p != s ) { ++p; filename = p; } return filename; } //! trim paths inline io::path& deletePathFromPath(io::path& filename, s32 pathCount) { // delete path from filename s32 i = filename.size(); // search for path separator or beginning while ( i>=0 ) { if ( filename[i] == '/' || filename[i] == '\\' ) { if ( --pathCount <= 0 ) break; } --i; } if ( i>0 ) { filename [ i + 1 ] = 0; filename.validate(); } else filename=""; return filename; } //! looks if file is in the same directory of path. returns offset of directory. //! 0 means in same directory. 1 means file is direct child of path inline s32 isInSameDirectory ( const io::path& path, const io::path& file ) { s32 subA = 0; s32 subB = 0; s32 pos; if ( path.size() && !path.equalsn ( file, path.size() ) ) return -1; pos = 0; while ( (pos = path.findNext ( '/', pos )) >= 0 ) { subA += 1; pos += 1; } pos = 0; while ( (pos = file.findNext ( '/', pos )) >= 0 ) { subB += 1; pos += 1; } return subB - subA; } // splits a path into components static inline void splitFilename(const io::path &name, io::path* path=0, io::path* filename=0, io::path* extension=0, bool make_lower=false) { s32 i = name.size(); s32 extpos = i; // search for path separator or beginning while ( i >= 0 ) { if ( name[i] == '.' ) { extpos = i; if ( extension ) *extension = name.subString ( extpos + 1, name.size() - (extpos + 1), make_lower ); } else if ( name[i] == '/' || name[i] == '\\' ) { if ( filename ) *filename = name.subString ( i + 1, extpos - (i + 1), make_lower ); if ( path ) { *path = name.subString ( 0, i + 1, make_lower ); path->replace ( '\\', '/' ); } return; } i -= 1; } if ( filename ) *filename = name.subString ( 0, extpos, make_lower ); } //! some standard function ( to remove dependencies ) #undef isdigit #undef isspace #undef isupper inline s32 isdigit(s32 c) { return c >= '0' && c <= '9'; } inline s32 isspace(s32 c) { return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; } inline s32 isupper(s32 c) { return c >= 'A' && c <= 'Z'; } } // end namespace core } // end namespace irr #endif