1 /*
2  * Copyright (C) 2012-13 The gtkmm Development Team
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <glibmm/base64.h>
19 #include <glibmm/utility.h>
20 
21 namespace Glib
22 {
23 
24 std::string
encode(const std::string & source,bool break_lines)25 Base64::encode(const std::string& source, bool break_lines)
26 {
27   /* The output buffer must be large enough to fit all the data that will be
28      written to it. Due to the way base64 encodes you will need at least:
29      (len / 3 + 1) * 4 + 4 bytes (+ 4 may be needed in case of non-zero state).
30      If you enable line-breaking you will need at least:
31      ((len / 3 + 1) * 4 + 4) / 72 + 1 bytes of extra space.
32   */
33   gsize length = (source.length() / 3 + 1) * 4 + 1; // + 1 for the terminating zero
34   length += ((length / 72) + 1); // in case break_lines = true
35   const auto buf = make_unique_ptr_gfree((char*)g_malloc(length));
36   gint state = 0, save = 0;
37   const guchar* src = reinterpret_cast<const unsigned char*>(source.data());
38   gsize out = g_base64_encode_step(src, source.length(), break_lines, buf.get(), &state, &save);
39   out += g_base64_encode_close(break_lines, buf.get() + out, &state, &save);
40   return std::string(buf.get(), buf.get() + out);
41 }
42 
43 std::string
decode(const std::string & source)44 Base64::decode(const std::string& source)
45 {
46   gsize size;
47   const auto buf = make_unique_ptr_gfree((char*)g_base64_decode(source.c_str(), &size));
48   return std::string(buf.get(), buf.get() + size);
49 }
50 
51 } // namespace Glib
52