coreutil.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // Copyright (C) 2002-2012 Nikolaus Gebhardt
  2. // This file is part of the "Irrlicht Engine".
  3. // For conditions of distribution and use, see copyright notice in irrlicht.h
  4. #ifndef __IRR_CORE_UTIL_H_INCLUDED__
  5. #define __IRR_CORE_UTIL_H_INCLUDED__
  6. #include "irrString.h"
  7. #include "path.h"
  8. namespace irr
  9. {
  10. namespace core
  11. {
  12. /*! \file coreutil.h
  13. \brief File containing useful basic utility functions
  14. */
  15. // ----------- some basic quite often used string functions -----------------
  16. //! search if a filename has a proper extension
  17. inline s32 isFileExtension (const io::path& filename, const io::path& ext0,
  18. const io::path& ext1, const io::path& ext2)
  19. {
  20. s32 extPos = filename.findLast ( '.' );
  21. if ( extPos < 0 )
  22. return 0;
  23. extPos += 1;
  24. if ( filename.equals_substring_ignore_case ( ext0, extPos ) )
  25. return 1;
  26. if ( filename.equals_substring_ignore_case ( ext1, extPos ) )
  27. return 2;
  28. if ( filename.equals_substring_ignore_case ( ext2, extPos ) )
  29. return 3;
  30. return 0;
  31. }
  32. //! search if a filename has a proper extension
  33. inline bool hasFileExtension(const io::path& filename, const io::path& ext0,
  34. const io::path& ext1 = "", const io::path& ext2 = "")
  35. {
  36. return isFileExtension ( filename, ext0, ext1, ext2 ) > 0;
  37. }
  38. //! cut the filename extension from a source file path and store it in a dest file path
  39. inline io::path& cutFilenameExtension ( io::path &dest, const io::path &source )
  40. {
  41. s32 endPos = source.findLast ( '.' );
  42. dest = source.subString ( 0, endPos < 0 ? source.size () : endPos );
  43. return dest;
  44. }
  45. //! get the filename extension from a file path
  46. inline io::path& getFileNameExtension ( io::path &dest, const io::path &source )
  47. {
  48. s32 endPos = source.findLast ( '.' );
  49. if ( endPos < 0 )
  50. dest = "";
  51. else
  52. dest = source.subString ( endPos, source.size () );
  53. return dest;
  54. }
  55. //! delete path from filename
  56. inline io::path& deletePathFromFilename(io::path& filename)
  57. {
  58. // delete path from filename
  59. const fschar_t* s = filename.c_str();
  60. const fschar_t* p = s + filename.size();
  61. // search for path separator or beginning
  62. while ( *p != '/' && *p != '\\' && p != s )
  63. p--;
  64. if ( p != s )
  65. {
  66. ++p;
  67. filename = p;
  68. }
  69. return filename;
  70. }
  71. //! trim paths
  72. inline io::path& deletePathFromPath(io::path& filename, s32 pathCount)
  73. {
  74. // delete path from filename
  75. s32 i = filename.size();
  76. // search for path separator or beginning
  77. while ( i>=0 )
  78. {
  79. if ( filename[i] == '/' || filename[i] == '\\' )
  80. {
  81. if ( --pathCount <= 0 )
  82. break;
  83. }
  84. --i;
  85. }
  86. if ( i>0 )
  87. {
  88. filename [ i + 1 ] = 0;
  89. filename.validate();
  90. }
  91. else
  92. filename="";
  93. return filename;
  94. }
  95. //! looks if file is in the same directory of path. returns offset of directory.
  96. //! 0 means in same directory. 1 means file is direct child of path
  97. inline s32 isInSameDirectory ( const io::path& path, const io::path& file )
  98. {
  99. if ( path.size() && !path.equalsn ( file, path.size() ) )
  100. return -1;
  101. s32 subA = 0;
  102. s32 subB = 0;
  103. s32 pos = 0;
  104. while ( (pos = path.findNext ( '/', pos )) >= 0 )
  105. {
  106. subA += 1;
  107. pos += 1;
  108. }
  109. pos = 0;
  110. while ( (pos = file.findNext ( '/', pos )) >= 0 )
  111. {
  112. subB += 1;
  113. pos += 1;
  114. }
  115. return subB - subA;
  116. }
  117. //! splits a path into components
  118. static inline void splitFilename(const io::path &name, io::path* path=0,
  119. io::path* filename=0, io::path* extension=0, bool make_lower=false)
  120. {
  121. s32 i = name.size();
  122. s32 extpos = i;
  123. // search for path separator or beginning
  124. while ( i >= 0 )
  125. {
  126. if ( name[i] == '.' )
  127. {
  128. extpos = i;
  129. if ( extension )
  130. *extension = name.subString ( extpos + 1, name.size() - (extpos + 1), make_lower );
  131. }
  132. else
  133. if ( name[i] == '/' || name[i] == '\\' )
  134. {
  135. if ( filename )
  136. *filename = name.subString ( i + 1, extpos - (i + 1), make_lower );
  137. if ( path )
  138. {
  139. *path = name.subString ( 0, i + 1, make_lower );
  140. path->replace ( '\\', '/' );
  141. }
  142. return;
  143. }
  144. i -= 1;
  145. }
  146. if ( filename )
  147. *filename = name.subString ( 0, extpos, make_lower );
  148. }
  149. //! create a filename from components
  150. static inline io::path mergeFilename(const io::path& path, const io::path& filename, const io::path& extension = "")
  151. {
  152. io::path result(path);
  153. if ( !result.empty() )
  154. {
  155. fschar_t last = result.lastChar();
  156. if ( last != _IRR_TEXT('/') && last != _IRR_TEXT('\\') )
  157. result += _IRR_TEXT('/');
  158. }
  159. if ( !filename.empty() )
  160. result += filename;
  161. if ( !extension.empty() )
  162. {
  163. if ( !result.empty() && extension[0] != _IRR_TEXT('.') )
  164. result += _IRR_TEXT('.');
  165. result += extension;
  166. }
  167. return result;
  168. }
  169. //! some standard function ( to remove dependencies )
  170. inline s32 isdigit(s32 c) { return c >= '0' && c <= '9'; }
  171. inline s32 isspace(s32 c) { return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; }
  172. inline s32 isupper(s32 c) { return c >= 'A' && c <= 'Z'; }
  173. } // end namespace core
  174. } // end namespace irr
  175. #endif