CmPath.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #pragma once
  2. #include "CmPrerequisitesUtil.h"
  3. #include <boost/filesystem.hpp>
  4. namespace CamelotFramework
  5. {
  6. typedef boost::filesystem3::path Path;
  7. typedef boost::filesystem3::wpath WPath;
  8. Path CM_UTILITY_EXPORT toPath(const String& p);
  9. WPath CM_UTILITY_EXPORT toPath(const WString& p);
  10. String CM_UTILITY_EXPORT toString(const Path& p);
  11. WString CM_UTILITY_EXPORT toWString(const WPath& p);
  12. /**
  13. * @brief Various string manipulations of file paths.
  14. */
  15. class CM_UTILITY_EXPORT PathUtil
  16. {
  17. public:
  18. static const WPath BLANK;
  19. static WString getExtension(const WString& path)
  20. {
  21. boost::filesystem3::wpath ext = boost::filesystem3::extension(boost::filesystem3::wpath(path.c_str()));
  22. return ext.wstring().c_str();
  23. }
  24. static WPath getExtension(const WPath& path)
  25. {
  26. return boost::filesystem3::extension(path);
  27. }
  28. static bool hasExtension(const WString& path, const WString& extension)
  29. {
  30. return getExtension(path) == extension;
  31. }
  32. static void replaceExtension(WPath& path, const WString& newExtension)
  33. {
  34. path.replace_extension(newExtension.c_str());
  35. }
  36. static WString parentPath(const WString& path)
  37. {
  38. return WPath(path.c_str()).parent_path().c_str();
  39. }
  40. static WPath parentPath(const WPath& path)
  41. {
  42. return path.parent_path();
  43. }
  44. /**
  45. * @brief Returns true if path child is included in path parent.
  46. * Both paths must be canonical.
  47. */
  48. static bool includes(const WString& child, const WString& parent)
  49. {
  50. boost::filesystem3::wpath childPath = child.c_str();
  51. boost::filesystem3::wpath parentPath = parent.c_str();
  52. auto iterChild = childPath.begin();
  53. auto iterParent = parentPath.begin();
  54. for(; iterChild != childPath.end(); ++iterChild, ++iterParent)
  55. {
  56. if(*iterChild != *iterParent)
  57. return false;
  58. }
  59. return true;
  60. }
  61. static WString combine(const WString& base, const WString& name)
  62. {
  63. if (base.empty())
  64. return name;
  65. else
  66. return base + L'/' + name;
  67. }
  68. static WPath combine(const WPath& base, const WPath& name)
  69. {
  70. return base / name;
  71. }
  72. static WPath getFilename(const WPath& path)
  73. {
  74. return path.filename();
  75. }
  76. /**
  77. * @brief Method for standardizing paths - use forward slashes only, end with slash.
  78. */
  79. static WString standardisePath(const WString& inPath)
  80. {
  81. WString path = inPath;
  82. std::replace(path.begin(), path.end(), L'\\', L'/');
  83. if(path[path.length() - 1] != L'/')
  84. path += L'/';
  85. return path;
  86. }
  87. /**
  88. * @brief Method for splitting a fully qualified filename into the base name and path.
  89. */
  90. static void splitFilename(const WString& qualifiedName, WString& outBasename, WString& outPath)
  91. {
  92. WString path = qualifiedName;
  93. // Replace \ with / first
  94. std::replace( path.begin(), path.end(), L'\\', L'/' );
  95. // split based on final /
  96. size_t i = path.find_last_of(L'/');
  97. if (i == String::npos)
  98. {
  99. outPath.clear();
  100. outBasename = qualifiedName;
  101. }
  102. else
  103. {
  104. outBasename = path.substr(i+1, path.size() - i - 1);
  105. outPath = path.substr(0, i+1);
  106. }
  107. }
  108. /**
  109. * @brief Method for splitting a filename into the base name and extension.
  110. */
  111. static void splitBaseFilename(const WString& fullName, WString& outBasename, WString& outExtension)
  112. {
  113. size_t i = fullName.find_last_of(L".");
  114. if (i == CamelotFramework::WString::npos)
  115. {
  116. outExtension.clear();
  117. outBasename = fullName;
  118. }
  119. else
  120. {
  121. outExtension = fullName.substr(i+1);
  122. outBasename = fullName.substr(0, i);
  123. }
  124. }
  125. /**
  126. * @brief Method for splitting a fully qualified filename into the base name, extension and path.
  127. */
  128. static void splitFullFilename(const WString& qualifiedName, WString& outBasename, WString& outExtention, WString& outPath)
  129. {
  130. WString fullName;
  131. splitFilename(qualifiedName, fullName, outPath);
  132. splitBaseFilename(fullName, outBasename, outExtention);
  133. }
  134. };
  135. template<> struct RTTIPlainType<WPath>
  136. {
  137. enum { id = TID_WPath }; enum { hasDynamicSize = 1 };
  138. static void toMemory(const WPath& data, char* memory)
  139. {
  140. rttiWriteElem(toWString(data), memory);
  141. }
  142. static UINT32 fromMemory(WPath& data, char* memory)
  143. {
  144. WString strData;
  145. RTTIPlainType<WString>::fromMemory(strData, memory);
  146. data = toPath(strData);
  147. return rttiGetElemSize(strData);
  148. }
  149. static UINT32 getDynamicSize(const WPath& data)
  150. {
  151. return rttiGetElemSize(toWString(data));
  152. }
  153. };
  154. }