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.

460 lines
12 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: comstl/string/BSTR_functions.h (originally MOBStrFn.h, ::SynesisCom)
  3. *
  4. * Purpose: Contains classes and functions for dealing with BSTR strings.
  5. *
  6. * Created: 24th June 2002
  7. * Updated: 4th March 2010
  8. *
  9. * Home: http://stlsoft.org/
  10. *
  11. * Copyright (c) 2002-2010, Matthew Wilson and Synesis Software
  12. * All rights reserved.
  13. *
  14. * Redistribution and use in source and binary forms, with or without
  15. * modification, are permitted provided that the following conditions are met:
  16. *
  17. * - Redistributions of source code must retain the above copyright notice, this
  18. * list of conditions and the following disclaimer.
  19. * - Redistributions in binary form must reproduce the above copyright notice,
  20. * this list of conditions and the following disclaimer in the documentation
  21. * and/or other materials provided with the distribution.
  22. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  23. * any contributors may be used to endorse or promote products derived from
  24. * this software without specific prior written permission.
  25. *
  26. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  27. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  30. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  31. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  32. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  33. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  34. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  35. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  36. * POSSIBILITY OF SUCH DAMAGE.
  37. *
  38. * ////////////////////////////////////////////////////////////////////// */
  39. /** \file comstl/string/BSTR_functions.h
  40. *
  41. * \brief [C, C++] Functions for manipulating BSTR strings
  42. * (\ref group__library__string "String" Library).
  43. */
  44. #ifndef COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS
  45. #define COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS
  46. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  47. # define COMSTL_VER_COMSTL_STRING_H_BSTR_FUNCTIONS_MAJOR 4
  48. # define COMSTL_VER_COMSTL_STRING_H_BSTR_FUNCTIONS_MINOR 2
  49. # define COMSTL_VER_COMSTL_STRING_H_BSTR_FUNCTIONS_REVISION 7
  50. # define COMSTL_VER_COMSTL_STRING_H_BSTR_FUNCTIONS_EDIT 84
  51. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  52. /* /////////////////////////////////////////////////////////////////////////
  53. * Includes
  54. */
  55. #ifndef COMSTL_INCL_COMSTL_H_COMSTL
  56. # include <comstl/comstl.h>
  57. #endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
  58. #ifndef STLSOFT_INCL_H_STRING
  59. # define STLSOFT_INCL_H_STRING
  60. # include <string.h>
  61. #endif /* !STLSOFT_INCL_H_STRING */
  62. #ifndef STLSOFT_INCL_H_WCHAR
  63. # define STLSOFT_INCL_H_WCHAR
  64. # include <wchar.h>
  65. #endif /* !STLSOFT_INCL_H_WCHAR */
  66. /* /////////////////////////////////////////////////////////////////////////
  67. * Namespace
  68. */
  69. #if !defined(_COMSTL_NO_NAMESPACE) && \
  70. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  71. # if defined(_STLSOFT_NO_NAMESPACE)
  72. /* There is no stlsoft namespace, so must define ::comstl */
  73. namespace comstl
  74. {
  75. # else
  76. /* Define stlsoft::comstl_project */
  77. namespace stlsoft
  78. {
  79. namespace comstl_project
  80. {
  81. # endif /* _STLSOFT_NO_NAMESPACE */
  82. #endif /* !_COMSTL_NO_NAMESPACE */
  83. /* /////////////////////////////////////////////////////////////////////////
  84. * C functions
  85. */
  86. /** \brief [C only] Creates a BSTR from a Unicode string
  87. *
  88. * \ingroup group__library__string
  89. *
  90. * \param s The string from which to create the BSTR
  91. *
  92. * \result The created BSTR
  93. */
  94. STLSOFT_INLINE BSTR comstl__bstr_create_w(cs_char_w_t const* s)
  95. {
  96. return STLSOFT_NS_GLOBAL(SysAllocString)(s);
  97. }
  98. /** \brief [C only] Creates a BSTR from a (part of a) Unicode string
  99. *
  100. * \ingroup group__library__string
  101. *
  102. * \param s The string from which to create the BSTR
  103. * \param len The number of characters of \c s to copy into the result
  104. *
  105. * \result The created BSTR
  106. */
  107. STLSOFT_INLINE BSTR comstl__bstr_create_len_w(cs_char_w_t const* s, cs_size_t len)
  108. {
  109. COMSTL_MESSAGE_ASSERT("Cannot pass size_t(-1) as length!", 0 != len + 1);
  110. COMSTL_ASSERT(NULL == s || !STLSOFT_NS_GLOBAL(IsBadStringPtrW(s, len)));
  111. return STLSOFT_NS_GLOBAL(SysAllocStringLen)(s, stlsoft_static_cast(UINT, len));
  112. }
  113. /** \brief [C only] Creates a BSTR from an ANSI string
  114. *
  115. * \ingroup group__library__string
  116. *
  117. * \param s The string from which to create the BSTR
  118. *
  119. * \result The created BSTR
  120. */
  121. STLSOFT_INLINE BSTR comstl__bstr_create_a(cs_char_a_t const* s)
  122. {
  123. BSTR bstr = NULL;
  124. if(s != NULL)
  125. {
  126. const cs_size_t len = STLSOFT_NS_GLOBAL(strlen)(s);
  127. cs_char_w_t *pwsz = stlsoft_static_cast(cs_char_w_t*, STLSOFT_NS_GLOBAL(CoTaskMemAlloc)((1 + len) * sizeof(cs_char_w_t)));
  128. if(NULL != pwsz)
  129. {
  130. int n = STLSOFT_NS_GLOBAL(MultiByteToWideChar)(0, 0, s, -1, pwsz, stlsoft_static_cast(int, 1 + len));
  131. if(0 != n)
  132. {
  133. if(stlsoft_static_cast(cs_size_t, n) < len)
  134. {
  135. pwsz[n] = L'\0';
  136. }
  137. bstr = comstl__bstr_create_w(pwsz);
  138. }
  139. STLSOFT_NS_GLOBAL(CoTaskMemFree)(pwsz);
  140. }
  141. }
  142. return bstr;
  143. }
  144. /** \brief [C only] Creates a BSTR from an ANSI string
  145. *
  146. * \ingroup group__library__string
  147. *
  148. * \param s The string from which to create the BSTR
  149. * \param len The number of characters of \c s to copy into the result
  150. *
  151. * \result The created BSTR
  152. */
  153. STLSOFT_INLINE BSTR comstl__bstr_create_len_a(cs_char_a_t const* s, cs_size_t len)
  154. {
  155. BSTR bstr = NULL;
  156. COMSTL_MESSAGE_ASSERT("Cannot pass size_t(-1) as length!", 0 != len + 1);
  157. if(s != NULL)
  158. {
  159. cs_char_w_t* pwsz = stlsoft_static_cast(cs_char_w_t*, STLSOFT_NS_GLOBAL(CoTaskMemAlloc)((1 + len) * sizeof(cs_char_w_t)));
  160. if(NULL != pwsz)
  161. {
  162. int n = STLSOFT_NS_GLOBAL(MultiByteToWideChar)(0, 0, s, stlsoft_static_cast(int, len), pwsz, stlsoft_static_cast(int, 1 + len));
  163. #ifdef _DEBUG
  164. if(0 == n)
  165. {
  166. STLSOFT_NS_GLOBAL(GetLastError)();
  167. }
  168. #endif /* _DEBUG */
  169. if(0 != n)
  170. {
  171. bstr = comstl__bstr_create_len_w(pwsz, len);
  172. }
  173. STLSOFT_NS_GLOBAL(CoTaskMemFree)(pwsz);
  174. }
  175. }
  176. return bstr;
  177. }
  178. /** \brief [C only] Destroys a BSTR
  179. *
  180. * \ingroup group__library__string
  181. *
  182. * \param bstr The BSTR to destroy
  183. */
  184. STLSOFT_INLINE void comstl__bstr_destroy(BSTR bstr)
  185. {
  186. STLSOFT_NS_GLOBAL(SysFreeString)(bstr);
  187. }
  188. /** \brief [C only] Duplicates a BSTR
  189. *
  190. * \ingroup group__library__string
  191. *
  192. * \param bstr The BSTR to duplicate
  193. * \return The copied BSTR
  194. */
  195. STLSOFT_INLINE BSTR comstl__bstr_dup(BSTR bstr)
  196. {
  197. return comstl__bstr_create_w(bstr);
  198. }
  199. /** \brief [C only] Compares two BSTR strings
  200. *
  201. * \ingroup group__library__string
  202. *
  203. * \param s1 The first BSTR to compare. May be NULL
  204. * \param s2 The second BSTR to compare. May be NULL
  205. *
  206. * \return An integer value representing the relationship between the strings
  207. * \retval <0 s1 is lexicographically less than s2
  208. * \retval 0 s1 is lexicographically equal than s2
  209. * \retval >0 s1 is lexicographically greater than s2
  210. */
  211. STLSOFT_INLINE int comstl__bstr_compare(BSTR s1, BSTR s2)
  212. {
  213. if(NULL == s1)
  214. {
  215. if(NULL == s2)
  216. {
  217. return 0; /* Two NULLs are equal */
  218. }
  219. else
  220. {
  221. return -1;
  222. }
  223. }
  224. else
  225. {
  226. if(NULL == s2)
  227. {
  228. return +1;
  229. }
  230. else
  231. {
  232. return STLSOFT_NS_GLOBAL(wcscmp)(s1, s2);
  233. }
  234. }
  235. }
  236. /* /////////////////////////////////////////////////////////////////////////
  237. * Namespace
  238. */
  239. #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
  240. namespace comstl
  241. {
  242. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  243. /* /////////////////////////////////////////////////////////////////////////
  244. * C++ functions
  245. */
  246. #ifdef __cplusplus
  247. /** \brief Creates a BSTR from a Unicode string
  248. *
  249. * \ingroup group__library__string
  250. *
  251. * \param s The string from which to create the BSTR
  252. *
  253. * \result The created BSTR
  254. */
  255. inline BSTR bstr_create_w(cs_char_w_t const* s)
  256. {
  257. return comstl__bstr_create_w(s);
  258. }
  259. /** \brief Creates a BSTR from a Unicode string
  260. *
  261. * \ingroup group__library__string
  262. *
  263. * \param s The string from which to create the BSTR
  264. * \param len The number of characters of \c s to copy into the result
  265. *
  266. * \result The created BSTR
  267. */
  268. inline BSTR bstr_create_w(cs_char_w_t const* s, cs_size_t len)
  269. {
  270. return comstl__bstr_create_len_w(s, len);
  271. }
  272. /** \brief Creates a BSTR from an ANSI string
  273. *
  274. * \ingroup group__library__string
  275. *
  276. * \param s The string from which to create the BSTR
  277. *
  278. * \result The created BSTR
  279. */
  280. inline BSTR bstr_create_a(cs_char_a_t const* s)
  281. {
  282. return comstl__bstr_create_a(s);
  283. }
  284. /** \brief Creates a BSTR from an ANSI string
  285. *
  286. * \ingroup group__library__string
  287. *
  288. * \param s The string from which to create the BSTR
  289. * \param len The number of characters of \c s to copy into the result
  290. *
  291. * \result The created BSTR
  292. */
  293. inline BSTR bstr_create_a(cs_char_a_t const* s, cs_size_t len)
  294. {
  295. return comstl__bstr_create_len_a(s, len);
  296. }
  297. /** \brief Creates a BSTR from an ANSI string
  298. *
  299. * \ingroup group__library__string
  300. *
  301. * \param s The string from which to create the BSTR
  302. *
  303. * \result The created BSTR
  304. */
  305. inline BSTR bstr_create(cs_char_a_t const* s)
  306. {
  307. return bstr_create_a(s);
  308. }
  309. /** \brief Creates a BSTR from an ANSI string
  310. *
  311. * \ingroup group__library__string
  312. *
  313. * \param s The string from which to create the BSTR
  314. * \param len The number of characters of \c s to copy into the result
  315. *
  316. * \result The created BSTR
  317. */
  318. inline BSTR bstr_create(cs_char_a_t const* s, cs_size_t len)
  319. {
  320. return bstr_create_a(s, len);
  321. }
  322. /** \brief Creates a BSTR from a Unicode string
  323. *
  324. * \ingroup group__library__string
  325. *
  326. * \param s The string from which to create the BSTR
  327. *
  328. * \result The created BSTR
  329. */
  330. inline BSTR bstr_create(cs_char_w_t const* s)
  331. {
  332. return bstr_create_w(s);
  333. }
  334. /** \brief Creates a BSTR from a Unicode string
  335. *
  336. * \ingroup group__library__string
  337. *
  338. * \param s The string from which to create the BSTR
  339. * \param len The number of characters of \c s to copy into the result
  340. *
  341. * \result The created BSTR
  342. */
  343. inline BSTR bstr_create(cs_char_w_t const* s, cs_size_t len)
  344. {
  345. return bstr_create_w(s, len);
  346. }
  347. /** \brief Destroys a BSTR
  348. *
  349. * \ingroup group__library__string
  350. *
  351. * \param bstr The BSTR to destroy
  352. */
  353. inline void bstr_destroy(BSTR bstr)
  354. {
  355. comstl__bstr_destroy(bstr);
  356. }
  357. /** \brief Duplicates a BSTR
  358. *
  359. * \ingroup group__library__string
  360. *
  361. * \param bstr The BSTR to duplicate
  362. * \return The copied BSTR
  363. */
  364. inline BSTR bstr_dup(BSTR bstr)
  365. {
  366. return comstl__bstr_dup(bstr);
  367. }
  368. /** \brief Compares two BSTR strings
  369. *
  370. * \ingroup group__library__string
  371. *
  372. * \param s1 The first BSTR to compare. May be NULL
  373. * \param s2 The second BSTR to compare. May be NULL
  374. *
  375. * \return An integer value representing the relationship between the strings
  376. * \retval <0 s1 is lexicographically less than s2
  377. * \retval 0 s1 is lexicographically equal than s2
  378. * \retval >0 s1 is lexicographically greater than s2
  379. */
  380. inline int bstr_compare(BSTR s1, BSTR s2)
  381. {
  382. return comstl__bstr_compare(s1, s2);
  383. }
  384. #endif /* __cplusplus */
  385. /* /////////////////////////////////////////////////////////////////////////
  386. * Unit-testing
  387. */
  388. #ifdef STLSOFT_UNITTEST
  389. # include "./unittest/BSTR_functions_unittest_.h"
  390. #endif /* STLSOFT_UNITTEST */
  391. /* ////////////////////////////////////////////////////////////////////// */
  392. #ifndef _COMSTL_NO_NAMESPACE
  393. # if defined(_STLSOFT_NO_NAMESPACE) || \
  394. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  395. } /* namespace comstl */
  396. # else
  397. } /* namespace comstl_project */
  398. } /* namespace stlsoft */
  399. # endif /* _STLSOFT_NO_NAMESPACE */
  400. #endif /* !_COMSTL_NO_NAMESPACE */
  401. /* ////////////////////////////////////////////////////////////////////// */
  402. #endif /* !COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS */
  403. /* ///////////////////////////// end of file //////////////////////////// */