coreutil.h 4.5 KB

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