AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Acore::Impl::GenericBaseEncoding< Encoding > Struct Template Reference

#include "BaseEncoding.h"

Static Public Member Functions

static constexpr std::size_t EncodedSize (std::size_t size)
 
static constexpr std::size_t DecodedSize (std::size_t size)
 
static std::string Encode (std::vector< uint8 > const &data)
 
static Optional< std::vector< uint8 > > Decode (std::string const &data)
 

Static Public Attributes

static constexpr std::size_t BITS_PER_CHAR = Encoding::BITS_PER_CHAR
 
static constexpr std::size_t PAD_TO = std::lcm(8u, BITS_PER_CHAR)
 
static constexpr uint8 DECODE_ERROR = Encoding::DECODE_ERROR
 
static constexpr char PADDING = Encoding::PADDING
 

Detailed Description

template<typename Encoding>
struct Acore::Impl::GenericBaseEncoding< Encoding >

Member Function Documentation

◆ Decode()

template<typename Encoding >
static Optional< std::vector< uint8 > > Acore::Impl::GenericBaseEncoding< Encoding >::Decode ( std::string const &  data)
inlinestatic
102 {
103 auto it = data.begin(), end = data.end();
104 if (it == end)
105 {
106 return std::vector<uint8>();
107 }
108
109 std::vector<uint8> v;
110 v.reserve(DecodedSize(data.size()));
111
112 uint8 currentByte = 0;
113 uint8 bitsLeft = 8; // in current byte
114 while ((it != end) && (*it != PADDING))
115 {
116 uint8 cur = Encoding::Decode(*(it++));
117 if (cur == DECODE_ERROR)
118 return {};
119
120 if (bitsLeft > BITS_PER_CHAR)
121 {
122 bitsLeft -= BITS_PER_CHAR;
123 currentByte |= (cur << bitsLeft);
124 }
125 else
126 {
127 bitsLeft = BITS_PER_CHAR - bitsLeft; // in encoded char
128 currentByte |= (cur >> bitsLeft);
129 v.push_back(currentByte);
130 currentByte = (cur & ((1 << bitsLeft) - 1));
131 bitsLeft = 8 - bitsLeft; // in byte again
132 currentByte <<= bitsLeft;
133 }
134 }
135
136 if (currentByte)
137 return {}; // decode error, trailing non-zero bits
138
139 // process padding
140 while ((it != end) && (*it == PADDING) && (bitsLeft != 8))
141 {
142 if (bitsLeft > BITS_PER_CHAR)
143 {
144 bitsLeft -= BITS_PER_CHAR;
145 }
146 else
147 {
148 bitsLeft += (8 - BITS_PER_CHAR);
149 }
150 ++it;
151 }
152
153 // ok, all padding should be consumed, and we should be at end of string
154 if (it == end)
155 {
156 return v;
157 }
158
159 // anything else is an error
160 return {};
161 }
std::uint8_t uint8
Definition: Define.h:110
static constexpr std::size_t BITS_PER_CHAR
Definition: BaseEncoding.h:20
static constexpr char PADDING
Definition: BaseEncoding.h:26
static constexpr uint8 DECODE_ERROR
Definition: BaseEncoding.h:25
static constexpr std::size_t DecodedSize(std::size_t size)
Definition: BaseEncoding.h:38

References Acore::Impl::GenericBaseEncoding< Encoding >::BITS_PER_CHAR, Acore::Impl::GenericBaseEncoding< Encoding >::DECODE_ERROR, Acore::Impl::GenericBaseEncoding< Encoding >::DecodedSize(), and Acore::Impl::GenericBaseEncoding< Encoding >::PADDING.

Referenced by Acore::Encoding::Base32::Decode(), and Acore::Encoding::Base64::Decode().

◆ DecodedSize()

template<typename Encoding >
static constexpr std::size_t Acore::Impl::GenericBaseEncoding< Encoding >::DecodedSize ( std::size_t  size)
inlinestaticconstexpr
39 {
40 size *= BITS_PER_CHAR; // bits in input
41 if (size % PAD_TO) // pad to boundary
42 {
43 size += (PAD_TO - (size % PAD_TO));
44 }
45 return (size / 8);
46 }
static constexpr std::size_t PAD_TO
Definition: BaseEncoding.h:21

References Acore::Impl::GenericBaseEncoding< Encoding >::BITS_PER_CHAR, and Acore::Impl::GenericBaseEncoding< Encoding >::PAD_TO.

Referenced by Acore::Impl::GenericBaseEncoding< Encoding >::Decode().

◆ Encode()

template<typename Encoding >
static std::string Acore::Impl::GenericBaseEncoding< Encoding >::Encode ( std::vector< uint8 > const &  data)
inlinestatic
49 {
50 auto it = data.begin(), end = data.end();
51 if (it == end)
52 {
53 return "";
54 }
55
56 std::string s;
57 s.reserve(EncodedSize(data.size()));
58
59 uint8 bitsLeft = 8; // in current byte
60 do
61 {
62 uint8 thisC = 0;
63 if (bitsLeft >= BITS_PER_CHAR)
64 {
65 bitsLeft -= BITS_PER_CHAR;
66 thisC = ((*it >> bitsLeft) & ((1 << BITS_PER_CHAR) - 1));
67 if (!bitsLeft)
68 {
69 ++it;
70 bitsLeft = 8;
71 }
72 }
73 else
74 {
75 thisC = (*it & ((1 << bitsLeft) - 1)) << (BITS_PER_CHAR - bitsLeft);
76 bitsLeft += (8 - BITS_PER_CHAR);
77 if ((++it) != end)
78 {
79 thisC |= (*it >> bitsLeft);
80 }
81 }
82 s.append(1, Encoding::Encode(thisC));
83 } while (it != end);
84
85 while (bitsLeft != 8)
86 {
87 if (bitsLeft > BITS_PER_CHAR)
88 {
89 bitsLeft -= BITS_PER_CHAR;
90 }
91 else
92 {
93 bitsLeft += (8 - BITS_PER_CHAR);
94 }
95 s.append(1, PADDING);
96 }
97
98 return s;
99 }
static constexpr std::size_t EncodedSize(std::size_t size)
Definition: BaseEncoding.h:28

References Acore::Impl::GenericBaseEncoding< Encoding >::BITS_PER_CHAR, Acore::Impl::GenericBaseEncoding< Encoding >::EncodedSize(), and Acore::Impl::GenericBaseEncoding< Encoding >::PADDING.

Referenced by Acore::Encoding::Base32::Encode(), and Acore::Encoding::Base64::Encode().

◆ EncodedSize()

template<typename Encoding >
static constexpr std::size_t Acore::Impl::GenericBaseEncoding< Encoding >::EncodedSize ( std::size_t  size)
inlinestaticconstexpr
29 {
30 size *= 8; // bits in input
31 if (size % PAD_TO) // pad to boundary
32 {
33 size += (PAD_TO - (size % PAD_TO));
34 }
35 return (size / BITS_PER_CHAR);
36 }

References Acore::Impl::GenericBaseEncoding< Encoding >::BITS_PER_CHAR, and Acore::Impl::GenericBaseEncoding< Encoding >::PAD_TO.

Referenced by Acore::Impl::GenericBaseEncoding< Encoding >::Encode().

Member Data Documentation

◆ BITS_PER_CHAR

◆ DECODE_ERROR

template<typename Encoding >
constexpr uint8 Acore::Impl::GenericBaseEncoding< Encoding >::DECODE_ERROR = Encoding::DECODE_ERROR
staticconstexpr

◆ PAD_TO

template<typename Encoding >
constexpr std::size_t Acore::Impl::GenericBaseEncoding< Encoding >::PAD_TO = std::lcm(8u, BITS_PER_CHAR)
staticconstexpr

◆ PADDING

template<typename Encoding >
constexpr char Acore::Impl::GenericBaseEncoding< Encoding >::PADDING = Encoding::PADDING
staticconstexpr