1 #ifndef SRC_BASE64_H_
2 #define SRC_BASE64_H_
3
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6 #include "util.h"
7
8 #include <cmath>
9 #include <cstddef>
10 #include <cstdint>
11
12 namespace node {
13 //// Base 64 ////
14
15 enum class Base64Mode {
16 NORMAL,
17 URL
18 };
19
20 static constexpr char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
21 "abcdefghijklmnopqrstuvwxyz"
22 "0123456789+/";
23
24 static constexpr char base64_table_url[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
25 "abcdefghijklmnopqrstuvwxyz"
26 "0123456789-_";
27
base64_select_table(Base64Mode mode)28 static inline const char* base64_select_table(Base64Mode mode) {
29 switch (mode) {
30 case Base64Mode::NORMAL: return base64_table;
31 case Base64Mode::URL: return base64_table_url;
32 default: UNREACHABLE();
33 }
34 }
35
36 static inline constexpr size_t base64_encoded_size(
37 size_t size,
38 Base64Mode mode = Base64Mode::NORMAL) {
39 return mode == Base64Mode::NORMAL
40 ? ((size + 2) / 3 * 4)
41 : std::ceil(static_cast<double>(size * 4) / 3);
42 }
43
44 // Doesn't check for padding at the end. Can be 1-2 bytes over.
base64_decoded_size_fast(size_t size)45 static inline constexpr size_t base64_decoded_size_fast(size_t size) {
46 // 1-byte input cannot be decoded
47 return size > 1 ? (size / 4) * 3 + (size % 4 + 1) / 2 : 0;
48 }
49
50 inline uint32_t ReadUint32BE(const unsigned char* p);
51
52 template <typename TypeName>
53 size_t base64_decoded_size(const TypeName* src, size_t size);
54
55 template <typename TypeName>
56 size_t base64_decode(char* const dst, const size_t dstlen,
57 const TypeName* const src, const size_t srclen);
58
59 inline size_t base64_encode(const char* src,
60 size_t slen,
61 char* dst,
62 size_t dlen,
63 Base64Mode mode = Base64Mode::NORMAL);
64 } // namespace node
65
66
67 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
68
69 #endif // SRC_BASE64_H_
70