OGLplus  (0.59.0) a C++ wrapper for rendering APIs

base64.hpp
Go to the documentation of this file.
1 
9 #ifndef EAGINE_BASE64_HPP
10 #define EAGINE_BASE64_HPP
11 
12 #include "bit_density.hpp"
13 #include "optional_ref.hpp"
14 #include "span.hpp"
15 #include "valid_if/always.hpp"
16 
17 namespace eagine {
18 //------------------------------------------------------------------------------
19 static constexpr auto make_base64_encode_transform() {
20  return [](byte b) -> always_valid<char> {
21  const auto i = int(b);
22  if(i < 26) {
23  return {char('A' + i)};
24  }
25  if(i < 52) {
26  return {char('a' + i - 26)};
27  }
28  if(i < 62) {
29  return {char('0' + i - 52)};
30  }
31  if(i == 62) {
32  return {'+'};
33  }
34  if(i == 63) {
35  return {'/'};
36  }
37  return {'='};
38  };
39 }
40 //------------------------------------------------------------------------------
41 static constexpr auto make_base64_decode_transform() {
42  return [](char c) -> optionally_valid<byte> {
43  if((c >= 'A') && (c <= 'Z')) {
44  return {byte(c - 'A'), true};
45  }
46  if((c >= 'a') && (c <= 'z')) {
47  return {byte(c - 'a' + 26), true};
48  }
49  if((c >= '0') && (c <= '9')) {
50  return {byte(c - '0' + 52), true};
51  }
52  if(c == '+') {
53  return {byte(62), true};
54  }
55  if(c == '/') {
56  return {byte(63), true};
57  }
58  return {};
59  };
60 }
61 //------------------------------------------------------------------------------
62 static inline auto base64_encoded_length(span_size_t orig_size) noexcept {
63  return dissolved_bits_length(orig_size, 6);
64 }
65 //------------------------------------------------------------------------------
66 static inline auto base64_decoded_length(span_size_t orig_size) noexcept {
67  return concentrated_bits_length(orig_size, 6);
68 }
69 //------------------------------------------------------------------------------
70 template <typename Ps, typename Ss, typename Pd, typename Sd>
71 static inline auto base64_encode(
72  memory::basic_span<const byte, Ps, Ss> src,
73  memory::basic_span<char, Pd, Sd> dst) -> memory::basic_span<char, Pd, Sd> {
74  span_size_t i = 0;
75  span_size_t o = 0;
76 
77  if(do_dissolve_bits(
78  make_span_getter(i, src),
79  make_span_putter(o, dst, make_base64_encode_transform()),
80  6)) {
81  return head(dst, o);
82  }
83  return {};
84 }
85 //------------------------------------------------------------------------------
86 template <typename P, typename S, typename Dst>
87 static inline auto
88 base64_encode(memory::basic_span<const byte, P, S> src, Dst& dst)
89  -> optional_reference_wrapper<Dst> {
90  using Ds = typename Dst::size_type;
91  dst.resize(Ds(base64_encoded_length(src.size())));
92  span_size_t i = 0;
93  span_size_t o = 0;
94 
95  if(do_dissolve_bits(
96  make_span_getter(i, src),
97  make_span_putter(o, dst, make_base64_encode_transform()),
98  6)) {
99  dst.resize(Ds(o));
100  return {dst};
101  }
102  return {nothing};
103 }
104 //------------------------------------------------------------------------------
105 template <typename Ps, typename Ss, typename Pd, typename Sd>
106 static inline auto base64_decode(
107  memory::basic_span<const char, Ps, Ss> src,
108  memory::basic_span<byte, Pd, Sd> dst) -> memory::basic_span<byte, Pd, Sd> {
109  span_size_t i = 0;
110  span_size_t o = 0;
111 
112  if(do_concentrate_bits(
113  make_span_getter(i, src, make_base64_decode_transform()),
114  make_span_putter(o, dst),
115  6)) {
116  return head(dst, o);
117  }
118  return {};
119 }
120 //------------------------------------------------------------------------------
121 template <typename P, typename S, typename Dst>
122 static inline auto
123 base64_decode(memory::basic_span<const char, P, S> src, Dst& dst)
124  -> optional_reference_wrapper<Dst> {
125  using Ds = typename Dst::size_type;
126  dst.resize(Ds(base64_decoded_length(src.size())));
127  span_size_t i = 0;
128  span_size_t o = 0;
129 
130  if(do_concentrate_bits(
131  make_span_getter(i, src, make_base64_decode_transform()),
132  make_span_putter(o, dst),
133  6)) {
134  dst.resize(Ds(o));
135  return {dst};
136  }
137  return {nothing};
138 }
139 //------------------------------------------------------------------------------
140 } // namespace eagine
141 #endif // EAGINE_BASE64_HPP
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
Common code is placed in this namespace.
Definition: eagine.hpp:21
static constexpr auto head(basic_span< T, P, S > s, L l) noexcept -> basic_span< T, P, S >
Returns the first l elements from the front of a span.
Definition: span_algo.hpp:99
unsigned char byte
Byte type alias.
Definition: types.hpp:24
static constexpr nothing_t nothing
Constant of nothing_t type.
Definition: nothing.hpp:30

Copyright © 2015-2021 Matúš Chochlík.
<chochlik -at -gmail.com>
Documentation generated on Tue Apr 13 2021 by Doxygen (version 1.8.17).