1 /*
2  * DISTRHO Plugin Framework (DPF)
3  * Copyright (C) 2012-2016 Filipe Coelho <falktx@falktx.com>
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any purpose with
6  * or without fee is hereby granted, provided that the above copyright notice and this
7  * permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
10  * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
11  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
13  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #ifndef DISTRHO_BASE64_HPP_INCLUDED
18 #define DISTRHO_BASE64_HPP_INCLUDED
19 
20 #include "../DistrhoUtils.hpp"
21 
22 #include <cctype>
23 #include <vector>
24 
25 // -----------------------------------------------------------------------
26 // base64 stuff, based on http://www.adp-gmbh.ch/cpp/common/base64.html
27 
28 /*
29    Copyright (C) 2004-2008 René Nyffenegger
30 
31    This source code is provided 'as-is', without any express or implied
32    warranty. In no event will the author be held liable for any damages
33    arising from the use of this software.
34 
35    Permission is granted to anyone to use this software for any purpose,
36    including commercial applications, and to alter it and redistribute it
37    freely, subject to the following restrictions:
38 
39    1. The origin of this source code must not be misrepresented; you must not
40       claim that you wrote the original source code. If you use this source code
41       in a product, an acknowledgment in the product documentation would be
42       appreciated but is not required.
43 
44    2. Altered source versions must be plainly marked as such, and must not be
45       misrepresented as being the original source code.
46 
47    3. This notice may not be removed or altered from any source distribution.
48 
49    René Nyffenegger rene.nyffenegger@adp-gmbh.ch
50 */
51 
52 // -----------------------------------------------------------------------
53 // Helpers
54 
55 #ifndef DOXYGEN
56 namespace DistrhoBase64Helpers {
57 
58 static const char* const kBase64Chars =
59     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
60     "abcdefghijklmnopqrstuvwxyz"
61     "0123456789+/";
62 
63 static inline
findBase64CharIndex(const char c)64 uint8_t findBase64CharIndex(const char c)
65 {
66     static const uint8_t kBase64CharsLen(static_cast<uint8_t>(std::strlen(kBase64Chars)));
67 
68     for (uint8_t i=0; i<kBase64CharsLen; ++i)
69     {
70         if (kBase64Chars[i] == c)
71             return i;
72     }
73 
74     d_stderr2("findBase64CharIndex('%c') - failed", c);
75     return 0;
76 }
77 
78 static inline
isBase64Char(const char c)79 bool isBase64Char(const char c)
80 {
81     return (std::isalnum(c) || (c == '+') || (c == '/'));
82 }
83 
84 } // namespace DistrhoBase64Helpers
85 #endif
86 
87 // -----------------------------------------------------------------------
88 
89 static inline
d_getChunkFromBase64String(const char * const base64string)90 std::vector<uint8_t> d_getChunkFromBase64String(const char* const base64string)
91 {
92     DISTRHO_SAFE_ASSERT_RETURN(base64string != nullptr, std::vector<uint8_t>());
93 
94     uint i=0, j=0;
95     uint charArray3[3], charArray4[4];
96 
97     std::vector<uint8_t> ret;
98     ret.reserve(std::strlen(base64string)*3/4 + 4);
99 
100     for (std::size_t l=0, len=std::strlen(base64string); l<len; ++l)
101     {
102         const char c = base64string[l];
103 
104         if (c == '\0' || c == '=')
105             break;
106         if (c == ' ' || c == '\n')
107             continue;
108 
109         DISTRHO_SAFE_ASSERT_CONTINUE(DistrhoBase64Helpers::isBase64Char(c));
110 
111         charArray4[i++] = static_cast<uint>(c);
112 
113         if (i == 4)
114         {
115             for (i=0; i<4; ++i)
116                 charArray4[i] = DistrhoBase64Helpers::findBase64CharIndex(static_cast<char>(charArray4[i]));
117 
118             charArray3[0] =  (charArray4[0] << 2)        + ((charArray4[1] & 0x30) >> 4);
119             charArray3[1] = ((charArray4[1] & 0xf) << 4) + ((charArray4[2] & 0x3c) >> 2);
120             charArray3[2] = ((charArray4[2] & 0x3) << 6) +   charArray4[3];
121 
122             for (i=0; i<3; ++i)
123                 ret.push_back(static_cast<uint8_t>(charArray3[i]));
124 
125             i = 0;
126         }
127     }
128 
129     if (i != 0)
130     {
131         for (j=0; j<i && j<4; ++j)
132             charArray4[j] = DistrhoBase64Helpers::findBase64CharIndex(static_cast<char>(charArray4[j]));
133 
134         for (j=i; j<4; ++j)
135             charArray4[j] = 0;
136 
137         charArray3[0] =  (charArray4[0] << 2)        + ((charArray4[1] & 0x30) >> 4);
138         charArray3[1] = ((charArray4[1] & 0xf) << 4) + ((charArray4[2] & 0x3c) >> 2);
139         charArray3[2] = ((charArray4[2] & 0x3) << 6) +   charArray4[3];
140 
141         for (j=0; i>0 && j<i-1; j++)
142             ret.push_back(static_cast<uint8_t>(charArray3[j]));
143     }
144 
145     return ret;
146 }
147 
148 // -----------------------------------------------------------------------
149 
150 #endif // DISTRHO_BASE64_HPP_INCLUDED
151