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.

477 lines
14 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: comstl/shims/access/string/guid.hpp
  3. *
  4. * Purpose: Contains classes and functions for dealing with OLE/COM strings.
  5. *
  6. * Created: 24th May 2002
  7. * Updated: 12th May 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/shims/access/string/guid.hpp
  40. *
  41. * \brief [C++] Definition of the string access shims for
  42. * <code>GUID</code>
  43. * (\ref group__concept__shim__string_access "String Access Shims" Concept).
  44. */
  45. #ifndef COMSTL_INCL_COMSTL_SHIMS_ACCESS_STRING_HPP_GUID
  46. #define COMSTL_INCL_COMSTL_SHIMS_ACCESS_STRING_HPP_GUID
  47. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  48. # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_GUID_MAJOR 5
  49. # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_GUID_MINOR 1
  50. # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_GUID_REVISION 1
  51. # define COMSTL_VER_COMSTL_SHIMS_ACCESS_STRING_HPP_GUID_EDIT 114
  52. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  53. /* /////////////////////////////////////////////////////////////////////////
  54. * Includes
  55. */
  56. #ifndef COMSTL_INCL_COMSTL_H_COMSTL
  57. # include <comstl/comstl.h>
  58. #endif /* !COMSTL_INCL_COMSTL_H_COMSTL */
  59. #ifndef COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS
  60. # include <comstl/string/BSTR_functions.h>
  61. #endif /* !COMSTL_INCL_COMSTL_STRING_H_BSTR_FUNCTIONS */
  62. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
  63. # include <stlsoft/shims/access/string.hpp>
  64. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */
  65. #ifndef STLSOFT_INCL_H_WCHAR
  66. # define STLSOFT_INCL_H_WCHAR
  67. # include <wchar.h>
  68. #endif /* !STLSOFT_INCL_H_WCHAR */
  69. /* /////////////////////////////////////////////////////////////////////////
  70. * Namespace
  71. */
  72. #ifndef _COMSTL_NO_NAMESPACE
  73. # if defined(_STLSOFT_NO_NAMESPACE) || \
  74. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  75. /* There is no stlsoft namespace, so must define ::comstl */
  76. namespace comstl
  77. {
  78. # else
  79. /* Define stlsoft::comstl_project */
  80. namespace stlsoft
  81. {
  82. namespace comstl_project
  83. {
  84. # endif /* _STLSOFT_NO_NAMESPACE */
  85. #endif /* !_COMSTL_NO_NAMESPACE */
  86. /* /////////////////////////////////////////////////////////////////////////
  87. * Functions
  88. */
  89. inline cs_size_t guid2string_w(GUID const& guid, cs_char_w_t buff[1 + COMSTL_CCH_GUID])
  90. {
  91. return static_cast<cs_size_t>(StringFromGUID2(guid, buff, 1 + COMSTL_CCH_GUID));
  92. }
  93. inline cs_size_t guid2string_a(GUID const& guid, cs_char_a_t buff[1 + COMSTL_CCH_GUID])
  94. {
  95. const cs_size_t COMSTL_CCH_GUID_AND_NULL = COMSTL_CCH_GUID + 1;
  96. /* Don't ask! */
  97. #ifdef STLSOFT_COMPILER_IS_BORLAND
  98. int buff__[COMSTL_CCH_GUID_AND_NULL];
  99. cs_char_w_t *buff_ = (wchar_t *)buff__;
  100. #else /* ? compiler */
  101. cs_char_w_t buff_[COMSTL_CCH_GUID_AND_NULL];
  102. #endif /* compiler */
  103. cs_size_t cch = guid2string_w(guid, buff_);
  104. ::WideCharToMultiByte(0, 0, buff_, COMSTL_CCH_GUID_AND_NULL, buff, COMSTL_CCH_GUID_AND_NULL, 0, 0);
  105. return cch;
  106. }
  107. /* /////////////////////////////////////////////////////////////////////////
  108. * Classes
  109. */
  110. /* GUID */
  111. /** \brief This class provides an intermediary object that may be returned by the
  112. * c_str_ptr_null() function, such that the text of a given GUID
  113. * may be accessed as a null-terminated string.
  114. *
  115. * \ingroup group__concept__shim__string_access
  116. *
  117. */
  118. template <ss_typename_param_k C>
  119. class c_str_ptr_GUID_proxy
  120. {
  121. public:
  122. typedef C char_type;
  123. typedef c_str_ptr_GUID_proxy<C> class_type;
  124. // Construction
  125. public:
  126. /// Constructs an instance of the proxy from the given GUID instance
  127. ///
  128. /// \param guid The GUID instance from which the text will be retrieved
  129. ss_explicit_k c_str_ptr_GUID_proxy(GUID const& guid);
  130. /// Copy constructor
  131. c_str_ptr_GUID_proxy(class_type const& rhs)
  132. : m_(m_buffer)
  133. {
  134. for(cs_size_t i = 0; i < STLSOFT_NUM_ELEMENTS(m_buffer); ++i)
  135. {
  136. m_buffer[i] = rhs.m_buffer[i];
  137. }
  138. }
  139. // Accessors
  140. public:
  141. /// Returns a null-terminated string representing the GUID contents
  142. operator char_type const* () const
  143. {
  144. return m_buffer;
  145. }
  146. // Members
  147. private:
  148. char_type const* const m_;
  149. char_type m_buffer[1 + COMSTL_CCH_GUID];
  150. // Not to be implemented
  151. private:
  152. void operator =(class_type const& rhs);
  153. };
  154. STLSOFT_TEMPLATE_SPECIALISATION
  155. inline c_str_ptr_GUID_proxy<cs_char_a_t>::c_str_ptr_GUID_proxy(GUID const& guid)
  156. : m_(m_buffer)
  157. {
  158. #ifndef STLSOFT_COMPILER_IS_BORLAND
  159. COMSTL_STATIC_ASSERT(STLSOFT_NUM_ELEMENTS(m_buffer) > COMSTL_CCH_GUID);
  160. #endif /* compiler */
  161. guid2string_a(guid, m_buffer);
  162. }
  163. STLSOFT_TEMPLATE_SPECIALISATION
  164. inline c_str_ptr_GUID_proxy<cs_char_w_t>::c_str_ptr_GUID_proxy(GUID const& guid)
  165. : m_(m_buffer)
  166. {
  167. #ifndef STLSOFT_COMPILER_IS_BORLAND
  168. COMSTL_STATIC_ASSERT(STLSOFT_NUM_ELEMENTS(m_buffer) > COMSTL_CCH_GUID);
  169. #endif /* compiler */
  170. guid2string_w(guid, m_buffer);
  171. }
  172. /* /////////////////////////////////////////////////////////////////////////
  173. * Equivalence testing
  174. */
  175. // c_str_ptr_GUID_proxy
  176. template <ss_typename_param_k C>
  177. inline cs_bool_t operator ==(C const* lhs, c_str_ptr_GUID_proxy<C> const& rhs)
  178. {
  179. return lhs == static_cast<C const*>(rhs);
  180. }
  181. template <ss_typename_param_k C>
  182. inline cs_bool_t operator ==(c_str_ptr_GUID_proxy<C> const& lhs, C const* rhs)
  183. {
  184. return static_cast<C const*>(lhs) == rhs;
  185. }
  186. template <ss_typename_param_k C>
  187. inline cs_bool_t operator !=(C const* lhs, c_str_ptr_GUID_proxy<C> const& rhs)
  188. {
  189. return lhs != static_cast<C const*>(rhs);
  190. }
  191. template <ss_typename_param_k C>
  192. inline cs_bool_t operator !=(c_str_ptr_GUID_proxy<C> const& lhs, C const* rhs)
  193. {
  194. return static_cast<C const*>(lhs) != rhs;
  195. }
  196. /* /////////////////////////////////////////////////////////////////////////
  197. * IOStream compatibility
  198. */
  199. template< ss_typename_param_k C
  200. , ss_typename_param_k S
  201. >
  202. inline S& operator <<(S& s, c_str_ptr_GUID_proxy<C> const& shim)
  203. {
  204. s << static_cast<C const*>(shim);
  205. return s;
  206. }
  207. /* /////////////////////////////////////////////////////////////////////////
  208. * c_str_data
  209. *
  210. * This can be applied to an expression, and the return value is either a
  211. * pointer to the character string or to an empty string.
  212. */
  213. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  214. inline c_str_ptr_GUID_proxy<cs_char_a_t> c_str_data_a(GUID const& guid)
  215. {
  216. return c_str_ptr_GUID_proxy<cs_char_a_t>(guid);
  217. }
  218. inline c_str_ptr_GUID_proxy<cs_char_w_t> c_str_data_w(GUID const& guid)
  219. {
  220. return c_str_ptr_GUID_proxy<cs_char_w_t>(guid);
  221. }
  222. inline c_str_ptr_GUID_proxy<cs_char_o_t> c_str_data_o(GUID const& guid)
  223. {
  224. return c_str_ptr_GUID_proxy<cs_char_o_t>(guid);
  225. }
  226. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  227. /** \brief Returns the corresponding possibly unterminated C-string pointer of the GUID \c guid
  228. *
  229. * \ingroup group__concept__shim__string_access
  230. *
  231. */
  232. inline c_str_ptr_GUID_proxy<TCHAR> c_str_data(GUID const& guid)
  233. {
  234. #ifdef UNICODE
  235. return c_str_data_w(guid);
  236. #else /* ? UNICODE */
  237. return c_str_data_a(guid);
  238. #endif /* UNICODE */
  239. }
  240. /* /////////////////////////////////////////////////////////////////////////
  241. * c_str_len
  242. *
  243. * This can be applied to an expression, and the return value is the number of
  244. * characters in the character string in the expression.
  245. */
  246. /* GUID */
  247. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  248. inline cs_size_t c_str_len_a(GUID const& /* guid */)
  249. {
  250. return COMSTL_CCH_GUID;
  251. }
  252. inline cs_size_t c_str_len_w(GUID const& /* guid */)
  253. {
  254. return COMSTL_CCH_GUID;
  255. }
  256. inline cs_size_t c_str_len_o(GUID const& /* guid */)
  257. {
  258. return COMSTL_CCH_GUID;
  259. }
  260. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  261. /** \brief Returns the length (in characters) of the GUID \c guid, <b><i>not</i></b> including the null-terminating character
  262. *
  263. * \ingroup group__concept__shim__string_access
  264. *
  265. */
  266. inline cs_size_t c_str_len(GUID const& /* guid */)
  267. {
  268. return COMSTL_CCH_GUID;
  269. }
  270. /* /////////////////////////////////////////////////////////////////////////
  271. * c_str_ptr
  272. *
  273. * This can be applied to an expression, and the return value is either a
  274. * pointer to the character string or to an empty string.
  275. */
  276. /* GUID */
  277. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  278. inline c_str_ptr_GUID_proxy<cs_char_a_t> c_str_ptr_a(GUID const& guid)
  279. {
  280. return c_str_ptr_GUID_proxy<cs_char_a_t>(guid);
  281. }
  282. inline c_str_ptr_GUID_proxy<cs_char_w_t> c_str_ptr_w(GUID const& guid)
  283. {
  284. return c_str_ptr_GUID_proxy<cs_char_w_t>(guid);
  285. }
  286. inline c_str_ptr_GUID_proxy<cs_char_o_t> c_str_ptr_o(GUID const& guid)
  287. {
  288. return c_str_ptr_GUID_proxy<cs_char_o_t>(guid);
  289. }
  290. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  291. /** \brief Returns the corresponding C-string pointer of the GUID \c guid
  292. *
  293. * \ingroup group__concept__shim__string_access
  294. *
  295. */
  296. inline c_str_ptr_GUID_proxy<TCHAR> c_str_ptr(GUID const& guid)
  297. {
  298. #ifdef UNICODE
  299. return c_str_ptr_w(guid);
  300. #else /* ? UNICODE */
  301. return c_str_ptr_a(guid);
  302. #endif /* UNICODE */
  303. }
  304. /* /////////////////////////////////////////////////////////////////////////
  305. * c_str_ptr_null
  306. *
  307. * This can be applied to an expression, and the return value is either a
  308. * pointer to the character string or NULL.
  309. */
  310. /* GUID */
  311. #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
  312. inline c_str_ptr_GUID_proxy<cs_char_a_t> c_str_ptr_null_a(GUID const& guid)
  313. {
  314. return c_str_ptr_GUID_proxy<cs_char_a_t>(guid);
  315. }
  316. inline c_str_ptr_GUID_proxy<cs_char_w_t> c_str_ptr_null_w(GUID const& guid)
  317. {
  318. return c_str_ptr_GUID_proxy<cs_char_w_t>(guid);
  319. }
  320. inline c_str_ptr_GUID_proxy<cs_char_o_t> c_str_ptr_null_o(GUID const& guid)
  321. {
  322. return c_str_ptr_GUID_proxy<cs_char_o_t>(guid);
  323. }
  324. #endif /* !STLSOFT_DOCUMENTATION_SKIP_SECTION */
  325. /** \brief Returns the corresponding C-string pointer of the GUID \c guid
  326. *
  327. * \ingroup group__concept__shim__string_access
  328. *
  329. */
  330. inline c_str_ptr_GUID_proxy<TCHAR> c_str_ptr_null(GUID const& guid)
  331. {
  332. #ifdef UNICODE
  333. return c_str_ptr_null_w(guid);
  334. #else /* ? UNICODE */
  335. return c_str_ptr_null_a(guid);
  336. #endif /* UNICODE */
  337. }
  338. ////////////////////////////////////////////////////////////////////////////
  339. // Unit-testing
  340. #ifdef STLSOFT_UNITTEST
  341. # include "./unittest/guid_unittest_.h"
  342. #endif /* STLSOFT_UNITTEST */
  343. /* ////////////////////////////////////////////////////////////////////// */
  344. #ifndef _COMSTL_NO_NAMESPACE
  345. # if defined(_STLSOFT_NO_NAMESPACE) || \
  346. defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  347. } // namespace comstl
  348. # else
  349. } // namespace stlsoft::comstl_project
  350. } // namespace stlsoft
  351. # endif /* _STLSOFT_NO_NAMESPACE */
  352. #endif /* !_COMSTL_NO_NAMESPACE */
  353. /* /////////////////////////////////////////////////////////////////////////
  354. * Namespace
  355. *
  356. * The string access shims exist either in the stlsoft namespace, or in the
  357. * global namespace. This is required by the lookup rules.
  358. *
  359. */
  360. #ifndef _COMSTL_NO_NAMESPACE
  361. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  362. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  363. namespace stlsoft
  364. {
  365. # else /* ? _STLSOFT_NO_NAMESPACE */
  366. /* There is no stlsoft namespace, so must define in the global namespace */
  367. # endif /* !_STLSOFT_NO_NAMESPACE */
  368. using ::comstl::c_str_data_a;
  369. using ::comstl::c_str_data_w;
  370. using ::comstl::c_str_data_o;
  371. using ::comstl::c_str_data;
  372. using ::comstl::c_str_len_a;
  373. using ::comstl::c_str_len_w;
  374. using ::comstl::c_str_len_o;
  375. using ::comstl::c_str_len;
  376. using ::comstl::c_str_ptr_a;
  377. using ::comstl::c_str_ptr_w;
  378. using ::comstl::c_str_ptr_o;
  379. using ::comstl::c_str_ptr;
  380. using ::comstl::c_str_ptr_null_a;
  381. using ::comstl::c_str_ptr_null_w;
  382. using ::comstl::c_str_ptr_null_o;
  383. using ::comstl::c_str_ptr_null;
  384. # if !defined(_STLSOFT_NO_NAMESPACE) && \
  385. !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
  386. } // namespace stlsoft
  387. # else /* ? _STLSOFT_NO_NAMESPACE */
  388. /* There is no stlsoft namespace, so must define in the global namespace */
  389. # endif /* !_STLSOFT_NO_NAMESPACE */
  390. #endif /* !_COMSTL_NO_NAMESPACE */
  391. /* ////////////////////////////////////////////////////////////////////// */
  392. #endif /* !COMSTL_INCL_COMSTL_SHIMS_ACCESS_STRING_HPP_GUID */
  393. /* ///////////////////////////// end of file //////////////////////////// */