Prepare for 1.4.0 release.
[inoclam.git] / src / base64.cxx
blob7464634eb0616a7c672821a602a6447fd5609031
1 // Note that the only valid version of the GPL as far as jwSMTP
2 // is concerned is v2 of the license (ie v2, not v2.2 or v3.x or whatever),
3 // unless explicitly otherwise stated.
4 //
5 // This file is part of the jwSMTP library.
6 //
7 // jwSMTP library is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; version 2 of the License.
11 // jwSMTP library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with jwSMTP library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // jwSMTP library
21 // http://johnwiggins.net
22 // smtplib@johnwiggins.net
24 // base64.h: base64 encoding functions
26 // Modified by Tom Cort <tom.cort@state.vt.us 30-Oct-2008.
27 // Renamed headers to .hxx and removed WIN32 specific code.
29 #include <vector>
30 #include <string>
31 #include "base64.hxx"
32 namespace jwsmtp {
33 char getbase64character(const char &in) {
34 switch (in) {
35 case B64_A:
36 return 'A';
37 case B64_B:
38 return 'B';
39 case B64_C:
40 return 'C';
41 case B64_D:
42 return 'D';
43 case B64_E:
44 return 'E';
45 case B64_F:
46 return 'F';
47 case B64_G:
48 return 'G';
49 case B64_H:
50 return 'H';
51 case B64_I:
52 return 'I';
53 case B64_J:
54 return 'J';
55 case B64_K:
56 return 'K';
57 case B64_L:
58 return 'L';
59 case B64_M:
60 return 'M';
61 case B64_N:
62 return 'N';
63 case B64_O:
64 return 'O';
65 case B64_P:
66 return 'P';
67 case B64_Q:
68 return 'Q';
69 case B64_R:
70 return 'R';
71 case B64_S:
72 return 'S';
73 case B64_T:
74 return 'T';
75 case B64_U:
76 return 'U';
77 case B64_V:
78 return 'V';
79 case B64_W:
80 return 'W';
81 case B64_X:
82 return 'X';
83 case B64_Y:
84 return 'Y';
85 case B64_Z:
86 return 'Z';
87 case B64_a:
88 return 'a';
89 case B64_b:
90 return 'b';
91 case B64_c:
92 return 'c';
93 case B64_d:
94 return 'd';
95 case B64_e:
96 return 'e';
97 case B64_f:
98 return 'f';
99 case B64_g:
100 return 'g';
101 case B64_h:
102 return 'h';
103 case B64_i:
104 return 'i';
105 case B64_j:
106 return 'j';
107 case B64_k:
108 return 'k';
109 case B64_l:
110 return 'l';
111 case B64_m:
112 return 'm';
113 case B64_n:
114 return 'n';
115 case B64_o:
116 return 'o';
117 case B64_p:
118 return 'p';
119 case B64_q:
120 return 'q';
121 case B64_r:
122 return 'r';
123 case B64_s:
124 return 's';
125 case B64_t:
126 return 't';
127 case B64_u:
128 return 'u';
129 case B64_v:
130 return 'v';
131 case B64_w:
132 return 'w';
133 case B64_x:
134 return 'x';
135 case B64_y:
136 return 'y';
137 case B64_z:
138 return 'z';
139 case B64_0:
140 return '0';
141 case B64_1:
142 return '1';
143 case B64_2:
144 return '2';
145 case B64_3:
146 return '3';
147 case B64_4:
148 return '4';
149 case B64_5:
150 return '5';
151 case B64_6:
152 return '6';
153 case B64_7:
154 return '7';
155 case B64_8:
156 return '8';
157 case B64_9:
158 return '9';
159 case plus:
160 return '+';
161 case slash:
162 return '/';
163 case padding:
164 return '=';
166 return '\0'; // ?????? yikes
168 std::vector < char >base64encode(const std::vector < char >&input, const bool returns) {
169 std::vector < char >output;
171 // add a newline (SMTP demands less than 1000 characters in a message line).
172 long count = 0;
173 for (std::vector < char >::size_type p = 0; p < input.size(); p += 3) {
174 output.push_back(getbase64character((input[p] & 0xFC) >> 2));
175 ++count;
176 if (p + 1 < input.size()) {
177 output.push_back(getbase64character(((input[p] & 0x03) << 4) | ((input[p + 1] & 0xF0) >> 4)));
178 ++count;
180 if (p + 2 < input.size()) {
181 output.push_back(getbase64character(((input[p + 1] & 0x0F) << 2) | ((input[p + 2] & 0xC0) >> 6)));
182 output.push_back(getbase64character((input[p + 2] & 0x3F)));
183 ++count;
185 if (p + 1 == input.size()) {
186 output.push_back(getbase64character(((input[p] & 0x03) << 4)));
189 else if (p + 2 == input.size()) {
190 output.push_back(getbase64character(((input[p + 1] & 0x0F) << 2)));
192 if (returns) {
194 // 79 characters on a line.
195 if (count > 75) {
196 output.push_back('\r');
197 output.push_back('\n');
198 count = 0;
202 int pad(input.size() % 3);
203 if (pad) {
204 if (pad == 1)
205 pad = 2;
207 else
208 pad = 1;
210 for (int i = 0; i < pad; ++i)
211 output.push_back('=');
212 return output;
214 std::string base64encode(const std::string & input, const bool returns) {
215 std::vector < char >in, out;
216 for (std::string::const_iterator it = input.begin(); it != input.end(); ++it) {
217 in.push_back(*it);
219 out = base64encode(in, returns);
220 std::string ret;
221 for (std::vector < char >::const_iterator it1 = out.begin(); it1 != out.end(); ++it1) {
222 ret += *it1;
223 } return ret;
225 } // end namespace jwsmtp