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.

384 lines
12 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: pantheios/inserters/blob.hpp
  3. *
  4. * Purpose: String inserter for binary regions.
  5. *
  6. * Created: 21st June 2005
  7. * Updated: 22nd March 2010
  8. *
  9. * Home: http://www.pantheios.org/
  10. *
  11. * Copyright (c) 2005-2010, Matthew Wilson and Synesis Software
  12. * Copyright (c) 1999-2005, Synesis Software and Matthew Wilson
  13. * All rights reserved.
  14. *
  15. * Redistribution and use in source and binary forms, with or without
  16. * modification, are permitted provided that the following conditions are
  17. * met:
  18. *
  19. * - Redistributions of source code must retain the above copyright notice,
  20. * this list of conditions and the following disclaimer.
  21. * - Redistributions in binary form must reproduce the above copyright
  22. * notice, this list of conditions and the following disclaimer in the
  23. * documentation and/or other materials provided with the distribution.
  24. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the
  25. * names of any contributors may be used to endorse or promote products
  26. * derived from this software without specific prior written permission.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  29. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  30. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  31. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  32. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  33. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  34. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  35. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  36. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  37. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39. *
  40. * ////////////////////////////////////////////////////////////////////// */
  41. /** \file pantheios/inserters/blob.hpp
  42. *
  43. * [C++ only] Definition of the pantheios::blob inserter for binary
  44. * regions.
  45. */
  46. #ifndef PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_BLOB
  47. #define PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_BLOB
  48. /* /////////////////////////////////////////////////////////////////////////
  49. * Version information
  50. */
  51. #ifndef PANTHEIOS_DOCUMENTATION_SKIP_SECTION
  52. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_BLOB_MAJOR 2
  53. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_BLOB_MINOR 4
  54. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_BLOB_REVISION 4
  55. # define PANTHEIOS_VER_PANTHEIOS_INSERTERS_HPP_BLOB_EDIT 27
  56. #endif /* !PANTHEIOS_DOCUMENTATION_SKIP_SECTION */
  57. /* /////////////////////////////////////////////////////////////////////////
  58. * Includes
  59. */
  60. #ifndef PANTHEIOS_INCL_PANTHEIOS_H_PANTHEIOS
  61. # include <pantheios/pantheios.h>
  62. #endif /* !PANTHEIOS_INCL_PANTHEIOS_H_PANTHEIOS */
  63. #ifndef PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_FMT
  64. # include <pantheios/inserters/fmt.hpp>
  65. #endif /* !PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_FMT */
  66. #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_STRING_H_FWD
  67. # include <stlsoft/shims/access/string/fwd.h>
  68. #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_STRING_H_FWD */
  69. #ifndef PANTHEIOS_INCL_H_STDIO
  70. # define PANTHEIOS_INCL_H_STDIO
  71. # include <stdio.h>
  72. #endif /* !PANTHEIOS_INCL_H_STDIO */
  73. /* /////////////////////////////////////////////////////////////////////////
  74. * Namespace
  75. */
  76. #if !defined(PANTHEIOS_NO_NAMESPACE)
  77. namespace pantheios
  78. {
  79. #endif /* !PANTHEIOS_NO_NAMESPACE */
  80. /* /////////////////////////////////////////////////////////////////////////
  81. * Inserter classes
  82. */
  83. /** Class for inserting binary regions types into Pantheios diagnostic
  84. * logging statements.
  85. *
  86. * \ingroup group__application_layer_interface__inserters
  87. *
  88. * This class formats a binary region into a string, thereby enabling it to
  89. * be inserted into a logging statement. Consider the following statement:
  90. * \code
  91. int ar[2] = { 0x00112233, 0x44556677 };
  92. char s[] = "abc";
  93. std::string str("def");
  94. pantheios::log(pantheios::notice, "s=", s, ", blob=", pantheios::blob(ar, sizeof(ar)), ", str=", str);
  95. * \endcode
  96. *
  97. * This will produce the output:
  98. \htmlonly
  99. <pre>
  100. <b>s=abc, blob=0011223344556677, str=def</b>
  101. </pre>
  102. \endhtmlonly
  103. *
  104. * The bytes can be grouped and these groups separated. Consider the
  105. * following statement:
  106. * \code
  107. int ar[2] = { 0x00112233, 0x44556677 };
  108. char s[] = "abc";
  109. std::string str("def");
  110. pantheios::log(pantheios::notice, "s=", s, ", blob=", pantheios::blob(ar, sizeof(ar), 2, "-"), ", str=", str);
  111. * \endcode
  112. *
  113. * This will produce the output:
  114. * \htmlonly
  115. <pre>
  116. <b>s=abc, blob=2233-0011-6677-4455, str=def</b>
  117. </pre>
  118. \endhtmlonly
  119. *
  120. * The output can be split into lines. Consider the following statement:
  121. * \code
  122. int ar[2] = { 0x00112233, 0x44556677 };
  123. char s[] = "abc";
  124. std::string str("def");
  125. pantheios::log(pantheios::notice, "s=", s, ", blob=", pantheios::blob(ar, sizeof(ar), 2, "-", 3, "\n\t"), ", str=", str);
  126. * \endcode
  127. *
  128. * This will produce the output:
  129. \htmlonly
  130. <pre>
  131. <b>s=abc, blob=2233-0011-6677
  132. 4455, str=def</b>
  133. </pre>
  134. \endhtmlonly
  135. */
  136. class blob
  137. {
  138. /// \name Member Types
  139. /// @{
  140. public:
  141. typedef blob class_type;
  142. /// @}
  143. /// \name Construction
  144. /// @{
  145. public:
  146. /// Constructs a \link pantheios::blob blob\endlink inserter
  147. /// that will display as an unbroken sequence of hexadecimal digits.
  148. ///
  149. /// \param pv Pointer to the first byte in the sequence to be displayed.
  150. /// \param cb Number of bytes in the sequence.
  151. blob( void const* pv
  152. , size_t cb);
  153. /// Constructs a \link pantheios::blob blob\endlink inserter
  154. /// that will break the sequence of hexadecimal digits into groups
  155. /// of the specified number of bytes, separating groups with the
  156. /// specified separator.
  157. ///
  158. /// \param pv Pointer to the first byte in the sequence to be displayed.
  159. /// \param cb Number of bytes in the sequence.
  160. /// \param bytesPerGroup Number of bytes per group. Must be a power of 2.
  161. /// \param groupSeparator The string used to separate the byte groups.
  162. blob( void const* pv
  163. , size_t cb
  164. , unsigned bytesPerGroup
  165. , pan_char_t const* groupSeparator);
  166. /// Constructs a \link pantheios::blob blob\endlink inserter
  167. /// that will break the sequence of hexadecimal digits into groups
  168. /// of the specified number of bytes, separating groups with the
  169. /// specified separator, and break into lines of the specified
  170. /// number of groups, using the given line separator.
  171. ///
  172. /// \param pv Pointer to the first byte in the sequence to be displayed.
  173. /// \param cb Number of bytes in the sequence.
  174. /// \param bytesPerGroup Number of bytes per group. Must be a power of 2.
  175. /// \param groupSeparator The string used to separate the byte groups.
  176. /// \param groupsPerLine Number of groups per line.
  177. /// \param lineSeparator The string used to separate the lines.
  178. blob( void const* pv
  179. , size_t cb
  180. , unsigned bytesPerGroup
  181. , pan_char_t const* groupSeparator
  182. , int groupsPerLine
  183. , pan_char_t const* lineSeparator = PANTHEIOS_LITERAL_STRING("\n")
  184. );
  185. /// Releases any storage associated with the instance.
  186. ~blob() stlsoft_throw_0();
  187. /// @}
  188. /// \name Accessors
  189. /// @{
  190. public:
  191. /// A possibly non-nul-terminated non-null pointer to the c-style string representation of the integer
  192. pan_char_t const* data() const;
  193. /// A nul-terminated non-null pointer to the c-style string representation of the integer
  194. pan_char_t const* c_str() const;
  195. /// The length of the c-style string representation of the integer
  196. size_t length() const;
  197. /// @}
  198. /// \name Implementation
  199. /// @{
  200. private:
  201. void construct_() const;
  202. void construct_();
  203. /// @}
  204. /// \name Member Variables
  205. /// @{
  206. private:
  207. pan_char_t const* m_value;
  208. size_t m_len;
  209. void const* const m_pv;
  210. size_t m_cb;
  211. unsigned m_byteGrouping;
  212. pan_char_t const* m_groupSeparator;
  213. int m_groupsPerLine;
  214. pan_char_t const* m_lineSeparator;
  215. /// @}
  216. /// \name Not to be implemented
  217. /// @{
  218. private:
  219. #if !defined(STLSOFT_COMPILER_IS_GCC)
  220. blob(class_type const&);
  221. #endif /* compiler */
  222. class_type& operator =(class_type const&);
  223. /// @}
  224. };
  225. /* /////////////////////////////////////////////////////////////////////////
  226. * String Access Shims
  227. */
  228. #ifndef PANTHEIOS_DOCUMENTATION_SKIP_SECTION
  229. # if !defined(PANTHEIOS_NO_NAMESPACE)
  230. namespace shims
  231. {
  232. # endif /* !PANTHEIOS_NO_NAMESPACE */
  233. /** \overload c_str_data_a(blob const&) */
  234. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  235. inline wchar_t const* c_str_data_w(blob const& b)
  236. {
  237. return b.data();
  238. }
  239. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  240. inline char const* c_str_data_a(blob const& b)
  241. {
  242. return b.data();
  243. }
  244. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  245. /** \overload c_str_data(blob const&) */
  246. inline pan_char_t const* c_str_data(blob const& b)
  247. {
  248. return b.data();
  249. }
  250. /** \overload c_str_len_a(blob const&) */
  251. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  252. inline size_t c_str_len_w(blob const& b)
  253. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  254. inline size_t c_str_len_a(blob const& b)
  255. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  256. {
  257. return b.length();
  258. }
  259. /** \overload c_str_len(blob const&) */
  260. inline size_t c_str_len(blob const& b)
  261. {
  262. return b.length();
  263. }
  264. /** \overload c_str_ptr_a(blob const&) */
  265. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  266. inline wchar_t const* c_str_ptr_w(blob const& b)
  267. {
  268. return b.c_str();
  269. }
  270. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  271. inline char const* c_str_ptr_a(blob const& b)
  272. {
  273. return b.c_str();
  274. }
  275. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  276. /** \overload c_str_ptr(blob const&) */
  277. inline pan_char_t const* c_str_ptr(blob const& b)
  278. {
  279. return b.c_str();
  280. }
  281. # if !defined(PANTHEIOS_NO_NAMESPACE)
  282. } /* namespace shims */
  283. # if defined(STLSOFT_COMPILER_IS_GCC)
  284. /* GCC does not seem to correctly handle the phases of
  285. * processing of C++ templates, so we need to 'use' the
  286. * shims into the same namespace as the inserter class
  287. * in order that ADL can suffice instead.
  288. */
  289. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  290. using ::pantheios::shims::c_str_data_w;
  291. using ::pantheios::shims::c_str_len_w;
  292. using ::pantheios::shims::c_str_ptr_w;
  293. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  294. using ::pantheios::shims::c_str_data_a;
  295. using ::pantheios::shims::c_str_len_a;
  296. using ::pantheios::shims::c_str_ptr_a;
  297. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  298. using ::pantheios::shims::c_str_data;
  299. using ::pantheios::shims::c_str_len;
  300. using ::pantheios::shims::c_str_ptr;
  301. # endif /* compiler */
  302. # endif /* !PANTHEIOS_NO_NAMESPACE */
  303. #endif /* !PANTHEIOS_DOCUMENTATION_SKIP_SECTION */
  304. /* /////////////////////////////////////////////////////////////////////////
  305. * Namespace
  306. */
  307. #if !defined(PANTHEIOS_NO_NAMESPACE)
  308. } /* namespace pantheios */
  309. namespace stlsoft
  310. {
  311. // 'Export' the string access shims into the STLSoft namespace
  312. //
  313. // c_str_ptr(_a) is not necessary for version 1.0 of Pantheios, but it's
  314. // defined and exported in order to allow for the case where someone
  315. // may find a legitimate use for the conversion classes additional to
  316. // the type-tunneling of the Pantheios API.
  317. # ifdef PANTHEIOS_USE_WIDE_STRINGS
  318. using ::pantheios::shims::c_str_data_w;
  319. using ::pantheios::shims::c_str_len_w;
  320. using ::pantheios::shims::c_str_ptr_w;
  321. # else /* ? PANTHEIOS_USE_WIDE_STRINGS */
  322. using ::pantheios::shims::c_str_data_a;
  323. using ::pantheios::shims::c_str_len_a;
  324. using ::pantheios::shims::c_str_ptr_a;
  325. # endif /* PANTHEIOS_USE_WIDE_STRINGS */
  326. using ::pantheios::shims::c_str_data;
  327. using ::pantheios::shims::c_str_len;
  328. using ::pantheios::shims::c_str_ptr;
  329. }
  330. #endif /* !PANTHEIOS_NO_NAMESPACE */
  331. /* /////////////////////////////////////////////////////////////////////////
  332. * Inclusion
  333. */
  334. #ifdef STLSOFT_PPF_pragma_once_SUPPORT
  335. # pragma once
  336. #endif /* STLSOFT_PPF_pragma_once_SUPPORT */
  337. /* ////////////////////////////////////////////////////////////////////// */
  338. #endif /* !PANTHEIOS_INCL_PANTHEIOS_INSERTERS_HPP_BLOB */
  339. /* ///////////////////////////// end of file //////////////////////////// */