Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:24

0001 //
0002 // Copyright (c) 2016-2019 Vinnie Falco (vinnie dot falco at gmail dot com)
0003 //
0004 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0005 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // Official repository: https://github.com/boostorg/beast
0008 //
0009 
0010 /*
0011    Portions from http://www.adp-gmbh.ch/cpp/common/base64.html
0012    Copyright notice:
0013 
0014    base64.cpp and base64.h
0015 
0016    Copyright (C) 2004-2008 Rene Nyffenegger
0017 
0018    This source code is provided 'as-is', without any express or implied
0019    warranty. In no event will the author be held liable for any damages
0020    arising from the use of this software.
0021 
0022    Permission is granted to anyone to use this software for any purpose,
0023    including commercial applications, and to alter it and redistribute it
0024    freely, subject to the following restrictions:
0025 
0026    1. The origin of this source code must not be misrepresented; you must not
0027       claim that you wrote the original source code. If you use this source code
0028       in a product, an acknowledgment in the product documentation would be
0029       appreciated but is not required.
0030 
0031    2. Altered source versions must be plainly marked as such, and must not be
0032       misrepresented as being the original source code.
0033 
0034    3. This notice may not be removed or altered from any source distribution.
0035 
0036    Rene Nyffenegger rene.nyffenegger@adp-gmbh.ch
0037 */
0038 
0039 #ifndef BOOST_BEAST_DETAIL_BASE64_IPP
0040 #define BOOST_BEAST_DETAIL_BASE64_IPP
0041 
0042 #include <boost/beast/core/detail/base64.hpp>
0043 #include <boost/beast/core/string.hpp>
0044 #include <cctype>
0045 #include <string>
0046 #include <utility>
0047 
0048 namespace boost {
0049 namespace beast {
0050 namespace detail {
0051 
0052 namespace base64 {
0053 
0054 char const*
0055 get_alphabet()
0056 {
0057     static char constexpr tab[] = {
0058         "ABCDEFGHIJKLMNOP"
0059         "QRSTUVWXYZabcdef"
0060         "ghijklmnopqrstuv"
0061         "wxyz0123456789+/"
0062     };
0063     return &tab[0];
0064 }
0065 
0066 signed char const*
0067 get_inverse()
0068 {
0069     static signed char constexpr tab[] = {
0070          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //   0-15
0071          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, //  16-31
0072          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, //  32-47
0073          52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, //  48-63
0074          -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, //  64-79
0075          15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, //  80-95
0076          -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, //  96-111
0077          41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, // 112-127
0078          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 128-143
0079          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 144-159
0080          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 160-175
0081          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 176-191
0082          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 192-207
0083          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 208-223
0084          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 224-239
0085          -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1  // 240-255
0086     };
0087     return &tab[0];
0088 }
0089 
0090 /** Encode a series of octets as a padded, base64 string.
0091 
0092     The resulting string will not be null terminated.
0093 
0094     @par Requires
0095 
0096     The memory pointed to by `out` points to valid memory
0097     of at least `encoded_size(len)` bytes.
0098 
0099     @return The number of characters written to `out`. This
0100     will exclude any null termination.
0101 */
0102 std::size_t
0103 encode(void* dest, void const* src, std::size_t len)
0104 {
0105     char*      out = static_cast<char*>(dest);
0106     char const* in = static_cast<char const*>(src);
0107     auto const tab = base64::get_alphabet();
0108 
0109     for(auto n = len / 3; n--;)
0110     {
0111         *out++ = tab[ (in[0] & 0xfc) >> 2];
0112         *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
0113         *out++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
0114         *out++ = tab[  in[2] & 0x3f];
0115         in += 3;
0116     }
0117 
0118     switch(len % 3)
0119     {
0120     case 2:
0121         *out++ = tab[ (in[0] & 0xfc) >> 2];
0122         *out++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
0123         *out++ = tab[                         (in[1] & 0x0f) << 2];
0124         *out++ = '=';
0125         break;
0126 
0127     case 1:
0128         *out++ = tab[ (in[0] & 0xfc) >> 2];
0129         *out++ = tab[((in[0] & 0x03) << 4)];
0130         *out++ = '=';
0131         *out++ = '=';
0132         break;
0133 
0134     case 0:
0135         break;
0136     }
0137 
0138     return out - static_cast<char*>(dest);
0139 }
0140 
0141 /** Decode a padded base64 string into a series of octets.
0142 
0143     @par Requires
0144 
0145     The memory pointed to by `out` points to valid memory
0146     of at least `decoded_size(len)` bytes.
0147 
0148     @return The number of octets written to `out`, and
0149     the number of characters read from the input string,
0150     expressed as a pair.
0151 */
0152 std::pair<std::size_t, std::size_t>
0153 decode(void* dest, char const* src, std::size_t len)
0154 {
0155     char* out = static_cast<char*>(dest);
0156     auto in = reinterpret_cast<unsigned char const*>(src);
0157     unsigned char c3[3], c4[4] = {0,0,0,0};
0158     int i = 0;
0159     int j = 0;
0160 
0161     auto const inverse = base64::get_inverse();
0162 
0163     while(len-- && *in != '=')
0164     {
0165         auto const v = inverse[*in];
0166         if(v == -1)
0167             break;
0168         ++in;
0169         c4[i] = v;
0170         if(++i == 4)
0171         {
0172             c3[0] =  (c4[0]        << 2) + ((c4[1] & 0x30) >> 4);
0173             c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
0174             c3[2] = ((c4[2] & 0x3) << 6) +   c4[3];
0175 
0176             for(i = 0; i < 3; i++)
0177                 *out++ = c3[i];
0178             i = 0;
0179         }
0180     }
0181 
0182     if(i)
0183     {
0184         c3[0] = ( c4[0]        << 2) + ((c4[1] & 0x30) >> 4);
0185         c3[1] = ((c4[1] & 0xf) << 4) + ((c4[2] & 0x3c) >> 2);
0186         c3[2] = ((c4[2] & 0x3) << 6) +   c4[3];
0187 
0188         for(j = 0; j < i - 1; j++)
0189             *out++ = c3[j];
0190     }
0191 
0192     return {out - static_cast<char*>(dest),
0193         in - reinterpret_cast<unsigned char const*>(src)};
0194 }
0195 
0196 } // base64
0197 
0198 } // detail
0199 } // beast
0200 } // boost
0201 
0202 #endif