This repository was archived by the owner on Feb 28, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommon.hpp
More file actions
144 lines (122 loc) · 4.53 KB
/
Copy pathcommon.hpp
File metadata and controls
144 lines (122 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#pragma once
#pragma push_macro("BIZWEN_EXPORT")
#undef BIZWEN_EXPORT
#if !defined(BIZWEN_MODULE)
#define BIZWEN_EXPORT
#include <climits>
#include <memory> // std::to_address
#include <tuple>
#include <type_traits> // std::remove_reference
#else
#define BIZWEN_EXPORT export
#endif
static_assert(CHAR_BIT == 8);
namespace bizwen
{
BIZWEN_EXPORT enum class rfc4648_kind : unsigned char
{
base64,
base64_url,
base32,
base32_lower,
base32_mixed,
base32_hex,
base32_hex_lower,
base32_hex_mixed,
base32_crockford,
base32_crockford_lower,
base32_crockford_mixed,
base16,
base16_lower,
base16_mixed,
hex = base16,
hex_lower = base16_lower,
hex_mixed = base16_mixed
};
namespace detail
{
template <typename T>
auto to_address_const(T t)
{
auto ptr = std::to_address(t);
using const_pointer = std::add_const_t<std::remove_reference_t<decltype(*t)>> *;
return const_pointer(ptr);
}
template <rfc4648_kind Kind>
inline consteval auto get_family()
{
if constexpr (Kind == rfc4648_kind::base64 || Kind == rfc4648_kind::base64_url)
return rfc4648_kind::base64;
if constexpr (Kind == rfc4648_kind::base16 || Kind == rfc4648_kind::base16_lower ||
Kind == rfc4648_kind::base16_mixed)
return rfc4648_kind::base16;
else
return rfc4648_kind::base32;
}
using buf_ref = unsigned char (&)[4];
using sig_ref = unsigned char &;
} // namespace detail
BIZWEN_EXPORT template <typename End, typename Out>
struct rfc4648_decode_result
{
End end;
Out out;
operator std::tuple<End &, Out &>() && noexcept
{
return {end, out};
}
};
BIZWEN_EXPORT class rfc4648_context
{
// 0 - 2 for base64 encode, buf_[0 - 2] is significant
// 0 - 4 for base32 encode, buf_[0 - 4] is significant
// base16 encoding does not need ctx
// 0 - 4 for base64 decode, only buf_[0] is significant
// 0 - 8 for base32 decode, only buf_[0] is significant
// 0 - 2 for base16 decode, only buf_[0] is significant
alignas(int) unsigned char sig_{};
alignas(int) unsigned char buf_[4];
template <rfc4648_kind Kind, bool Padding, typename In, typename Out>
friend inline constexpr Out rfc4648_encode(In begin, In end, Out first);
template <rfc4648_kind Kind, bool Padding, typename R, typename Out>
friend inline constexpr Out rfc4648_encode(R &&r, Out first);
template <rfc4648_kind Kind, typename In, typename Out>
friend inline constexpr Out rfc4648_encode(rfc4648_context &ctx, In begin, In end, Out first);
template <rfc4648_kind Kind, typename R, typename Out>
friend inline constexpr Out rfc4648_encode(rfc4648_context &ctx, R &&r, Out first);
template <rfc4648_kind Kind, bool Padding, typename Out>
friend inline constexpr Out rfc4648_encode(rfc4648_context &ctx, Out first);
template <rfc4648_kind Kind, bool Padding, typename In, typename Out>
friend inline constexpr rfc4648_decode_result<In, Out> rfc4648_decode(In begin, In end, Out first);
template <rfc4648_kind Kind, bool Padding, typename R, typename Out>
friend inline constexpr auto rfc4648_decode(R &&r, Out first);
template <rfc4648_kind Kind, typename In, typename Out>
friend inline constexpr rfc4648_decode_result<In, Out> rfc4648_decode(rfc4648_context &ctx, In begin, In end,
Out first);
template <rfc4648_kind Kind, typename R, typename Out>
friend inline constexpr auto rfc4648_decode(rfc4648_context &ctx, R &&r, Out first);
template <rfc4648_kind Kind, bool Padding, typename In>
friend inline constexpr In rfc4648_decode(rfc4648_context &ctx, In begin, In end);
};
BIZWEN_EXPORT template <rfc4648_kind Kind = rfc4648_kind::base64>
inline constexpr std::size_t rfc4648_encode_length(std::size_t input) noexcept
{
if constexpr (detail::get_family<Kind>() == rfc4648_kind::base64)
return (input + 5) / 6 * 8;
else if constexpr (detail::get_family<Kind>() == rfc4648_kind::base32)
return (input + 4) / 5 * 8;
else
return (input + 3) / 4 * 8;
}
BIZWEN_EXPORT template <rfc4648_kind Kind = rfc4648_kind::base64>
inline constexpr std::size_t rfc4648_decode_length(std::size_t input) noexcept
{
if constexpr (detail::get_family<Kind>() == rfc4648_kind::base64)
return (input + 7) / 8 * 6;
else if constexpr (detail::get_family<Kind>() == rfc4648_kind::base32)
return (input + 7) / 8 * 5;
else
return (input + 7) / 8 * 4;
}
} // namespace bizwen
#pragma pop_macro("BIZWEN_EXPORT")