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.

339 lines
7.6 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1994.
  5. //
  6. // File: pathpars.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 2-10-96 srikants Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #include <pch.cxx>
  18. #pragma hdrstop
  19. #include <pathpars.hxx>
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Member: CPathParser::_SkipToNextBackSlash
  23. //
  24. // Synopsis: Increments _iNext to position at the next backslash.
  25. //
  26. // History: 2-11-96 srikants Created
  27. //
  28. // Notes:
  29. //
  30. //----------------------------------------------------------------------------
  31. void CPathParser::_SkipToNextBackSlash()
  32. {
  33. for ( ; _iNext < _len ; _iNext++ )
  34. {
  35. if ( wBackSlash == _pwszPath[_iNext] )
  36. break;
  37. }
  38. }
  39. //+---------------------------------------------------------------------------
  40. //
  41. // Member: CPathParser::_IsDriveName
  42. //
  43. // Synopsis: Checks if the first component of the path is a drive name.
  44. //
  45. //
  46. // Returns: TRUE if it has a drive name.
  47. // FALSE o/w
  48. //
  49. // History: 2-11-96 srikants Created
  50. //
  51. // Notes:
  52. //
  53. //----------------------------------------------------------------------------
  54. BOOL CPathParser::_IsDriveName() const
  55. {
  56. if ( _len < cMinDriveName )
  57. return FALSE;
  58. if ( wColon == _pwszPath[1] && iswalpha(_pwszPath[0]) )
  59. return TRUE;
  60. return FALSE;
  61. }
  62. //+---------------------------------------------------------------------------
  63. //
  64. // Member: CPathParser::_IsUNCName
  65. //
  66. // Synopsis: Tests if the given path is a UNC name.
  67. //
  68. // History: 2-11-96 srikants Created
  69. //
  70. // Notes:
  71. //
  72. //----------------------------------------------------------------------------
  73. BOOL CPathParser::_IsUNCName()
  74. {
  75. if ( _len < cMinUNC )
  76. return FALSE;
  77. //
  78. // Check if the first two chars are "\\"
  79. //
  80. if ( wBackSlash != _pwszPath[0] || _pwszPath[1] != wBackSlash )
  81. return FALSE;
  82. //
  83. // Now look for a back slash from the third character.
  84. //
  85. _iNext = 3;
  86. _SkipToNextBackSlash();
  87. if ( _iNext < _len )
  88. {
  89. Win4Assert( wBackSlash == _pwszPath[_iNext] );
  90. return TRUE;
  91. }
  92. return FALSE;
  93. }
  94. //+---------------------------------------------------------------------------
  95. //
  96. // Member: CPathParser::_SkipToNext
  97. //
  98. // Synopsis: Positions _iNext beyond the next backslash.
  99. //
  100. // History: 2-11-96 srikants Created
  101. //
  102. // Notes:
  103. //
  104. //----------------------------------------------------------------------------
  105. void CPathParser::_SkipToNext()
  106. {
  107. // Win4Assert( _iNext < _len && !_IsAtBackSlash() );
  108. _SkipToNextBackSlash();
  109. if ( _iNext < _len )
  110. {
  111. Win4Assert( _IsAtBackSlash() );
  112. _iNext++;
  113. }
  114. }
  115. //+---------------------------------------------------------------------------
  116. //
  117. // Member: CPathParser::_SkipUNC
  118. //
  119. // Synopsis: Skips the UNC part of the name.
  120. //
  121. // History: 2-11-96 srikants Created
  122. //
  123. // Notes:
  124. //
  125. //----------------------------------------------------------------------------
  126. void CPathParser::_SkipUNC()
  127. {
  128. Win4Assert( wBackSlash == _pwszPath[_iNext] );
  129. _iNext++;
  130. //
  131. // Locate the next backslash or EOS
  132. //
  133. _SkipToNext();
  134. }
  135. //+---------------------------------------------------------------------------
  136. //
  137. // Member: CPathParser::_SkipDrive
  138. //
  139. // Synopsis: Skips the "drive" part of the path.
  140. //
  141. // History: 2-11-96 srikants Created
  142. //
  143. // Notes:
  144. //
  145. //----------------------------------------------------------------------------
  146. void CPathParser::_SkipDrive()
  147. {
  148. if ( _len > cMinDriveName && wBackSlash == _pwszPath[cMinDriveName] )
  149. _iNext = cMinDriveName+1;
  150. else
  151. _iNext = _len;
  152. }
  153. //+---------------------------------------------------------------------------
  154. //
  155. // Member: CPathParser::Init
  156. //
  157. // Synopsis: Initializes the member variables for the given path.
  158. //
  159. // Arguments: [pwszPath] -
  160. // [len] -
  161. //
  162. // History: 2-11-96 srikants Created
  163. //
  164. // Notes:
  165. //
  166. //----------------------------------------------------------------------------
  167. void CPathParser::Init( WCHAR const * pwszPath, ULONG len )
  168. {
  169. _pwszPath = pwszPath;
  170. _pCurr = pwszPath;
  171. Win4Assert( 0 != pwszPath );
  172. if ( 0 == len )
  173. _len = wcslen( pwszPath );
  174. else
  175. _len = len;
  176. _iNext = _len;
  177. Win4Assert( wBackSlash != pwszPath[0] || _IsUNCName() );
  178. if ( _IsUNCName() )
  179. {
  180. _type = eUNC;
  181. _SkipUNC();
  182. }
  183. else if ( _IsDriveName() )
  184. {
  185. _type = eDrivePath;
  186. _SkipDrive();
  187. }
  188. else
  189. {
  190. _iNext = 0;
  191. _SkipToNext();
  192. }
  193. }
  194. //+---------------------------------------------------------------------------
  195. //
  196. // Member: ~ctor of CPathParser - initializes the member variables.
  197. //
  198. // Arguments: [pwszPath] -
  199. // [len] -
  200. //
  201. // History: 2-11-96 srikants Created
  202. //
  203. // Notes:
  204. //
  205. //----------------------------------------------------------------------------
  206. CPathParser::CPathParser( WCHAR const * pwszPath, ULONG len )
  207. : _pwszPath(0),
  208. _pCurr(0),
  209. _type(eRelative)
  210. {
  211. Init( pwszPath, len );
  212. }
  213. //+---------------------------------------------------------------------------
  214. //
  215. // Member: CPathParser::GetFileName
  216. //
  217. // Synopsis: Fetches the current "filename" component. Note that the full
  218. // path is NOT returned.
  219. //
  220. // Arguments: [wszBuf] - Buffer to copy the current component into.
  221. // [cc] - On input, the max WCHARS in buffer. On output, the
  222. // length of the string in WCHARS.
  223. //
  224. // Returns: TRUE if the buffer is sufficient. No data is copied to wszBuf.
  225. // FALSE if the buffer is too small. cc gives the number of
  226. // characters in the string.
  227. //
  228. // History: 2-11-96 srikants Created
  229. //
  230. // Notes:
  231. //
  232. //----------------------------------------------------------------------------
  233. BOOL CPathParser::GetFileName( WCHAR * wszBuf, ULONG & cc ) const
  234. {
  235. Win4Assert( _pCurr >= _pwszPath );
  236. Win4Assert( _iNext <= _len );
  237. ULONG len = _iNext - (ULONG)(_pCurr - _pwszPath);
  238. if ( cc <= len )
  239. {
  240. cc = len;
  241. return FALSE;
  242. }
  243. RtlCopyMemory( wszBuf, _pCurr, len*sizeof(WCHAR) );
  244. wszBuf[len] = 0;
  245. cc = len;
  246. return TRUE;
  247. }
  248. //+---------------------------------------------------------------------------
  249. //
  250. // Member: CPathParser::GetFilePath
  251. //
  252. // Synopsis: Same as GetFileName but returns the full path upto the current
  253. // component.
  254. //
  255. // Arguments: [wszBuf] -
  256. // [cc] -
  257. //
  258. // History: 2-11-96 srikants Created
  259. //
  260. // Notes:
  261. //
  262. //----------------------------------------------------------------------------
  263. BOOL CPathParser::GetFilePath( WCHAR * wszBuf, ULONG & cc ) const
  264. {
  265. Win4Assert( _pCurr >= _pwszPath );
  266. Win4Assert( _iNext <= _len );
  267. ULONG len = _iNext;
  268. if ( cc <= len )
  269. {
  270. cc = len;
  271. return FALSE;
  272. }
  273. RtlCopyMemory( wszBuf, _pwszPath, len*sizeof(WCHAR) );
  274. wszBuf[len] = 0;
  275. cc = len;
  276. return TRUE;
  277. }
  278. //+---------------------------------------------------------------------------
  279. //
  280. // Member: CPathParser::Next
  281. //
  282. // Synopsis: Positions the iterator over the next component.
  283. //
  284. // History: 2-11-96 srikants Created
  285. //
  286. // Notes:
  287. //
  288. //----------------------------------------------------------------------------
  289. void CPathParser::Next()
  290. {
  291. Win4Assert( !IsLastComp() );
  292. _pCurr = _pwszPath + _iNext;
  293. _iNext++;
  294. _SkipToNext();
  295. }