Project
Loading...
Searching...
No Matches
Base64.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11#include "Base64.h"
12
13#include <cstdint>
14#include <cstdlib>
15#include <cstring>
16
17#include <cstdio>
18#include <cassert>
19
21{
22static char encoder[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
23static char decoder[256];
24static int initialized;
25
26static void
27 base64_init_decoder()
28{
29 int i = 0;
30
31 if (initialized) {
32 return;
33 }
34
35 // -1 is used for error detection
36 memset(decoder, -1, sizeof decoder);
37
38 for (; i < 64; decoder[(int)encoder[i]] = i, ++i) {
39 }
40
41 initialized = 1;
42
43 return;
44}
45
46static int
47 base64_encsize(int size)
48{
49 return 4 * ((size + 2) / 3);
50}
51
52int base64_encode(char* dest, int size, unsigned char* src, int slen)
53{
54 int dlen, i, j;
55 uint32_t a, b, c, triple;
56
57 dlen = base64_encsize(slen);
58
59 // Sanity checks
60 if (src == nullptr || dest == nullptr) {
61 return -1;
62 }
63 if (dlen + 1 > size) {
64 return -1;
65 }
66 if (slen == 0) {
67 if (size > 0) {
68 dest[0] = 0;
69 return 0;
70 }
71 return -1;
72 }
73
74 for (i = 0, j = 0; i < slen;) {
75 a = src[i++];
76
77 // b and c may be off limit
78 b = i < slen ? src[i++] : 0;
79 c = i < slen ? src[i++] : 0;
80
81 triple = (a << 16) + (b << 8) + c;
82
83 dest[j++] = encoder[(triple >> 18) & 0x3F];
84 dest[j++] = encoder[(triple >> 12) & 0x3F];
85 dest[j++] = encoder[(triple >> 6) & 0x3F];
86 dest[j++] = encoder[triple & 0x3F];
87 }
88
89 // Pad zeroes at the end
90 switch (slen % 3) {
91 case 1:
92 dest[j - 2] = '=';
93 case 2:
94 dest[j - 1] = '=';
95 }
96
97 // Always add \0
98 dest[j] = 0;
99
100 return dlen;
101}
102
103char* base64_enc_malloc(unsigned char* src, int slen)
104{
105 int size;
106 char* buffer;
107
108 size = base64_encsize(slen) + 1;
109
110 buffer = (char*)malloc(size);
111 if (buffer == nullptr) {
112 return nullptr;
113 }
114
115 size = base64_encode(buffer, size, src, slen);
116 if (size == -1) {
117 free(buffer);
118 return nullptr;
119 }
120
121 return buffer;
122}
123
124static int
125 base64_decsize(char* src)
126{
127 int slen, size, i;
128
129 if (src == nullptr) {
130 return 0;
131 }
132
133 slen = strlen(src);
134 size = slen / 4 * 3;
135
136 // Count pad chars
137 for (i = 0; src[slen - i - 1] == '='; ++i) {
138 }
139
140 // Remove at most 2 bytes.
141 return size - (i >= 2 ? 2 : i);
142}
143
144int base64_decode(unsigned char* dest, int size, char* src)
145{
146 int slen, dlen, padlen, i, j;
147 uint32_t a, b, c, d, triple;
148
149 // Initialize decoder
150 base64_init_decoder();
151
152 // Sanity checks
153 if (src == nullptr || dest == nullptr) {
154 return -1;
155 }
156
157 slen = strlen(src);
158 if (slen == 0) {
159 if (size > 0) {
160 dest[0] = 0;
161 return 0;
162 }
163 return -1;
164 }
165
166 // Remove trailing pad characters.
167 for (padlen = 0; src[slen - padlen - 1] == '='; ++padlen) {
168 }
169 if (padlen > 2) {
170 slen -= padlen - 2;
171 }
172 if (slen % 4) {
173 return -1;
174 }
175
176 dlen = base64_decsize(src);
177
178 // Check buffer size
179 if (dlen + 1 > size) {
180 return -1;
181 }
182
183 for (i = 0, j = 0; i < slen;) {
184 a = decoder[(int)src[i++]];
185 b = decoder[(int)src[i++]];
186 c = decoder[(int)src[i++]];
187 d = decoder[(int)src[i++]];
188
189 // Sextet 3 and 4 may be zero at the end
190 if (i == slen) {
191 if (src[slen - 1] == '=') {
192 d = 0;
193 if (src[slen - 2] == '=') {
194 c = 0;
195 }
196 }
197 }
198
199 // Non-Base64 char
200 if (a == -1 || b == -1 || c == -1 || d == -1) {
201 return -1;
202 }
203
204 triple = (a << 18) + (b << 12) + (c << 6) + d;
205
206 dest[j++] = (triple >> 16) & 0xFF;
207 dest[j++] = (triple >> 8) & 0xFF;
208 dest[j++] = triple & 0xFF;
209 }
210
211 // Always add \0
212 dest[j] = 0;
213
214 return dlen;
215}
216
217unsigned char*
219{
220 int size;
221 unsigned char* buffer;
222
223 size = base64_decsize(src) + 1;
224
225 buffer = (unsigned char*)malloc(size);
226 if (buffer == nullptr) {
227 return nullptr;
228 }
229
231 if (size == -1) {
232 free(buffer);
233 return nullptr;
234 }
235
236 return buffer;
237}
238} // namespace o2::framework::internal
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
GLenum src
Definition glcorearb.h:1767
GLuint buffer
Definition glcorearb.h:655
GLsizeiptr size
Definition glcorearb.h:659
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
unsigned char * base64_dec_malloc(char *src)
Definition Base64.cxx:218
int base64_encode(char *dest, int size, unsigned char *src, int slen)
Definition Base64.cxx:52
char * base64_enc_malloc(unsigned char *src, int slen)
Definition Base64.cxx:103
int base64_decode(unsigned char *dest, int size, char *src)
Definition Base64.cxx:144