0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Base64.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3
9  * of the License.
10  *
11  * Hypertable 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.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
26 
27 #include <Common/Compat.h>
28 
29 #include "Base64.h"
30 
31 #if defined(__APPLE__)
32 #include <Common/fmemopen.h>
33 #endif
34 
35 #include <string>
36 
37 extern "C" {
38 #include <openssl/bio.h>
39 #include <openssl/evp.h>
40 
41 #include <math.h>
42 #include <stdio.h>
43 #include <string.h>
44 }
45 
46 #pragma clang diagnostic push
47 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
48 
49 using namespace Hypertable;
50 
51 namespace {
52  int decode_length(const string message) {
53  int padding = 0;
54 
55  // Check for trailing '=''s as padding
56  if (message[message.length()-1] == '=' && message[message.length()-2] == '=')
57  padding = 2;
58  else if (message[message.length()-1] == '=')
59  padding = 1;
60 
61  return (int)message.length()*0.75 - padding;
62  }
63 
64 }
65 
66 const string Base64::encode(const string &message, bool newlines) {
67  BIO *bio;
68  BIO *b64;
69  FILE* stream;
70 
71  int encoded_length = (4*ceil((double)message.length()/3)) + 64 + 1;
72  char *buffer = new char [encoded_length];
73 
74  stream = fmemopen(buffer, encoded_length, "w");
75  b64 = BIO_new(BIO_f_base64());
76  bio = BIO_new_fp(stream, BIO_NOCLOSE);
77  bio = BIO_push(b64, bio);
78  if (!newlines)
79  BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
80  BIO_write(bio, message.c_str(), message.length());
81  (void)BIO_flush(bio);
82  int buffer_length = BIO_tell(bio);
83  BIO_free_all(bio);
84  fclose(stream);
85 
86  string encoded_message(buffer, buffer_length);
87  delete [] buffer;
88 
89  return encoded_message;
90 }
91 
92 const string Base64::decode(const string &message, bool newlines) {
93  BIO *bio;
94  BIO *b64;
95  int decoded_length = decode_length(message);
96 
97  unsigned char *buffer = new unsigned char [decoded_length+1];
98  FILE* stream = fmemopen((char*)message.c_str(), message.length(), "r");
99 
100  b64 = BIO_new(BIO_f_base64());
101  bio = BIO_new_fp(stream, BIO_NOCLOSE);
102  bio = BIO_push(b64, bio);
103  if (!newlines)
104  BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
105  decoded_length = BIO_read(bio, buffer, message.length());
106  buffer[decoded_length] = '\0';
107 
108  BIO_free_all(bio);
109  fclose(stream);
110 
111  string decoded_message((const char *)buffer, decoded_length);
112  delete buffer;
113 
114  return decoded_message;
115 }
116 
117 #pragma clang diagnostic pop
Compatibility Macros for C/C++.
Declarations for Base64.
static const string encode(const string &message, bool newlines=false)
Encodes message in base64.
Definition: Base64.cc:66
FILE * fmemopen(void *buf, size_t size, const char *mode)
A BSD port of the fmemopen Linux method using funopen.
Definition: fmemopen.c:94
Hypertable definitions
static const string decode(const string &message, bool newlines=false)
Decodes base64 message.
Definition: Base64.cc:92