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.

560 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: N C S T R I N G . H
  7. //
  8. // Contents: Common string routines.
  9. //
  10. // Notes:
  11. //
  12. // Author: shaunco 24 Mar 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include "ncdebug.h"
  17. #include "ncvalid.h"
  18. #include "ncmsz.h"
  19. #include "ncstl.h"
  20. const int c_cchGuidWithTerm = 39; // includes terminating null
  21. const int c_cbGuidWithTerm = c_cchGuidWithTerm * sizeof(WCHAR);
  22. inline ULONG CbOfSz (PCWSTR psz) { AssertH(psz); return wcslen (psz) * sizeof(WCHAR); }
  23. inline ULONG CbOfSza (PCSTR psza) { AssertH(psza); return strlen (psza) * sizeof(CHAR); }
  24. inline ULONG CbOfSzAndTerm (PCWSTR psz) { AssertH(psz); return (wcslen (psz) + 1) * sizeof(WCHAR); }
  25. inline ULONG CbOfSzaAndTerm (PCSTR psza) { AssertH(psza); return (strlen (psza) + 1) * sizeof(CHAR); }
  26. ULONG CbOfSzSafe (PCWSTR psz);
  27. ULONG CbOfSzaSafe (PCSTR psza);
  28. ULONG CbOfSzAndTermSafe (PCWSTR psz);
  29. ULONG CbOfSzaAndTermSafe (PCSTR psza);
  30. ULONG
  31. CchOfSzSafe (
  32. PCWSTR psz);
  33. inline ULONG CchToCb (ULONG cch) { return cch * sizeof(WCHAR); }
  34. struct MAP_SZ_DWORD
  35. {
  36. PCWSTR pszValue;
  37. DWORD dwValue;
  38. };
  39. PWSTR
  40. PszAllocateAndCopyPsz (
  41. PCWSTR pszSrc);
  42. extern const WCHAR c_szEmpty[];
  43. template<class T>
  44. VOID
  45. ConvertStringToColString (
  46. IN PCWSTR psz,
  47. IN const WCHAR chSeparator,
  48. OUT T& coll)
  49. {
  50. AssertSz(chSeparator, "Separator can not be \0");
  51. FreeCollectionAndItem(coll);
  52. if (NULL == psz)
  53. {
  54. return;
  55. }
  56. PWSTR pszBuf = new WCHAR[wcslen(psz) + 1];
  57. wcscpy(pszBuf, psz);
  58. WCHAR* pchString = pszBuf;
  59. WCHAR* pchSeparator;
  60. while (*pchString)
  61. {
  62. pchSeparator = wcschr(pchString, chSeparator);
  63. if (pchSeparator)
  64. {
  65. *pchSeparator = 0;
  66. }
  67. if (*pchString)
  68. {
  69. coll.push_back(new tstring(pchString));
  70. }
  71. if (pchSeparator)
  72. {
  73. pchString = pchSeparator + 1;
  74. }
  75. else
  76. {
  77. break;
  78. }
  79. }
  80. delete [] pszBuf;
  81. }
  82. template<class T>
  83. VOID
  84. ConvertColStringToString (
  85. IN const T& coll,
  86. IN const WCHAR chSeparator,
  87. OUT tstring& str)
  88. {
  89. AssertSz(chSeparator, "Separator can not be \0");
  90. if (chSeparator)
  91. {
  92. T::const_iterator iter = coll.begin();
  93. while (iter != coll.end())
  94. {
  95. str += (*iter)->c_str();
  96. ++iter;
  97. if (iter != coll.end())
  98. {
  99. str += chSeparator;
  100. }
  101. }
  102. }
  103. }
  104. DWORD
  105. WINAPIV
  106. DwFormatString (
  107. PCWSTR pszFmt,
  108. PWSTR pszBuf,
  109. DWORD cchBuf,
  110. ...);
  111. DWORD
  112. WINAPIV
  113. DwFormatStringWithLocalAlloc (
  114. PCWSTR pszFmt,
  115. PWSTR* ppszBuf,
  116. ...);
  117. enum NC_IGNORE_SPACES
  118. {
  119. NC_IGNORE,
  120. NC_DONT_IGNORE,
  121. };
  122. BOOL
  123. FFindStringInCommaSeparatedList (
  124. PCWSTR pszSubString,
  125. PCWSTR pszList,
  126. NC_IGNORE_SPACES eIgnoreSpaces,
  127. DWORD* pdwPosition);
  128. enum NC_FIND_ACTION
  129. {
  130. NC_NO_ACTION,
  131. NC_REMOVE_FIRST_MATCH,
  132. NC_REMOVE_ALL_MATCHES,
  133. };
  134. inline BOOL
  135. FFindFirstMatch (
  136. NC_FIND_ACTION eAction)
  137. {
  138. return (NC_NO_ACTION == eAction) || (NC_REMOVE_FIRST_MATCH == eAction);
  139. }
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Function: FIsBstrEmpty
  143. //
  144. // Purpose: Determines if the given BSTR is "empty" meaning the pointer
  145. // is NULL or the string is 0-length.
  146. //
  147. // Arguments:
  148. // bstr [in] BSTR to check.
  149. //
  150. // Returns: TRUE if the BSTR is empty, FALSE if not.
  151. //
  152. // Author: danielwe 20 May 1997
  153. //
  154. // Notes:
  155. //
  156. inline
  157. BOOL
  158. FIsBstrEmpty (
  159. BSTR bstr)
  160. {
  161. return !(bstr && *bstr);
  162. }
  163. //+---------------------------------------------------------------------------
  164. //
  165. // Function: FIsStrEmpty
  166. //
  167. // Purpose: Determines if the given PCWSTR is "empty" meaning the pointer
  168. // is NULL or the string is 0-length.
  169. //
  170. // Arguments:
  171. // bstr [in] BSTR to check.
  172. //
  173. // Returns: TRUE if the BSTR is empty, FALSE if not.
  174. //
  175. // Author: danielwe 20 May 1997
  176. //
  177. // Notes:
  178. //
  179. inline
  180. BOOL
  181. FIsStrEmpty (
  182. PCWSTR psz)
  183. {
  184. return !(psz && *psz);
  185. }
  186. //+---------------------------------------------------------------------------
  187. //
  188. // Function: FIsPrefix
  189. //
  190. // Purpose: Returns whether a string is a prefix of another string.
  191. //
  192. // Arguments:
  193. // pszPrefix [in] Potential prefix
  194. // pszString [in] String that may begin with the prefix
  195. //
  196. // Returns: TRUE if given prefix string is a prefix of the target string.
  197. //
  198. // Author: danielwe 24 Mar 1997
  199. //
  200. // Notes: Uses CompareString with the default locale.
  201. //
  202. inline
  203. BOOL
  204. FIsPrefix (
  205. PCWSTR pszPrefix,
  206. PCWSTR pszString)
  207. {
  208. Assert (pszPrefix);
  209. Assert (pszString);
  210. return (0 == _wcsnicmp(pszPrefix, pszString, wcslen(pszPrefix)));
  211. }
  212. BOOL
  213. FIsSubstr (
  214. PCWSTR pszSubString,
  215. PCWSTR pszString);
  216. HRESULT
  217. HrAddStringToDelimitedSz (
  218. PCWSTR pszAddString,
  219. PCWSTR pszIn,
  220. WCHAR chDelimiter,
  221. DWORD dwFlags,
  222. DWORD dwStringIndex,
  223. PWSTR* ppszOut);
  224. HRESULT
  225. HrRemoveStringFromDelimitedSz (
  226. PCWSTR pszRemove,
  227. PCWSTR pszIn,
  228. WCHAR chDelimiter,
  229. DWORD dwFlags,
  230. PWSTR* ppszOut);
  231. //+---------------------------------------------------------------------------
  232. //
  233. // Function: template<class T> ColStringToMultiSz
  234. //
  235. // Purpose: Convert an STL collection of tstring pointers to a multi-sz.
  236. //
  237. // Arguments:
  238. // listStr [in] list of tstring pointers to put in the multi-sz.
  239. // ppszOut [out] the returned multi-sz.
  240. //
  241. // Returns: nothing.
  242. //
  243. // Author: shaunco 10 Apr 1997
  244. //
  245. // Notes: The output multi-sz should be freed using delete.
  246. //
  247. template<class T>
  248. VOID
  249. ColStringToMultiSz (
  250. const T& colStr,
  251. PWSTR* ppszOut)
  252. {
  253. Assert (ppszOut);
  254. // Count up the count of characters consumed by the list of strings.
  255. // This count includes the null terminator of each string.
  256. //
  257. T::const_iterator iter;
  258. UINT cch = 0;
  259. for (iter = colStr.begin(); iter != colStr.end(); iter++)
  260. {
  261. tstring* pstr = *iter;
  262. if (!pstr->empty())
  263. {
  264. cch += (UINT)(pstr->length() + 1);
  265. }
  266. }
  267. if (cch)
  268. {
  269. // Allocate the multi-sz. Assumes new will throw on error.
  270. //
  271. PWSTR pszOut = new WCHAR [cch + 1];
  272. *ppszOut = pszOut;
  273. // Copy the strings to the multi-sz.
  274. //
  275. for (iter = colStr.begin(); iter != colStr.end(); iter++)
  276. {
  277. tstring* pstr = *iter;
  278. if (!pstr->empty())
  279. {
  280. lstrcpyW (pszOut, pstr->c_str());
  281. pszOut += pstr->length() + 1;
  282. }
  283. }
  284. // Null terminate the multi-sz.
  285. Assert (pszOut == *ppszOut + cch);
  286. *pszOut = 0;
  287. }
  288. else
  289. {
  290. *ppszOut = NULL;
  291. }
  292. }
  293. //+---------------------------------------------------------------------------
  294. //
  295. // Function: template<class T> DeleteColString
  296. //
  297. // Purpose: Empty a list of tstring and delete each tstring as it is
  298. // removed.
  299. //
  300. // Arguments:
  301. // pcolstr [inout] Collection of tstring pointers to delete and empty
  302. //
  303. // Returns: nothing
  304. //
  305. // Author: mikemi 30 Apr 1997
  306. //
  307. // Notes:
  308. //
  309. template<class T>
  310. VOID
  311. DeleteColString (
  312. T* pcolstr)
  313. {
  314. Assert( pcolstr );
  315. T::const_iterator iter;
  316. tstring* pstr;
  317. for (iter = pcolstr->begin(); iter != pcolstr->end(); iter++)
  318. {
  319. pstr = *iter;
  320. delete pstr;
  321. }
  322. pcolstr->erase( pcolstr->begin(), pcolstr->end() );
  323. }
  324. //+---------------------------------------------------------------------------
  325. //
  326. // Function: template<class T> MultiSzToColString
  327. //
  328. // Purpose: Convert an multi-sz buffer to a STL collection of tstring
  329. // pointers.
  330. //
  331. // Arguments:
  332. // pmsz [in] the multi-sz to convert (Can be NULL)
  333. // pcolstr [out] list of tstring pointers to add allocated tstrings to
  334. //
  335. // Returns: nothing
  336. //
  337. // Author: mikemi 30 Apr 1997
  338. //
  339. // Notes: The output collection should be freed using DeleteColString.
  340. // This function will delete the collection list passed
  341. //
  342. template<class T>
  343. VOID
  344. MultiSzToColString (
  345. PCWSTR pmsz,
  346. T* pcolstr)
  347. {
  348. Assert (pcolstr);
  349. if (!pcolstr->empty())
  350. {
  351. DeleteColString (pcolstr);
  352. }
  353. if (pmsz)
  354. {
  355. while (*pmsz)
  356. {
  357. tstring* pstr = new tstring;
  358. if (pstr)
  359. {
  360. *pstr = pmsz;
  361. pcolstr->push_back (pstr);
  362. }
  363. // get the next string even if new failed
  364. pmsz += lstrlen (pmsz) + 1;
  365. }
  366. }
  367. }
  368. //+---------------------------------------------------------------------------
  369. //
  370. // Function: template<class T> RemoveDupsInColPtr
  371. //
  372. // Purpose: Remove all duplicate entries in an STL collection of pointers
  373. // to objects.
  374. //
  375. // Arguments:
  376. // pcol [inout] Collection of pointers to objects.
  377. //
  378. // Returns: nothing
  379. //
  380. // Author: mikemi 03 May 1997
  381. //
  382. // Notes: The objects pointed at should have a comparison operator
  383. //
  384. template<class T>
  385. VOID
  386. RemoveDupsInColPtr (
  387. T* pcol)
  388. {
  389. Assert (pcol);
  390. // remove duplicates
  391. //
  392. T::iterator posItem;
  393. T::iterator pos;
  394. T::value_type pItem;
  395. T::value_type p;
  396. posItem = pcol->begin();
  397. while (posItem != pcol->end())
  398. {
  399. pItem = *posItem;
  400. // for every other item, remove the duplicates
  401. pos = posItem;
  402. pos++;
  403. while (pos != pcol->end())
  404. {
  405. p = *pos;
  406. if ( *pItem == *p )
  407. {
  408. pos = pcol->erase( pos );
  409. delete p;
  410. }
  411. else
  412. {
  413. pos++;
  414. }
  415. }
  416. // increment afterwards due to fact that we are removing,
  417. // and otherwise could have removed the item it pointed to
  418. posItem++;
  419. }
  420. }
  421. //+---------------------------------------------------------------------------
  422. //
  423. // Function: template<class T> CopyColPtr
  424. //
  425. // Purpose: Copies one collection of pointers into another.
  426. //
  427. // Arguments:
  428. // pcolDest [out] Collection of pointers to objects.
  429. // pcolSrc [in] Collection of pointers to objects.
  430. //
  431. // Returns: nothing
  432. //
  433. // Author: BillBe 13 Jun 1998
  434. //
  435. // Notes:
  436. //
  437. template<class T>
  438. VOID
  439. CopyColPtr (T* pcolDest, const T& colSrc)
  440. {
  441. Assert (pcolDest);
  442. T::iterator posItem;
  443. // Clear out destination
  444. pcolDest->erase(pcolDest->begin(), pcolDest->end());
  445. // Go through each item in pcolSrc and add to pcolDest
  446. //
  447. posItem = colSrc.begin();
  448. while (posItem != colSrc.end())
  449. {
  450. pcolDest->push_back(*posItem);
  451. posItem++;
  452. }
  453. }
  454. PCWSTR
  455. SzLoadStringPcch (
  456. HINSTANCE hinst,
  457. UINT unId,
  458. int* pcch);
  459. //+---------------------------------------------------------------------------
  460. //
  461. // Function: SzLoadString
  462. //
  463. // Purpose: Load a resource string. (This function will never return NULL.)
  464. //
  465. // Arguments:
  466. // hinst [in] Instance handle of module with the string resource.
  467. // unId [in] Resource ID of the string to load.
  468. //
  469. // Returns: Pointer to the constant string.
  470. //
  471. // Author: shaunco 24 Mar 1997
  472. //
  473. // Notes: See SzLoadStringPcch()
  474. //
  475. inline
  476. PCWSTR
  477. SzLoadString (
  478. HINSTANCE hinst,
  479. UINT unId)
  480. {
  481. int cch;
  482. return SzLoadStringPcch(hinst, unId, &cch);
  483. }
  484. PSTR
  485. SzaDupSza (
  486. IN PCSTR pszaSrc);
  487. PWSTR
  488. SzDupSz (
  489. IN PCWSTR pszSrc);