coreutil.h 4.5 KB

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