Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
5.2 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include "pathstr.h"
  4. CPath::CPath(
  5. LPCTSTR pszRoot,
  6. LPCTSTR pszDir,
  7. LPCTSTR pszFile,
  8. LPCTSTR pszExt
  9. )
  10. {
  11. if (pszDir)
  12. SetPath(pszDir);
  13. if (pszRoot)
  14. SetRoot(pszRoot);
  15. if (pszFile)
  16. SetFileSpec(pszFile);
  17. if (pszExt)
  18. SetExtension(pszExt);
  19. }
  20. CPath::CPath(
  21. const CPath& rhs
  22. ) : CString(rhs)
  23. {
  24. }
  25. CPath&
  26. CPath::operator = (
  27. const CPath& rhs
  28. )
  29. {
  30. if (this != &rhs)
  31. {
  32. CString::operator = (rhs);
  33. }
  34. return *this;
  35. }
  36. CPath&
  37. CPath::operator = (
  38. LPCTSTR rhs
  39. )
  40. {
  41. CString::operator = (rhs);
  42. return *this;
  43. }
  44. void
  45. CPath::AddBackslash(
  46. void
  47. )
  48. {
  49. ::PathAddBackslash(GetBuffer(MAX(MAX_PATH, Length() + 2)));
  50. ReleaseBuffer();
  51. }
  52. void
  53. CPath::RemoveBackslash(
  54. void
  55. )
  56. {
  57. ::PathRemoveBackslash(GetBuffer());
  58. ReleaseBuffer();
  59. }
  60. bool
  61. CPath::GetRoot(
  62. CPath *pOut
  63. ) const
  64. {
  65. CPath temp(*this);
  66. temp.StripToRoot();
  67. *pOut = temp;
  68. return 0 < pOut->Length();
  69. }
  70. bool
  71. CPath::GetPath(
  72. CPath *pOut
  73. ) const
  74. {
  75. CPath temp(*this);
  76. temp.RemoveFileSpec();
  77. *pOut = temp;
  78. return 0 < pOut->Length();
  79. }
  80. bool
  81. CPath::GetDirectory(
  82. CPath *pOut
  83. ) const
  84. {
  85. if (GetPath(pOut))
  86. pOut->RemoveRoot();
  87. return 0 < pOut->Length();
  88. }
  89. bool
  90. CPath::GetExtension(
  91. CPath *pOut
  92. ) const
  93. {
  94. *pOut = ::PathFindExtension(*this);
  95. return 0 < pOut->Length();
  96. }
  97. bool
  98. CPath::GetFileSpec(
  99. CPath *pOut
  100. ) const
  101. {
  102. *pOut = ::PathFindFileName(*this);
  103. return 0 < pOut->Length();
  104. }
  105. bool
  106. CPath::Append(
  107. LPCTSTR psz
  108. )
  109. {
  110. bool bResult = boolify(::PathAppend(GetBuffer(MAX(MAX_PATH, Length() + lstrlen(psz) + 3)), psz));
  111. ReleaseBuffer();
  112. return bResult;
  113. }
  114. bool
  115. CPath::BuildRoot(
  116. int iDrive
  117. )
  118. {
  119. Empty();
  120. bool bResult = NULL != ::PathBuildRoot(GetBuffer(5), iDrive);
  121. ReleaseBuffer();
  122. return bResult;
  123. }
  124. bool
  125. CPath::Canonicalize(
  126. void
  127. )
  128. {
  129. CString strTemp(*this);
  130. bool bResult = boolify(::PathCanonicalize(GetBuffer(MAX(MAX_PATH, Size())), strTemp));
  131. ReleaseBuffer();
  132. return bResult;
  133. }
  134. bool
  135. CPath::Compact(
  136. HDC hdc,
  137. int cxPixels
  138. )
  139. {
  140. bool bResult = boolify(::PathCompactPath(hdc, GetBuffer(), cxPixels));
  141. ReleaseBuffer();
  142. return bResult;
  143. }
  144. bool
  145. CPath::CommonPrefix(
  146. LPCTSTR pszPath1,
  147. LPCTSTR pszPath2
  148. )
  149. {
  150. Empty();
  151. ::PathCommonPrefix(pszPath1,
  152. pszPath2,
  153. GetBuffer(MAX(MAX_PATH, (MAX(lstrlen(pszPath1), lstrlen(pszPath2)) + 1))));
  154. ReleaseBuffer();
  155. return 0 < Length();
  156. }
  157. void
  158. CPath::QuoteSpaces(
  159. void
  160. )
  161. {
  162. ::PathQuoteSpaces(GetBuffer(MAX(MAX_PATH, Length() + 3)));
  163. ReleaseBuffer();
  164. }
  165. void
  166. CPath::UnquoteSpaces(
  167. void
  168. )
  169. {
  170. ::PathUnquoteSpaces(GetBuffer());
  171. ReleaseBuffer();
  172. }
  173. void
  174. CPath::RemoveBlanks(
  175. void
  176. )
  177. {
  178. ::PathRemoveBlanks(GetBuffer());
  179. ReleaseBuffer();
  180. }
  181. void
  182. CPath::RemoveExtension(
  183. void
  184. )
  185. {
  186. PathRemoveExtension(GetBuffer());
  187. ReleaseBuffer();
  188. }
  189. void
  190. CPath::RemoveFileSpec(
  191. void
  192. )
  193. {
  194. ::PathRemoveFileSpec(GetBuffer());
  195. ReleaseBuffer();
  196. }
  197. void
  198. CPath::RemoveRoot(
  199. void
  200. )
  201. {
  202. LPTSTR psz = ::PathSkipRoot(*this);
  203. if (psz)
  204. {
  205. CPath temp(psz);
  206. *this = temp;
  207. }
  208. }
  209. void
  210. CPath::RemovePath(
  211. void
  212. )
  213. {
  214. CPath temp;
  215. GetFileSpec(&temp);
  216. *this = temp;
  217. }
  218. void
  219. CPath::StripToRoot(
  220. void
  221. )
  222. {
  223. ::PathStripToRoot(GetBuffer());
  224. ReleaseBuffer();
  225. }
  226. void
  227. CPath::SetRoot(
  228. LPCTSTR pszRoot
  229. )
  230. {
  231. CPath strTemp(*this);
  232. strTemp.RemoveRoot();
  233. *this = pszRoot;
  234. Append(strTemp);
  235. }
  236. void
  237. CPath::SetPath(
  238. LPCTSTR pszPath
  239. )
  240. {
  241. CPath strTemp(*this);
  242. *this = pszPath;
  243. strTemp.RemovePath();
  244. Append(strTemp);
  245. }
  246. void
  247. CPath::SetDirectory(
  248. LPCTSTR pszDir
  249. )
  250. {
  251. CPath path;
  252. GetPath(&path);
  253. path.StripToRoot();
  254. path.AddBackslash();
  255. path.Append(pszDir);
  256. SetPath(path);
  257. }
  258. void
  259. CPath::SetFileSpec(
  260. LPCTSTR pszFileSpec
  261. )
  262. {
  263. RemoveFileSpec();
  264. Append(pszFileSpec);
  265. }
  266. void
  267. CPath::SetExtension(
  268. LPCTSTR pszExt
  269. )
  270. {
  271. ::PathRenameExtension(GetBuffer(MAX(MAX_PATH, Length() + lstrlen(pszExt) + 2)), pszExt);
  272. ReleaseBuffer();
  273. }
  274. CPathIter::CPathIter(
  275. const CPath& path
  276. ) : m_path(path),
  277. m_pszCurrent((LPTSTR)m_path.Cstr())
  278. {
  279. //
  280. // Skip over leading whitespace and backslashes.
  281. //
  282. while(*m_pszCurrent &&
  283. (TEXT('\\') == *m_pszCurrent ||
  284. TEXT(' ') == *m_pszCurrent ||
  285. TEXT('\t') == *m_pszCurrent ||
  286. TEXT('\n') == *m_pszCurrent))
  287. {
  288. m_pszCurrent++;
  289. }
  290. }
  291. bool
  292. CPathIter::Next(
  293. CPath *pOut
  294. )
  295. {
  296. DBGASSERT((NULL != pOut));
  297. LPCTSTR pszStart = m_pszCurrent;
  298. if (NULL == pszStart || TEXT('\0') == *pszStart)
  299. return false;
  300. TCHAR chTemp = TEXT('\0');
  301. m_pszCurrent = ::PathFindNextComponent(pszStart);
  302. if (NULL != m_pszCurrent && *m_pszCurrent)
  303. SWAP(*(m_pszCurrent - 1), chTemp);
  304. *pOut = pszStart;
  305. if (TEXT('\0') != chTemp)
  306. SWAP(*(m_pszCurrent - 1), chTemp);
  307. return true;
  308. }
  309. void
  310. CPathIter::Reset(
  311. void
  312. )
  313. {
  314. m_pszCurrent = (LPTSTR)m_path.Cstr();
  315. }