Qx v0.5.7
Qt Extensions Library
Loading...
Searching...
No Matches
qx-base85.h
1#ifndef QX_BASE85_H
2#define QX_BASE85_H
3
4// Shared Lib Support
5#include "qx/core/qx_core_export.h"
6
7// Inner-component Includes
8#include "qx/core/qx-char.h"
9
10// Extra-component Includes
12
13// Standard Library Includes
14#include <array>
15
16// Qt Includes
17#include <QString>
18#include <QHash>
19#include <QSet>
20
21using namespace Qt::Literals::StringLiterals;
22
23namespace Qx
24{
25
26class QX_CORE_EXPORT Base85Encoding
27{
28//-Class Enum-----------------------------------------------------------------------------------------------------------
29public:
37
38//-Class Variables------------------------------------------------------------------------------------------------------
39private:
40 // Character Sets
41 static constexpr std::array<char, 85> CHAR_SET_DEFAULT = [](){
42 std::array<char, 85> arr;
43 arr.fill(0);
44 return arr;
45 }();
46 static constexpr std::array<char, 85> CHAR_SET_ORIGINAL = [](){
47 char asciiValue = 0x21; // Original set starts at '!'
48 std::array<char, 85> arr;
49 for(auto itr = arr.begin(); itr != arr.end(); itr++)
50 *itr = asciiValue++; // Insert current char, then increment to the next one
51 return arr;
52 }();
53 static constexpr std::array<char, 85> CHAR_SET_Z85{
54 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
55 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
56 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
57 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
58 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
59 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
60 'Y', 'Z', '.', '-', ':', '+', '=', '^', '!', '/',
61 '*', '?', '&', '<', '>', '(', ')', '[', ']', '{',
62 '}', '@', '%', '$', '#'
63 };
64 static constexpr std::array<char, 85> CHAR_SET_RFC_1924{
65 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
66 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
67 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
68 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
69 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
70 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
71 'y', 'z', '!', '#', '$', '%', '&', '(', ')', '*',
72 '+', '-', ';', '<', '=', '>', '?', '@', '^', '_',
73 '`', '{', '|', '}', '~'
74 };
75 static constexpr char ZERO_GROUP_CHAR_ORIGINAL = 'z';
76 static constexpr char SPACE_GROUP_CHAR_ORIGINAL = 'y';
77
78 // Encodings
79 static inline QHash<StandardEncoding, Base85Encoding> smStdEncodings;
80
81 // Characters
82 static inline const QSet<char> ILLEGAL_CHAR_SET = {'\x09', '\x0A', '\x0B', '\x0C', '\x0D', '\x20'};
83
84//-Instance Variables------------------------------------------------------------------------------------------------------------
85private:
86 bool mValid;
87 std::array<char, 85> mCharSet;
88 QHash<char, int> mDecodeMap;
89 std::optional<char> mZeroGroupChar;
90 std::optional<char> mSpaceGroupChar;
91 bool mHandlePadding;
92
93//-Constructor-------------------------------------------------------------------------------------------------
94public:
95 Base85Encoding();
96 Base85Encoding(StandardEncoding enc);
97
98//-Class Functions---------------------------------------------------------------------------------------------------------
99private:
100 static const QHash<char, int>& decodeMapOriginalSet();
101 static const QHash<char, int>& decodeMapZ85Set();
102 static const QHash<char, int>& decodeMapRfc1924Set();
103public:
104 static bool characterIsLegal(char ch);
105 static const Base85Encoding* encodingFromStandard(StandardEncoding enc);
106
107//-Instance Functions---------------------------------------------------------------------------------------------------------
108private:
109 void generateDecodeMap();
110 void evaluateValidity();
111
112public:
113 bool isValid() const;
114 const std::array<char, 85>& characterSet() const;
115 std::optional<char> zeroGroupCharacter() const;
116 std::optional<char> spaceGroupCharacter() const;
117 bool isHandlePadding() const;
118 bool usesZeroGroupShortcut() const;
119 bool usesSpaceGroupShortcut() const;
120
121 char characterAt(int i) const;
122 int characterPosition(char ch) const;
123 bool containsCharacter(char ch, bool shortcut = true) const;
124
125 void setCharacterSet(const std::array<char, 85>& set);
126 void setZeroGroupCharacter(const char& ch);
127 void setSpaceGroupCharacter(const char& ch);
128 void resetZeroGroupCharacter();
129 void resetSpaceGroupCharacter();
130 void setHandlePadding(bool handlePadding);
131
132 bool operator==(const Base85Encoding& other) const;
133 bool operator!=(const Base85Encoding& other) const;
134};
135
136class QX_CORE_EXPORT Base85ParseError
137{
138//-Class Enum-----------------------------------------------------------------------------------------------------------
139public:
148
149//-Class Variables------------------------------------------------------------------------------------------------------
150private:
151 static inline const QHash<ParseError, QString> ERROR_STR_MAP{
152 {NoError, u"No error occurred."_s},
153 {InvalidEncoding, u"The provided encoding is invalid."_s},
154 {PaddingRequired, u"The string makes use of padding, but the specified encoding does not support padding."_s},
155 {NonANSI, u"The string contains characters that are wider than a single byte."_s},
156 {CharacterSetMismatch, u"The string contains characters that are not present in the specified encoding's character set."_s},
157 {ShortcutMidFrame, u"A shortcut character appears in the middle of one of the string's 5-character ASCII frames."_s},
158 };
159
160//-Instance Variables------------------------------------------------------------------------------------------------------------
161private:
162 ParseError mError;
163 qsizetype mOffset;
164
165//-Constructor-------------------------------------------------------------------------------------------------
166public:
167 Base85ParseError();
168 Base85ParseError(ParseError error, qsizetype offset);
169
170//-Instance Functions---------------------------------------------------------------------------------------------------------
171public:
172 ParseError error() const;
173 QString errorString() const;
174 qsizetype offset() const;
175};
176
177class QX_CORE_EXPORT Base85
178{
179//-Class Variables------------------------------------------------------------------------------------------------------
180private:
181 // Padding
182 static constexpr char ENCODE_PAD_CHAR = '\0';
183
184 // Shortcut Frames
185 static inline const QByteArray ZERO_GROUP_FRAME = "\x00\x00\x00\x00"_ba;
186 static inline const QByteArray SPACE_GROUP_FRAME = "\x20\x20\x20\x20"_ba;
187
188 // Decode
189 static constexpr quint32 POWERS_OF_85[] = {
190 1,
191 85,
192 85 * 85,
193 85 * 85 * 85,
194 85 * 85 * 85 * 85,
195 };
196
197//-Instance Variables------------------------------------------------------------------------------------------------------------
198private:
199 const Base85Encoding* mEncoding;
200 QByteArray mEncoded;
201
202//-Constructor-------------------------------------------------------------------------------------------------
203private:
204 Base85(QByteArray data, const Base85Encoding* enc);
205
206public:
207 Base85();
208
209//-Class Functions---------------------------------------------------------------------------------------------------------
210private:
211 static void encodeData(const QByteArray& data, Base85& encoded);
212 static QByteArray encodeFrame(const QByteArray& frame, const Base85Encoding* encoding);
213 static void decodeData(const QByteArray& data, QByteArray& decodedData, const Base85Encoding* encoding);
214 static QByteArray decodeFrame(const QByteArray& frame, const Base85Encoding* encoding);
215
216 // External parse helpers
217 static char charToLatin1(char ch);
218 static char charToLatin1(QChar ch);
219
220 // External parse
221 template<typename D>
223 static Base85 fromExternal(D base85, const Base85Encoding* enc, Base85ParseError* error);
224
225 template<typename D>
227 static Base85ParseError parseExternal(D base85, Base85& externallyEncoded);
228
229public:
230 static Base85 fromEncoded(QAnyStringView base85, const Base85Encoding* enc, Base85ParseError* error = nullptr);
231 static Base85 encode(const QByteArray& data, const Base85Encoding* enc);
232
233//-Instance Functions---------------------------------------------------------------------------------------------------------
234public:
235 bool isNull();
236 bool isEmpty();
237
238 const Base85Encoding* encoding() const;
239
240 QByteArray decode();
241 QString toString();
242 QByteArrayView data() const;
243 qsizetype size() const;
244
245 bool operator==(const Base85& other) const;
246 bool operator!=(const Base85& other) const;
247};
248
249}
250#endif // QX_BASE85_H
The Base85Encoding class provides the parameters of a particular Base85 string encoding.
Definition qx-base85.h:27
StandardEncoding
Definition qx-base85.h:30
@ Adobe
Definition qx-base85.h:33
@ Btoa_4_2
Definition qx-base85.h:32
@ Btoa
Definition qx-base85.h:31
@ Z85
Definition qx-base85.h:34
The Base85ParseError class is used to report errors while parsing a Base85 encoded string.
Definition qx-base85.h:137
ParseError
Definition qx-base85.h:140
@ ShortcutMidFrame
Definition qx-base85.h:146
@ InvalidEncoding
Definition qx-base85.h:142
@ CharacterSetMismatch
Definition qx-base85.h:145
@ NonANSI
Definition qx-base85.h:144
@ NoError
Definition qx-base85.h:141
@ PaddingRequired
Definition qx-base85.h:143
The Base85 class provides a Base85 encoded string.
Definition qx-base85.h:178
Specifies that a type is one of several types.
Definition qx-concepts.h:513
The Qx namespace is the main namespace through which all non-global functionality of the Qx library i...
Definition qx-processwaiter.cpp:5
bool operator==(const FileDetails::Translation &lhs, const FileDetails::Translation &rhs) noexcept
Definition qx-filedetails.cpp:85
The qx-concepts header file provides a library of general purpose concepts as an extension of the sta...