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.

479 lines
18 KiB

  1. /* /////////////////////////////////////////////////////////////////////////
  2. * File: b64/b64.h
  3. *
  4. * Purpose: Header file for the b64 library
  5. *
  6. * Created: 18th October 2004
  7. * Updated: 4th February 2012
  8. *
  9. * Thanks: To Adam McLaurin, for ideas regarding the b64_decode2() and
  10. * b64_encode2().
  11. *
  12. * Home: http://synesis.com.au/software/
  13. *
  14. * Copyright (c) 2004-2012, Matthew Wilson and Synesis Software
  15. * All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions are met:
  19. *
  20. * - Redistributions of source code must retain the above copyright notice, this
  21. * list of conditions and the following disclaimer.
  22. * - Redistributions in binary form must reproduce the above copyright notice,
  23. * this list of conditions and the following disclaimer in the documentation
  24. * and/or other materials provided with the distribution.
  25. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
  26. * any contributors may be used to endorse or promote products derived from
  27. * this software without specific prior written permission.
  28. *
  29. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  30. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  31. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  32. * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  33. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  34. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  35. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  36. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  37. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  38. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  39. * POSSIBILITY OF SUCH DAMAGE.
  40. *
  41. * ////////////////////////////////////////////////////////////////////// */
  42. /** \file b64/b64.h
  43. *
  44. * \brief [C/C++] Header file for the b64 library.
  45. */
  46. #ifndef B64_INCL_B64_H_B64
  47. #define B64_INCL_B64_H_B64
  48. /* /////////////////////////////////////////////////////////////////////////
  49. * Version information
  50. */
  51. #ifndef B64_DOCUMENTATION_SKIP_SECTION
  52. # define B64_VER_B64_H_B64_MAJOR 1
  53. # define B64_VER_B64_H_B64_MINOR 6
  54. # define B64_VER_B64_H_B64_REVISION 3
  55. # define B64_VER_B64_H_B64_EDIT 35
  56. #endif /* !B64_DOCUMENTATION_SKIP_SECTION */
  57. /** \def B64_VER_MAJOR
  58. * The major version number of b64
  59. */
  60. /** \def B64_VER_MINOR
  61. * The minor version number of b64
  62. */
  63. /** \def B64_VER_REVISION
  64. * The revision version number of b64
  65. */
  66. /** \def B64_VER
  67. * The current composite version number of b64
  68. */
  69. #ifndef B64_DOCUMENTATION_SKIP_SECTION
  70. # define B64_VER_1_0_1 0x01000100
  71. # define B64_VER_1_0_2 0x01000200
  72. # define B64_VER_1_0_3 0x01000300
  73. # define B64_VER_1_1_1 0x01010100
  74. # define B64_VER_1_1_2 0x01010200
  75. # define B64_VER_1_1_3 0x01010300
  76. # define B64_VER_1_2_1 0x01020100
  77. # define B64_VER_1_2_2 0x01020200
  78. # define B64_VER_1_2_3 0x01020300
  79. # define B64_VER_1_2_4 0x01020400
  80. # define B64_VER_1_2_5 0x01020500
  81. # define B64_VER_1_2_6 0x01020600
  82. # define B64_VER_1_2_7 0x01020700
  83. # define B64_VER_1_3_1 0x010301ff
  84. # define B64_VER_1_3_2 0x010302ff
  85. # define B64_VER_1_3_3 0x010303ff
  86. # define B64_VER_1_3_4 0x010304ff
  87. # define B64_VER_1_4_1_ALPHA_1 0x01040101
  88. # define B64_VER_1_4_2 0x010402ff
  89. #endif /* !B64_DOCUMENTATION_SKIP_SECTION */
  90. #define B64_VER_MAJOR 1
  91. #define B64_VER_MINOR 4
  92. #define B64_VER_REVISION 2
  93. #define B64_VER 0x010402ff
  94. /* /////////////////////////////////////////////////////////////////////////
  95. * Includes
  96. */
  97. #include <stddef.h>
  98. /* /////////////////////////////////////////////////////////////////////////
  99. * Features
  100. */
  101. /* If the Synesis preprocessor symbol SYNESIS_VARIANT_TEST is defined, then we
  102. * automatically define B64_VARIANT_TEST, which requests a test build: i.e.
  103. * debug information off, optimisations on, contract enforcements on
  104. */
  105. #if defined(SYNESIS_VARIANT_TEST)
  106. # if !defined(B64_VARIANT_TEST)
  107. # define B64_VARIANT_TEST
  108. # endif /* !B64_VARIANT_TEST */
  109. #endif /* SYNESIS_VARIANT_TEST */
  110. /* /////////////////////////////////////////////////////////////////////////
  111. * Namespace
  112. */
  113. #if !defined(B64_NO_NAMESPACE) && \
  114. !defined(__cplusplus)
  115. # define B64_NO_NAMESPACE
  116. #endif /* !B64_NO_NAMESPACE && !__cplusplus */
  117. #ifdef B64_NAMESPACE
  118. # undef B64_NAMESPACE
  119. #endif /* B64_NAMESPACE */
  120. #ifdef B64_NAMESPACE_QUALIFIER
  121. # undef B64_NAMESPACE_QUALIFIER
  122. #endif /* B64_NAMESPACE_QUALIFIER */
  123. #ifndef B64_NO_NAMESPACE
  124. # ifdef B64_CUSTOM_NAMESPACE
  125. # define B64_NAMESPACE B64_CUSTOM_NAMESPACE
  126. # else /* ? B64_CUSTOM_NAMESPACE */
  127. # define B64_NAMESPACE b64
  128. # endif /* B64_CUSTOM_NAMESPACE */
  129. # if defined(B64_CUSTOM_NAMESPACE) && \
  130. defined(B64_CUSTOM_NAMESPACE_QUALIFIER)
  131. # define B64_NAMESPACE_QUALIFIER B64_CUSTOM_NAMESPACE_QUALIFIER
  132. # else /* B64_CUSTOM_NAMESPACE && B64_CUSTOM_NAMESPACE_QUALIFIER */
  133. # define B64_NAMESPACE_QUALIFIER ::B64_NAMESPACE
  134. # endif /* B64_CUSTOM_NAMESPACE && B64_CUSTOM_NAMESPACE_QUALIFIER */
  135. /** [C/C++] The b64 namespace, within which the core library types and functions
  136. * reside in C++ compilation. In C compilation, they all reside in the global
  137. * namespace.
  138. *
  139. * \htmlonly
  140. * <hr>
  141. * \endhtmlonly
  142. */
  143. namespace B64_NAMESPACE
  144. {
  145. #endif /* !B64_NO_NAMESPACE */
  146. /* /////////////////////////////////////////////////////////////////////////
  147. * Typedefs
  148. */
  149. /** The ambient character type of the library
  150. *
  151. * \note Currently, this is always \c char, supporting only multibyte strings
  152. */
  153. typedef char b64_char_t;
  154. /** Return codes (from b64_encode2() / b64_decode2())
  155. */
  156. enum B64_RC
  157. {
  158. B64_RC_OK = 0 /*!< Operation was successful. */
  159. , B64_RC_INSUFFICIENT_BUFFER = 1 /*!< The given translation buffer was not of sufficient size. */
  160. , B64_RC_TRUNCATED_INPUT = 2 /*!< The input did not represent a fully formed stream of octet couplings. */
  161. , B64_RC_DATA_ERROR = 3 /*!< Invalid data. */
  162. #ifndef B64_DOCUMENTATION_SKIP_SECTION
  163. , B64_max_RC_value
  164. #endif /* !B64_DOCUMENTATION_SKIP_SECTION */
  165. };
  166. #ifndef __cplusplus
  167. typedef enum B64_RC B64_RC;
  168. #endif /* !__cplusplus */
  169. /** Coding behaviour modification flags (for b64_encode2() / b64_decode2())
  170. */
  171. enum B64_FLAGS
  172. {
  173. B64_F_LINE_LEN_USE_PARAM = 0x0000 /*!< Uses the lineLen parameter to b64_encode2(). Ignored by b64_decode2(). */
  174. , B64_F_LINE_LEN_INFINITE = 0x0001 /*!< Ignores the lineLen parameter to b64_encode2(). Line length is infinite. Ignored by b64_decode2(). */
  175. , B64_F_LINE_LEN_64 = 0x0002 /*!< Ignores the lineLen parameter to b64_encode2(). Line length is 64. Ignored by b64_decode2(). */
  176. , B64_F_LINE_LEN_76 = 0x0003 /*!< Ignores the lineLen parameter to b64_encode2(). Line length is 76. Ignored by b64_decode2(). */
  177. , B64_F_LINE_LEN_MASK = 0x000f /*!< Mask for testing line length flags to b64_encode2(). Ignored by b64_encode2(). */
  178. , B64_F_STOP_ON_NOTHING = 0x0000 /*!< Decoding ignores all invalid characters in the input data. Ignored by b64_encode2(). */
  179. , B64_F_STOP_ON_UNKNOWN_CHAR = 0x0100 /*!< Causes decoding to break if any non-Base-64 [a-zA-Z0-9=+/], non-whitespace character is encountered. Ignored by b64_encode2(). */
  180. , B64_F_STOP_ON_UNEXPECTED_WS = 0x0200 /*!< Causes decoding to break if any unexpected whitespace is encountered. Ignored by b64_encode2(). */
  181. , B64_F_STOP_ON_BAD_CHAR = 0x0300 /*!< Causes decoding to break if any non-Base-64 [a-zA-Z0-9=+/] character is encountered. Ignored by b64_encode2(). */
  182. };
  183. #ifndef __cplusplus
  184. typedef enum B64_FLAGS B64_FLAGS;
  185. #endif /* !__cplusplus */
  186. /* /////////////////////////////////////////////////////////////////////////
  187. * Functions
  188. */
  189. #ifdef __cplusplus
  190. extern "C" {
  191. #endif /* __cplusplus */
  192. /** Encodes a block of binary data into Base-64
  193. *
  194. * \param src Pointer to the block to be encoded. May not be NULL, except when
  195. * \c dest is NULL, in which case it is ignored.
  196. * \param srcSize Length of block to be encoded
  197. * \param dest Pointer to the buffer into which the result is to be written. May
  198. * be NULL, in which case the function returns the required length
  199. * \param destLen Length of the buffer into which the result is to be written. Must
  200. * be at least as large as that indicated by the return value from
  201. * \link b64::b64_encode b64_encode(NULL, srcSize, NULL, 0)\endlink.
  202. *
  203. * \return 0 if the size of the buffer was insufficient, or the length of the
  204. * converted buffer was longer than \c destLen
  205. *
  206. * \note The function returns the required length if \c dest is NULL
  207. *
  208. * \note The function returns the required length if \c dest is NULL. The returned size
  209. * might be larger than the actual required size, but will never be smaller.
  210. *
  211. * \note Threading: The function is fully re-entrant.
  212. *
  213. * \see b64::encode()
  214. */
  215. size_t b64_encode(
  216. void const* src
  217. , size_t srcSize
  218. , b64_char_t* dest
  219. , size_t destLen
  220. );
  221. /** Encodes a block of binary data into Base-64
  222. *
  223. * \param src Pointer to the block to be encoded. May not be NULL, except when
  224. * \c dest is NULL, in which case it is ignored.
  225. * \param srcSize Length of block to be encoded
  226. * \param dest Pointer to the buffer into which the result is to be written. May
  227. * be NULL, in which case the function returns the required length
  228. * \param destLen Length of the buffer into which the result is to be written. Must
  229. * be at least as large as that indicated by the return value from
  230. * \link b64::b64_encode2 b64_encode2(NULL, srcSize, NULL, 0, flags, lineLen, rc)\endlink.
  231. * \param flags A combination of the B64_FLAGS enumeration, that moderate the
  232. * behaviour of the function
  233. * \param lineLen If the flags parameter contains B64_F_LINE_LEN_USE_PARAM, then
  234. * this parameter represents the length of the lines into which the encoded form is split,
  235. * with a hard line break ('\\r\\n'). If this value is 0, then the line is not
  236. * split. If it is <0, then the RFC-1113 recommended line length of 64 is used
  237. * \param rc The return code representing the status of the operation. May be NULL.
  238. *
  239. * \return 0 if the size of the buffer was insufficient, or the length of the
  240. * converted buffer was longer than \c destLen
  241. *
  242. * \note The function returns the required length if \c dest is NULL. The returned size
  243. * might be larger than the actual required size, but will never be smaller.
  244. *
  245. * \note Threading: The function is fully re-entrant.
  246. *
  247. * \see b64::encode()
  248. */
  249. size_t b64_encode2(
  250. void const* src
  251. , size_t srcSize
  252. , b64_char_t* dest
  253. , size_t destLen
  254. , unsigned flags
  255. , int lineLen /* = 0 */
  256. , B64_RC* rc /* = NULL */
  257. );
  258. /** Decodes a sequence of Base-64 into a block of binary data
  259. *
  260. * \param src Pointer to the Base-64 block to be decoded. May not be NULL, except when
  261. * \c dest is NULL, in which case it is ignored. If \c dest is NULL, and \c src is
  262. * <b>not</b> NULL, then the returned value is calculated exactly, otherwise a value
  263. * is returned that is guaranteed to be large enough to hold the decoded block.
  264. *
  265. * \param srcLen Length of block to be encoded. Must be an integral of 4, the Base-64
  266. * encoding quantum, otherwise the Base-64 block is assumed to be invalid
  267. * \param dest Pointer to the buffer into which the result is to be written. May
  268. * be NULL, in which case the function returns the required length
  269. * \param destSize Length of the buffer into which the result is to be written. Must
  270. * be at least as large as that indicated by the return value from
  271. * \c b64_decode(src, srcSize, NULL, 0), even in the case where the encoded form
  272. * contains a number of characters that will be ignored, resulting in a lower total
  273. * length of converted form.
  274. *
  275. * \return 0 if the size of the buffer was insufficient, or the length of the
  276. * converted buffer was longer than \c destSize
  277. *
  278. * \note The function returns the required length if \c dest is NULL. The returned size
  279. * might be larger than the actual required size, but will never be smaller.
  280. *
  281. * \note \anchor anchor__4_characters The behaviour of both
  282. * \link b64::b64_encode2 b64_encode2()\endlink
  283. * and
  284. * \link b64::b64_decode2 b64_decode2()\endlink
  285. * are undefined if the line length is not a multiple of 4.
  286. *
  287. * \note Threading: The function is fully re-entrant.
  288. *
  289. * \see b64::decode()
  290. */
  291. size_t b64_decode(
  292. b64_char_t const* src
  293. , size_t srcLen
  294. , void* dest
  295. , size_t destSize
  296. );
  297. /** Decodes a sequence of Base-64 into a block of binary data
  298. *
  299. * \param src Pointer to the Base-64 block to be decoded. May not be NULL, except when
  300. * \c dest is NULL, in which case it is ignored. If \c dest is NULL, and \c src is
  301. * <b>not</b> NULL, then the returned value is calculated exactly, otherwise a value
  302. * is returned that is guaranteed to be large enough to hold the decoded block.
  303. *
  304. * \param srcLen Length of block to be encoded. Must be an integral of 4, the Base-64
  305. * encoding quantum, otherwise the Base-64 block is assumed to be invalid
  306. * \param dest Pointer to the buffer into which the result is to be written. May
  307. * be NULL, in which case the function returns the required length
  308. * \param destSize Length of the buffer into which the result is to be written. Must
  309. * be at least as large as that indicated by the return value from
  310. * \c b64_decode(src, srcSize, NULL, 0), even in the case where the encoded form
  311. * contains a number of characters that will be ignored, resulting in a lower total
  312. * length of converted form.
  313. * \param flags A combination of the B64_FLAGS enumeration, that moderate the
  314. * behaviour of the function.
  315. * \param rc The return code representing the status of the operation. May be NULL.
  316. * \param badChar If the flags parameter does not contain B64_F_STOP_ON_NOTHING, this
  317. * parameter specifies the address of a pointer that will be set to point to any
  318. * character in the sequence that stops the parsing, as dictated by the flags
  319. * parameter. May be NULL.
  320. *
  321. * \return 0 if the size of the buffer was insufficient, or the length of the
  322. * converted buffer was longer than \c destSize, or a bad character stopped parsing.
  323. *
  324. * \note The function returns the required length if \c dest is NULL. The returned size
  325. * might be larger than the actual required size, but will never be smaller.
  326. *
  327. * \note The behaviour of both
  328. * \link b64::b64_encode2 b64_encode2()\endlink
  329. * and
  330. * \link b64::b64_decode2 b64_decode2()\endlink
  331. * are undefined if the line length is not a multiple of 4.
  332. *
  333. * \note Threading: The function is fully re-entrant.
  334. *
  335. * \see b64::decode()
  336. */
  337. size_t b64_decode2(
  338. b64_char_t const* src
  339. , size_t srcLen
  340. , void* dest
  341. , size_t destSize
  342. , unsigned flags
  343. , b64_char_t const** badChar /* = NULL */
  344. , B64_RC* rc /* = NULL */
  345. );
  346. /** Returns the textual description of the error
  347. *
  348. * \param code The \link b64::B64_RC error code\endlink
  349. *
  350. * \deprecated This function is deprecated and will be removed in a future
  351. * release; instead use b64_getStatusCodeString().
  352. */
  353. char const* b64_getErrorString(B64_RC code);
  354. /** Returns the length of the textual description of the error
  355. *
  356. * \see b64_getErrorString()
  357. *
  358. * \param code The \link b64::B64_RC error code\endlink
  359. *
  360. * \deprecated This function is deprecated and will be removed in a future
  361. * release; instead use b64_getStatusCodeStringLength().
  362. */
  363. size_t b64_getErrorStringLength(B64_RC code);
  364. /** \def b64_getStatusCodeString(code)
  365. *
  366. * Returns the textual description of the error
  367. *
  368. * \param code The \link b64::B64_RC error code\endlink
  369. *
  370. * \see b64_getStatusCodeStringLength, b64_getErrorString, b64_getErrorStringLength
  371. */
  372. #define b64_getStatusCodeString b64_getErrorString
  373. /** \def b64_getStatusCodeStringLength(code)
  374. *
  375. * Returns the length of the textual description of the error
  376. *
  377. * \param code The \link b64::B64_RC error code\endlink
  378. *
  379. * \see b64_getStatusCodeString, b64_getErrorString, b64_getErrorStringLength
  380. */
  381. #define b64_getStatusCodeStringLength b64_getErrorStringLength
  382. #ifdef __cplusplus
  383. } /* extern "C" */
  384. #endif /* __cplusplus */
  385. /* /////////////////////////////////////////////////////////////////////////
  386. * Namespace
  387. */
  388. #ifndef B64_NO_NAMESPACE
  389. } /* namespace B64_NAMESPACE */
  390. # ifndef B64_DOCUMENTATION_SKIP_SECTION
  391. namespace stlsoft
  392. {
  393. inline char const *c_str_data_a( B64_NAMESPACE_QUALIFIER::B64_RC code)
  394. {
  395. return B64_NAMESPACE_QUALIFIER::b64_getStatusCodeString(code);
  396. }
  397. inline char const *c_str_data( B64_NAMESPACE_QUALIFIER::B64_RC code)
  398. {
  399. return B64_NAMESPACE_QUALIFIER::b64_getStatusCodeString(code);
  400. }
  401. inline size_t c_str_len_a( B64_NAMESPACE_QUALIFIER::B64_RC code)
  402. {
  403. return B64_NAMESPACE_QUALIFIER::b64_getStatusCodeStringLength(code);
  404. }
  405. inline size_t c_str_len( B64_NAMESPACE_QUALIFIER::B64_RC code)
  406. {
  407. return B64_NAMESPACE_QUALIFIER::b64_getStatusCodeStringLength(code);
  408. }
  409. inline char const *c_str_ptr_a( B64_NAMESPACE_QUALIFIER::B64_RC code)
  410. {
  411. return B64_NAMESPACE_QUALIFIER::b64_getStatusCodeString(code);
  412. }
  413. inline char const *c_str_ptr( B64_NAMESPACE_QUALIFIER::B64_RC code)
  414. {
  415. return B64_NAMESPACE_QUALIFIER::b64_getStatusCodeString(code);
  416. }
  417. } /* namespace stlsoft */
  418. # endif /* !B64_DOCUMENTATION_SKIP_SECTION */
  419. #endif /* !B64_NO_NAMESPACE */
  420. /* ////////////////////////////////////////////////////////////////////// */
  421. #endif /* B64_INCL_B64_H_B64 */
  422. /* ///////////////////////////// end of file //////////////////////////// */