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.

439 lines
9.9 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. //
  3. // Enhancement of std::basic_string; Windows-aware version
  4. //
  5. // 8-14-97 sburns
  6. // Users of this class should assume that none of the member functions here
  7. // are threadsafe: that is, that concurrent calls to member functions on the
  8. // same instance are not guaranteed to produce correct results. The static
  9. // class functions are, however, threadsafe.
  10. typedef
  11. std::basic_string<
  12. char,
  13. std::char_traits<char>,
  14. Burnslib::Heap::Allocator<char> >
  15. AnsiString;
  16. typedef
  17. std::basic_string<
  18. wchar_t,
  19. std::char_traits<wchar_t>,
  20. Burnslib::Heap::Allocator<wchar_t> >
  21. StringBase;
  22. class String : public StringBase
  23. {
  24. public:
  25. typedef StringBase base;
  26. // contructor pass-thrus: we support all of the constructors of the
  27. // base class.
  28. explicit String()
  29. :
  30. base()
  31. {
  32. }
  33. //lint -e(1931) allow implicit type conversion with this ctor
  34. String(const base& x)
  35. :
  36. base(x)
  37. {
  38. }
  39. String(const String& x, base::size_type p, base::size_type m)
  40. :
  41. base(x, p, m)
  42. {
  43. }
  44. String(base::const_pointer s, base::size_type n)
  45. :
  46. base(s, n)
  47. {
  48. }
  49. //lint -e(1931) allow implicit type conversion with this ctor
  50. String(base::const_pointer s)
  51. :
  52. base(s)
  53. {
  54. }
  55. String(base::size_type n, base::value_type c)
  56. :
  57. base(n, c)
  58. {
  59. }
  60. String(base::const_iterator f, base::const_iterator l)
  61. :
  62. base(f, l)
  63. {
  64. }
  65. //
  66. // Enhancements to the base class std::base
  67. //
  68. // conversion from ANSI to Unicode
  69. String(PCSTR lpsz);
  70. String(const AnsiString& s);
  71. // Same as compare, except case is ignored.
  72. int
  73. icompare(const String& str) const;
  74. // returns true if the string consists entirely of digits, false
  75. // otherwise.
  76. bool
  77. is_numeric() const;
  78. // Overload of the replace() family of methods. Replaces all occurrances
  79. // of the substring 'from' with the string 'to'. Returns *this. All
  80. // characters of the string are examined exactly once. If the replacement
  81. // results in the creation of new occurrances of the 'from' substring,
  82. // these are not reconsidered.
  83. //
  84. // from - The substring to be replaced. If 'from' is the empty string,
  85. // then no change is made.
  86. //
  87. // to - The string to replace 'from'. If 'to' is the empty string, then
  88. // all occurrances of 'from' are removed from the string.
  89. //lint -e(1511) we are properly overloading base::replace
  90. String&
  91. replace(const String& from, const String& to);
  92. enum StripType
  93. {
  94. LEADING = 0x01,
  95. TRAILING = 0x02,
  96. BOTH = LEADING | TRAILING
  97. };
  98. // Removes all consecutive occurrances of a given character from one or
  99. // more ends of the string. Returns *this.
  100. String&
  101. strip(
  102. StripType type = TRAILING,
  103. wchar_t charToStrip = L' ');
  104. // Converts all lower case characters of the string to upper case. Returns
  105. // *this.
  106. String&
  107. to_upper();
  108. // Converts all upper case characters of the string to lower case. Returns
  109. // *this.
  110. String&
  111. to_lower();
  112. // Copy the string into an OLESTR that has been allocated with
  113. // CoTaskMemAlloc, which the caller is responsible for deleting with
  114. // CoTaskMemFree. Returns S_OK on success, E_OUTOFMEMORY if CoTaskMemAlloc
  115. // fails.
  116. //
  117. // oleString - where to place the allocated copy.
  118. HRESULT
  119. as_OLESTR(LPOLESTR& oleString) const;
  120. enum ConvertResult
  121. {
  122. CONVERT_SUCCESSFUL,
  123. CONVERT_FAILED,
  124. CONVERT_OVERFLOW,
  125. CONVERT_UNDERFLOW,
  126. CONVERT_OUT_OF_MEMORY,
  127. CONVERT_BAD_INPUT,
  128. CONVERT_BAD_RADIX
  129. };
  130. // Converts the string from Unicode to the ANSI character set, for as many
  131. // characters as this can be done. See the restrictions for
  132. // WideCharToMultiByte.
  133. //
  134. // ansi - the string (i.e. basic_string<char>) in which the result is
  135. // placed. If the conversion fails, this is set to the empty string.
  136. ConvertResult
  137. convert(AnsiString& ansi) const;
  138. // For all numeric converions, the string is expected in the following
  139. // form:
  140. //
  141. // [whitespace] [{+ | �}] [0 [{ x | X }]] [digits]
  142. //
  143. // whitespace may consist of space and tab characters, which are ignored;
  144. //
  145. // digits are one or more decimal digits. The first character that does not
  146. // fit this form stops the scan.
  147. //
  148. // The default radix for the conversion is 10 (decimal). If radix is 0,
  149. // then the the initial characters of the string are used to determine the
  150. // radix for which the digits are to be interpreted. If the first character
  151. // is 0 and the second character is not 'x' or 'X', the string is
  152. // interpreted as an octal integer; otherwise, it is interpreted as a
  153. // decimal number. If the first character is '0' and the second character
  154. // is 'x' or 'X', the string is interpreted as a hexadecimal integer. If
  155. // the first character is '1' through '9', the string is interpreted as a
  156. // decimal integer. The letters 'a' through 'z' (or 'A' through 'Z') are
  157. // assigned the values 10 through 35; only letters whose assigned values
  158. // are less than the radix are permitted. The radix must be within the
  159. // range from 2 to 36, or the conversion will fail with an error
  160. // CONVERT_BAD_RADIX, and the result parameter is set to 0.
  161. //
  162. // If any additional, unrecognized characters appear in the string, the
  163. // conversion will fail with an error CONVERT_BAD_INPUT, and the result
  164. // parameter is set to 0.
  165. //
  166. // If the conversion would produce a result too large or too small for the
  167. // target type, then the conversion fails with error CONVERT_OVERFLOW or
  168. // CONVERT_UNDERFLOW, and the result parameter is set to 0.
  169. //
  170. // Conversions for unsigned types allow a plus (+) or minus (-) sign
  171. // prefix; a leading minus sign indicates that the result value is to be
  172. // negated.
  173. ConvertResult
  174. convert(short& s, int radix = 10) const;
  175. ConvertResult
  176. convert(unsigned short& us, int radix = 10) const;
  177. ConvertResult
  178. convert(int& i, int radix = 10) const;
  179. ConvertResult
  180. convert(long& l, int radix = 10) const;
  181. ConvertResult
  182. convert(unsigned& ui, int radix = 10) const;
  183. ConvertResult
  184. convert(unsigned long& ul, int radix = 10) const;
  185. ConvertResult
  186. convert(double& d) const;
  187. ConvertResult
  188. convert(LARGE_INTEGER& li) const;
  189. // Separates the tokens in the string and pushes them in left-to-right
  190. // order into the supplied container as a individual String instances. A
  191. // token is a sequence of characters separated by one or characters in the
  192. // set of delimiters. Similar to the strtok function. Returns the
  193. // number of tokens placed in the container.
  194. //
  195. // usage:
  196. // String s(L"a list of tokens");
  197. // StringList tokens;
  198. // size_t token_count = s.tokenize(back_inserter(tokens));
  199. // ASSERT(token_count == tokens.size())
  200. template <class BackInsertableContainer>
  201. size_t
  202. tokenize(
  203. std::back_insert_iterator<BackInsertableContainer>& bii,
  204. const String& delimiters = String(L" \t") ) const
  205. {
  206. size_t tokenCount = 0;
  207. size_type p1 = 0;
  208. while (1)
  209. {
  210. p1 = find_first_not_of(delimiters, p1);
  211. if (p1 == npos)
  212. {
  213. // no more tokens
  214. break;
  215. }
  216. size_type p2 = find_first_of(delimiters, p1 + 1);
  217. if (p2 == npos)
  218. {
  219. // this is the last token
  220. *bii++ = substr(p1);
  221. ++tokenCount;
  222. break;
  223. }
  224. // the region [p1..(p2 - 1)] is a token
  225. *bii++ = substr(p1, p2 - p1);
  226. ++tokenCount;
  227. p1 = p2 + 1;
  228. }
  229. return tokenCount;
  230. }
  231. //
  232. // static functions
  233. //
  234. // Returns the string resource as a new instance.
  235. //
  236. // resID - resource ID of the string resource to load.
  237. static
  238. String
  239. load(unsigned resId, HINSTANCE hInstance = 0);
  240. inline
  241. static
  242. String
  243. load(int resId, HINSTANCE hInstance = 0)
  244. {
  245. return String::load(static_cast<unsigned>(resId), hInstance);
  246. }
  247. // FormatMessage-style formatted output.
  248. #if defined(ALPHA) || defined(IA64)
  249. //lint -e(1916) it's ok to use elipsis here
  250. static
  251. String __cdecl
  252. String::format(
  253. const String& fmt,
  254. ...);
  255. #else
  256. // the x86 compiler won't allow the first parameter to be a reference
  257. // type. This is a compiler bug.
  258. //lint -e(1916) it's ok to use elipsis here
  259. static
  260. String __cdecl
  261. String::format(
  262. const String fmt,
  263. ...);
  264. #endif
  265. static
  266. String __cdecl
  267. format(const wchar_t* qqfmt, ...);
  268. //lint -e(1916) it's ok to use elipsis here
  269. static
  270. String __cdecl
  271. format(unsigned formatResID, ...);
  272. static
  273. String __cdecl
  274. format(int formatResID, ...);
  275. //
  276. // STL support
  277. //
  278. // Function object class for performing case-insensive comparisons of
  279. // Strings. Can be used with any STL template involving binary_function.
  280. class EqualIgnoreCase
  281. :
  282. public std::binary_function<String, String, bool>
  283. {
  284. public:
  285. // Returns true if f and s are equal, ignoring case in the comparison
  286. inline
  287. bool
  288. operator()(
  289. const first_argument_type& f,
  290. const second_argument_type& s) const
  291. {
  292. return (f.icompare(s) == 0);
  293. }
  294. };
  295. class LessIgnoreCase
  296. :
  297. public std::binary_function<String, String, bool>
  298. {
  299. public:
  300. // Returns true if f is less than s, ignoring case in the comparison
  301. inline
  302. bool
  303. operator()(
  304. const first_argument_type& f,
  305. const second_argument_type& s) const
  306. {
  307. return (f.icompare(s) < 0);
  308. }
  309. };
  310. private:
  311. // Causes this to control a distinct copy of the string, without any shared
  312. // references.
  313. void
  314. _copy();
  315. void
  316. assignFromAnsi(PCSTR lpsz, size_t len);
  317. };