Leaked source code of windows server 2003
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.

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