/* ///////////////////////////////////////////////////////////////////////// * File: b64/b64.hpp * * Purpose: Header file for the b64 C++-API. * * Created: 18th October 2004 * Updated: 4th February 2012 * * Home: http://synesis.com.au/software/ * * Copyright 2004-2012, Matthew Wilson and Synesis Software * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of * any contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * ////////////////////////////////////////////////////////////////////// */ /** \file b64/b64.hpp [C++ only] Header file for the b64 C++-API * * This header file contains the b64 C++-API types and functions. There are * no associated implementation files; in other words, the b64 C++-API is * header only. * * The b64/C++ is dependent on several components from the * STLSoft libraries (also 100% header-only) * so you will need to have them available on your include path when using this * header. * * \htmlonly *
* \endhtmlonly */ #ifndef B64_INCL_B64_HPP_B64 #define B64_INCL_B64_HPP_B64 /* ///////////////////////////////////////////////////////////////////////// * Version information */ #ifndef B64_DOCUMENTATION_SKIP_SECTION # define B64_VER_B64_HPP_B64_MAJOR 2 # define B64_VER_B64_HPP_B64_MINOR 1 # define B64_VER_B64_HPP_B64_REVISION 12 # define B64_VER_B64_HPP_B64_EDIT 38 #endif /* !B64_DOCUMENTATION_SKIP_SECTION */ /* ///////////////////////////////////////////////////////////////////////// * Includes */ #ifndef B64_INCL_B64_H_B64 # include #endif /* !B64_INCL_B64_H_B64 */ /* If the compiler cannot find the following include, you may have not * upgraded to the latest version of STLSoft: 1.9.1. Go to * http://stlsoft.org/ and download this version or later. */ #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT # include #endif /* !STLSOFT_INCL_STLSOFT_H_STLSOFT */ #if !defined(_STLSOFT_VER) || \ _STLSOFT_VER < 0x01096fff # error Requires STLSoft 1.9.111, or later. (www.stlsoft.org/downloads.html) #endif /* STLSoft version */ #ifdef STLSOFT_CF_std_NAMESPACE # if defined(B64_USE_CUSTOM_STRING) # include B64_CUSTOM_STRING_INCLUDE # else /* B64_USE_CUSTOM_STRING */ # include # endif /* !B64_USE_CUSTOM_STRING */ # if defined(B64_USE_CUSTOM_VECTOR) # include B64_CUSTOM_VECTOR_INCLUDE # else /* B64_USE_CUSTOM_VECTOR */ # include # endif /* !B64_USE_CUSTOM_VECTOR */ /* We'll now have a go at checking whether the string type is * known to be contiguous */ # ifndef STLSOFT_INCL_STLSOFT_UTIL_STD_LIBRARY_DISCRIMINATOR # include # endif /* !STLSOFT_INCL_STLSOFT_UTIL_STD_LIBRARY_DISCRIMINATOR */ # ifdef STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC # if STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION <= STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1 # define B64_STRING_TYPE_IS_CONTIGUOUS # endif /* STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION */ # endif /* STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC */ #else /* ? STLSOFT_CF_std_NAMESPACE */ # if defined(STLSOFT_COMPILER_IS_WATCOM) # include # include # define B64_USE_CUSTOM_STRING # define B64_CUSTOM_STRING_TYPE watcom_string_for_b64 # define B64_USE_CUSTOM_VECTOR # define B64_CUSTOM_BLOB_TYPE watcom_vector_for_b64 # define B64_STRING_TYPE_IS_CONTIGUOUS # else /* ? compiler */ # error No other non-std compiler is known # endif /* ? compiler */ #endif /* STLSOFT_CF_std_NAMESPACE */ #ifdef B64_NO_CONTIGUOUS_STRING_TYPE # ifdef B64_STRING_TYPE_IS_CONTIGUOUS # undef B64_STRING_TYPE_IS_CONTIGUOUS # endif /* B64_STRING_TYPE_IS_CONTIGUOUS */ #endif /* B64_NO_CONTIGUOUS_STRING_TYPE */ #if !defined(B64_STRING_TYPE_IS_CONTIGUOUS) # ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER # include # endif /* !STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER */ #endif /* !B64_STRING_TYPE_IS_CONTIGUOUS */ #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING # include #endif /* !STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING */ /* #ifdef B64_ */ #define B64_DECLARE_SHIM_PAIR_() stlsoft_ns_using(c_str_data_a); stlsoft_ns_using(c_str_len_a) #define B64_INVOKE_SHIM_data_(s) c_str_data_a(s) #define B64_INVOKE_SHIM_len_(s) c_str_len_a(s) #ifdef STLSOFT_CF_EXCEPTION_SUPPORT # if defined(STLSOFT_COMPILER_IS_WATCOM) # include # else /* ? compiler */ # include # endif /* compiler */ #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ /* ///////////////////////////////////////////////////////////////////////// * Namespace */ #ifndef B64_NO_NAMESPACE namespace B64_NAMESPACE { #endif /* !B64_NO_NAMESPACE */ /* ///////////////////////////////////////////////////////////////////////// * Classes */ #if defined(STLSOFT_COMPILER_IS_WATCOM) class watcom_vector_for_b64 : public WCValVector { private: typedef WCValVector parent_class_type; typedef watcom_vector_for_b64 class_type; public: watcom_vector_for_b64() {} watcom_vector_for_b64(size_t n) : parent_class_type(n) {} watcom_vector_for_b64(class_type const &rhs) : parent_class_type(rhs) {} public: size_t size() const { return parent_class_type::length(); } }; class watcom_string_for_b64 : public String { public: watcom_string_for_b64(size_t n, char ch) : String(ch, n) {} public: void resize(size_t n) { String& this_ = *this; this_ = String(*this, n); } }; #endif /* STLSOFT_COMPILER_IS_WATCOM */ #ifdef STLSOFT_CF_EXCEPTION_SUPPORT /** \brief Exception thrown during encoding/decoding */ class coding_exception : public stlsoft_ns_qual_std(runtime_error) { public: typedef stlsoft_ns_qual_std(runtime_error) parent_class_type; typedef coding_exception class_type; private: #if defined(B64_USE_CUSTOM_STRING) typedef B64_CUSTOM_STRING_TYPE string_type; #else /* B64_USE_CUSTOM_STRING */ typedef std::string string_type; #endif /* !B64_USE_CUSTOM_STRING */ public: /** Constructs an exception based on the error code, and a pointer to the bad character. */ coding_exception(B64_RC rc, char const* badChar) : parent_class_type(make_message_(rc)) , m_rc(rc) , m_badChar(badChar) {} public: /** The error code associated with the exception. */ B64_RC get_rc() const { return m_rc; } /** The return code associated with the exception. * * \note May be NULL, if the error is not associated with an invalid character encountered during decoding. */ char const* get_badChar() const { return m_badChar; } private: static string_type make_message_(B64_RC rc) { return string_type("Decoding error: ") + b64_getStatusCodeString(rc); } private: B64_RC m_rc; char const* m_badChar; }; #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ /* ///////////////////////////////////////////////////////////////////////// * Typedefs */ /** The string type for the b64 namespace * * \note This defaults to ::std::string. It is possible to override this, using * preprocessor symbol definitions. To do this, you must define * the symbol \c B64_USE_CUSTOM_STRING to instruct the compiler that the b64 * library is to use a custom string type. In that case you must also * define the \c B64_CUSTOM_STRING_INCLUDE and \c B64_CUSTOM_STRING_TYPE and symbols. * * \c B64_CUSTOM_STRING_INCLUDE specifies the \c <> or \c "" surrounded include file name, e.g. * *   \#define B64_CUSTOM_STRING_INCLUDE * * \c B64_CUSTOM_STRING_TYPE specifies the string type, e.g. * *   \#define B64_CUSTOM_STRING_TYPE    ::stlsoft::basic_simple_string * * \note For Open Watcom compilation, this type is actually the class * class b64::watcom_string_for_b64, a class adaptor for * the Open Watcom String class. The definition * of this class can be found in b64/b64.hpp. */ #if defined(B64_USE_CUSTOM_STRING) typedef B64_CUSTOM_STRING_TYPE string_t; #else /* B64_USE_CUSTOM_STRING */ typedef std::string string_t; #endif /* !B64_USE_CUSTOM_STRING */ /** The blob type for the b64 namespace * * \note This defaults to ::std::vector< ::stlsoft::byte_t>. It is possible to * override this, using * preprocessor symbol definitions. To do this, you must define * the symbol \c B64_USE_CUSTOM_VECTOR to instruct the compiler that the b64 * library is to use a custom string type. In that case you must also * define the \c B64_CUSTOM_VECTOR_INCLUDE and \c B64_CUSTOM_BLOB_TYPE and symbols. * * \c B64_CUSTOM_VECTOR_INCLUDE specifies the \c <> or \c "" surrounded include file name, e.g. * *   \#define B64_CUSTOM_VECTOR_INCLUDE * * \c B64_CUSTOM_BLOB_TYPE specifies the string type, e.g. * *   \#define B64_CUSTOM_BLOB_TYPE    ::stlsoft::pod_vector * * \note For Open Watcom compilation, this type is actually the class * class b64::watcom_vector_for_b64, a class adaptor for * the WCValVector<unsigned char> specialisation. The definition * of this class can be found in b64/b64.hpp. */ #if defined(B64_USE_CUSTOM_VECTOR) typedef B64_CUSTOM_BLOB_TYPE blob_t; #else /* B64_USE_CUSTOM_VECTOR */ # ifndef B64_DOCUMENTATION_SKIP_SECTION typedef ::stlsoft::byte_t byte_t_; typedef std::vector blob_t; # else /* !B64_DOCUMENTATION_SKIP_SECTION */ typedef std::vector< ::stlsoft::byte_t> blob_t; # endif /* !B64_DOCUMENTATION_SKIP_SECTION */ #endif /* !B64_USE_CUSTOM_VECTOR */ /* ///////////////////////////////////////////////////////////////////////// * Functions */ /** \brief Encodes the given block of memory into base-64. * * This function takes a pointer to a memory block to be encoded, and a number of * bytes to be encoded, and carries out a base-64 encoding on it, returning the * results in an instance of the string type \link #string_t string_t \endlink. See the * \ref section__cpp_api "example" from the main page * * \param src Pointer to the block to be encoded * \param srcSize Number of bytes in the block to be encoded * \param flags A combination of the B64_FLAGS enumeration, that moderate the * behaviour of the function * \param lineLen If the flags parameter contains B64_F_LINE_LEN_USE_PARAM, then * this parameter represents the length of the lines into which the encoded form is split, * with a hard line break ('\\r\\n'). If this value is 0, then the line is not * split. If it is <0, then the RFC-1113 recommended line length of 64 is used * \param rc The return code representing the status of the operation. May be NULL. * * \return The string form of the block * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ inline string_t encode(void const* src, size_t srcSize, int flags, int lineLen = 0, B64_RC* rc = NULL) { B64_RC rc_; // Make sure rc is non-NULL, since we will need to get the RC in order to // throw exception later. if(NULL == rc) { rc = &rc_; } size_t n = B64_NAMESPACE_QUALIFIER::b64_encode2(src, srcSize, NULL, 0u, static_cast(flags), lineLen, rc); #ifdef B64_STRING_TYPE_IS_CONTIGUOUS // If the string type is known to have contiguous storage we can avoid // any intermediate memory, and decode directly into its internal // buffer. string_t s(n, '~'); // ~ is used for an invalid / eyecatcher STLSOFT_MESSAGE_ASSERT("assumed contiguous string type is not so. Please report this error. To effect fix now, #define B64_NO_CONTIGUOUS_STRING_TYPE", 0 == n || &s[n - 1] == &s[0] + (n - 1)); size_t n2 = B64_NAMESPACE_QUALIFIER::b64_encode2(src, srcSize, &s[0], s.length(), static_cast(flags), lineLen, rc); s.resize(n2); #else /* ? B64_STRING_TYPE_IS_CONTIGUOUS */ // If the string type is not known to be contiguous, then we must use // intermediate storage. Here we use a 1KB auto_buffer, so that only // data in excess of that will incur an additional (over the string's) // heap allocation. typedef stlsoft::auto_buffer buffer_t; buffer_t buffer(n); size_t n2 = B64_NAMESPACE_QUALIFIER::b64_encode2(src, srcSize, &buffer[0], buffer.size(), static_cast(flags), lineLen, rc); string_t s(&buffer[0], n2); #endif /* B64_STRING_TYPE_IS_CONTIGUOUS */ #ifdef STLSOFT_CF_EXCEPTION_SUPPORT if( 0 != srcSize && 0 == n2 && rc == &rc_) { throw coding_exception(*rc, NULL); } #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ return s; } /** \brief Encodes the given block of memory into base-64. * * This function takes a pointer to a memory block to be encoded, and a number of * bytes to be encoded, and carries out a base-64 encoding on it, returning the * results in an instance of the string type \link #string_t string_t \endlink. See the * \ref section__cpp_api "example" from the main page * * \param src Pointer to the block to be encoded * \param srcSize Number of bytes in the block to be encoded * * \return The string form of the block * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ inline string_t encode(void const* src, size_t srcSize) { return encode(src, srcSize, 0, 0, NULL); } #ifdef STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT /** \brief Encodes the given array into base-64 * * \param ar The array whose contents are to be encoded * * \return The string form of the block * * \note This function is only defined for compilers that are able to discriminate * between pointers and arrays. See Chapter 14 of Imperfect C++ * for details about this facility, and consult your STLSoft header files * to find out to which compilers this applies. * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ template inline string_t encode(T (&ar)[N]) { return encode(&ar[0], sizeof(T) * N); } #endif /* STLSOFT_CF_STATIC_ARRAY_SIZE_DETERMINATION_SUPPORT */ /** \brief Encodes the given blob into base-64 * * \param blob The blob whose contents are to be encoded * * \return The string form of the block * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ inline string_t encode(blob_t const &blob) { return encode(blob.empty() ? NULL : &blob[0], blob.size()); } /** \brief Encodes the given blob into base-64 * * \param blob The blob whose contents are to be encoded * \param flags A combination of the B64_FLAGS enumeration, that moderate the * behaviour of the function * \param lineLen If the flags parameter contains B64_F_LINE_LEN_USE_PARAM, then * this parameter represents the length of the lines into which the encoded form is split, * with a hard line break ('\\r\\n'). If this value is 0, then the line is not * split. If it is <0, then the RFC-1113 recommended line length of 64 is used * \param rc The return code representing the status of the operation. May be NULL. * * \return The string form of the block * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ inline string_t encode(blob_t const &blob, int flags, int lineLen = 0, B64_RC* rc = NULL) { return encode(blob.empty() ? NULL : &blob[0], blob.size(), flags, lineLen, rc); } /** \brief Decodes the given base-64 block into binary * * \param src Pointer to the block to be decoded * \param srcLen Number of characters in the block to be decoded * \param flags A combination of the B64_FLAGS enumeration, that moderate the * behaviour of the function. * \param rc The return code representing the status of the operation. May be NULL. * \param badChar If the flags parameter does not contain B64_F_STOP_ON_NOTHING, this * parameter specifies the address of a pointer that will be set to point to the * character in the sequence that stops the parsing, as dictated by the flags * parameter. May be NULL. * * \return The binary form of the block, as a \c blob_t * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation * \exception b64::coding_exception If a bad character is encountered in the encoded block (as moderated by the flags parameter; see \link b64::B64_FLAGS B64_FLAGS\endlink) */ inline blob_t decode(b64_char_t const* src, size_t srcLen, int flags, b64_char_t const** badChar = NULL, B64_RC* rc = NULL) { #ifdef STLSOFT_CF_EXCEPTION_SUPPORT B64_RC rc_; b64_char_t const* badChar_; if(NULL == rc) { rc = &rc_; } if(NULL == badChar) { badChar = &badChar_; } #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ size_t n = B64_NAMESPACE_QUALIFIER::b64_decode2(src, srcLen, NULL, 0, static_cast(flags), badChar, rc); blob_t v(n); size_t n2 = v.empty() ? 0 : B64_NAMESPACE_QUALIFIER::b64_decode2(src, srcLen, &v[0], v.size(), static_cast(flags), badChar, rc); v.resize(n2); #ifdef STLSOFT_CF_EXCEPTION_SUPPORT if( 0 != srcLen && 0 == n2 && rc == &rc_) { if(B64_RC_OK == *rc) { *rc = B64_RC_TRUNCATED_INPUT; } throw coding_exception(*rc, (badChar == &badChar_) ? *badChar : NULL); } #endif /* STLSOFT_CF_EXCEPTION_SUPPORT */ return v; } /** \brief Decodes the given base-64 block into binary * * \param src Pointer to the block to be decoded * \param srcLen Number of characters in the block to be decoded * * \return The binary form of the block, as a \c blob_t * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ inline blob_t decode(b64_char_t const* src, size_t srcLen) { return decode(src, srcLen, B64_F_STOP_ON_BAD_CHAR, NULL, NULL); } #ifndef B64_DOCUMENTATION_SKIP_SECTION STLSOFT_OPEN_WORKER_NS_(impl) /** \brief Function template that decodes an instance of an arbitrary string type from base-64 into binary * * \param str The string whose contents are to be decoded * \param flags Flags that moderate the decoding * * \return The binary form of the block, as a \c blob_t * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ template inline blob_t b64_impl_decode_(int flags, S const &str) { B64_DECLARE_SHIM_PAIR_(); b64_char_t const* dummy; // Cannot rely on badChar being available in str return decode( B64_INVOKE_SHIM_data_(str) , B64_INVOKE_SHIM_len_(str) , static_cast(flags) , &dummy , NULL ); } STLSOFT_CLOSE_WORKER_NS_(ns) #endif /* !B64_DOCUMENTATION_SKIP_SECTION */ /** \brief Function template that decodes an instance of an arbitrary string type from base-64 into binary * * \param str The string whose contents are to be decoded * * \return The binary form of the block, as a \c blob_t * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ template inline blob_t decode(S const &str) { return STLSOFT_WORKER_NS_QUAL_(impl, b64_impl_decode_)(B64_F_STOP_ON_BAD_CHAR, str); } /** \brief Function template that decodes an instance of an arbitrary string type from base-64 into binary * * \param str The string whose contents are to be decoded * \param flags Flags that moderate the decoding * * \return The binary form of the block, as a \c blob_t * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation */ template inline blob_t decode(int flags, S const &str) // NOTE: This has to be overloaded, rather than use default arguments, otherwise VC has a spit { return STLSOFT_WORKER_NS_QUAL_(impl, b64_impl_decode_)(flags, str); } /** \brief Decodes the given string from base-64 into binary * * \param str The string whose contents are to be decoded * \param flags A combination of the B64_FLAGS enumeration, that moderate the * behaviour of the function. * * \return The binary form of the block, as a \c blob_t * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation * \exception b64::coding_exception If a bad character is encountered in the encoded block (as moderated by the flags parameter; see \link b64::B64_FLAGS B64_FLAGS\endlink) */ inline blob_t decode(string_t const &str, int flags = B64_F_STOP_ON_BAD_CHAR) { B64_DECLARE_SHIM_PAIR_(); return decode( B64_INVOKE_SHIM_data_(str) , B64_INVOKE_SHIM_len_(str) , flags , NULL , NULL ); } /** \brief Decodes the given string from base-64 into binary * * \param str The string whose contents are to be decoded * \param flags A combination of the B64_FLAGS enumeration, that moderate the * behaviour of the function. * \param rc The return code representing the status of the operation. May be NULL. * \param badChar If the flags parameter does not contain B64_F_STOP_ON_NOTHING, this * parameter specifies the address of a pointer that will be set to point to the * character in the sequence that stops the parsing, as dictated by the flags * parameter. May be NULL. * * \return The binary form of the block, as a \c blob_t * * \note There is no error return. If insufficient memory can be allocated, an * instance of \c std::bad_alloc will be thrown * * \note Threading: The function is fully re-entrant, assuming that the heap for the * system is re-entrant. * * \note Exceptions: Provides the strong guarantee, assuming that the constructor for * the string type (\c string_t) does so. * * \exception std::bad_alloc If insufficient memory is available to complete the operation * \exception b64::coding_exception If a bad character is encountered in the encoded block (as moderated by the flags parameter; see \link b64::B64_FLAGS B64_FLAGS\endlink) */ inline blob_t decode(string_t const &str, int flags, b64_char_t const** badChar, B64_RC* rc = NULL) { B64_DECLARE_SHIM_PAIR_(); return decode( B64_INVOKE_SHIM_data_(str) , B64_INVOKE_SHIM_len_(str) , flags , badChar , rc ); } /* ///////////////////////////////////////////////////////////////////////// * Namespace */ /** \brief [C++ only] The b64::cpp namespace, within which the C++ * types and functions used to reside; they now reside * within the b64 namespace. * * \deprecated All the constructs that were formerly in the * b64::cpp namespace now reside within the b64 * namespace. */ namespace cpp { using B64_NAMESPACE::coding_exception; using B64_NAMESPACE::blob_t; using B64_NAMESPACE::string_t; using B64_NAMESPACE::decode; using B64_NAMESPACE::encode; } /* namespace cpp */ #ifndef B64_NO_NAMESPACE } /* namespace B64_NAMESPACE */ #endif /* !B64_NO_NAMESPACE */ /* ////////////////////////////////////////////////////////////////////// */ #endif /* B64_INCL_B64_HPP_B64 */ /* ///////////////////////////// end of file //////////////////////////// */