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
114 {
115 auto it = data.begin(), end = data.end();
116 if (it == end)
117 {
118 return std::vector<uint8>();
119 }
120
121 std::vector<uint8> v;
122 v.reserve(DecodedSize(data.size()));
123
124 uint8 currentByte = 0;
125 uint8 bitsLeft = 8; // in current byte
126 while ((it != end) && (*it != PADDING))
127 {
128 uint8 cur = Encoding::Decode(*(it++));
129 if (cur == DECODE_ERROR)
130 return {};
131
132 if (bitsLeft > BITS_PER_CHAR)
133 {
134 bitsLeft -= BITS_PER_CHAR;
135 currentByte |= (cur << bitsLeft);
136 }
137 else
138 {
139 bitsLeft = BITS_PER_CHAR - bitsLeft; // in encoded char
140 currentByte |= (cur >> bitsLeft);
141 v.push_back(currentByte);
142 currentByte = (cur & ((1 << bitsLeft) - 1));
143 bitsLeft = 8 - bitsLeft; // in byte again
144 currentByte <<= bitsLeft;
145 }
146 }
147
148 if (currentByte)
149 return {}; // decode error, trailing non-zero bits
150
151 // process padding
152 while ((it != end) && (*it == PADDING) && (bitsLeft != 8))
153 {
154 if (bitsLeft > BITS_PER_CHAR)
155 {
156 bitsLeft -= BITS_PER_CHAR;
157 }
158 else
159 {
160 bitsLeft += (8 - BITS_PER_CHAR);
161 }
162 ++it;
163 }
164
165 // ok, all padding should be consumed, and we should be at end of string
166 if (it == end)
167 {
168 return v;
169 }
170
171 // anything else is an error
172 return {};
173 }
std::uint8_t uint8
Definition: Define.h:110
static constexpr std::size_t BITS_PER_CHAR
Definition: BaseEncoding.h:32
static constexpr char PADDING
Definition: BaseEncoding.h:38
static constexpr uint8 DECODE_ERROR
Definition: BaseEncoding.h:37
static constexpr std::size_t DecodedSize(std::size_t size)
Definition: BaseEncoding.h:50

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
51 {
52 size *= BITS_PER_CHAR; // bits in input
53 if (size % PAD_TO) // pad to boundary
54 {
55 size += (PAD_TO - (size % PAD_TO));
56 }
57 return (size / 8);
58 }
static constexpr std::size_t PAD_TO
Definition: BaseEncoding.h:33

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
61 {
62 auto it = data.begin(), end = data.end();
63 if (it == end)
64 {
65 return "";
66 }
67
68 std::string s;
69 s.reserve(EncodedSize(data.size()));
70
71 uint8 bitsLeft = 8; // in current byte
72 do
73 {
74 uint8 thisC = 0;
75 if (bitsLeft >= BITS_PER_CHAR)
76 {
77 bitsLeft -= BITS_PER_CHAR;
78 thisC = ((*it >> bitsLeft) & ((1 << BITS_PER_CHAR) - 1));
79 if (!bitsLeft)
80 {
81 ++it;
82 bitsLeft = 8;
83 }
84 }
85 else
86 {
87 thisC = (*it & ((1 << bitsLeft) - 1)) << (BITS_PER_CHAR - bitsLeft);
88 bitsLeft += (8 - BITS_PER_CHAR);
89 if ((++it) != end)
90 {
91 thisC |= (*it >> bitsLeft);
92 }
93 }
94 s.append(1, Encoding::Encode(thisC));
95 } while (it != end);
96
97 while (bitsLeft != 8)
98 {
99 if (bitsLeft > BITS_PER_CHAR)
100 {
101 bitsLeft -= BITS_PER_CHAR;
102 }
103 else
104 {
105 bitsLeft += (8 - BITS_PER_CHAR);
106 }
107 s.append(1, PADDING);
108 }
109
110 return s;
111 }
static constexpr std::size_t EncodedSize(std::size_t size)
Definition: BaseEncoding.h:40

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
41 {
42 size *= 8; // bits in input
43 if (size % PAD_TO) // pad to boundary
44 {
45 size += (PAD_TO - (size % PAD_TO));
46 }
47 return (size / BITS_PER_CHAR);
48 }

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