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.

404 lines
12 KiB

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