66#include "TTauri/Foundation/required.hpp"
67#include "TTauri/Foundation/throw_exception.hpp"
68#include "TTauri/Foundation/bigint.hpp"
78[[nodiscard]]
constexpr uint16_t
tt5_code(uint16_t page, uint16_t prefix, uint16_t value)
80 return (page << 10) | (prefix << 5) | value;
90 case '_':
return tt5_code(3, 0, 0x1b);
91 case '.':
return tt5_code(3, 0, 0x1c);
92 case '-':
return tt5_code(3, 0, 0x1d);
93 case ',':
return tt5_code(2, 0, 0x0b);
94 case ':':
return tt5_code(2, 0, 0x0c);
95 case ';':
return tt5_code(2, 0, 0x0d);
96 case '/':
return tt5_code(2, 0, 0x0e);
97 case '\n':
return tt5_code(2, 0, 0x0f);
99 if (c >=
'a' && c <=
'z') {
100 return tt5_code(0, 0, (c -
'a') + 1);
101 }
else if (c >=
'A' && c <=
'Z') {
102 return tt5_code(1, 0, (c -
'A') + 1);
103 }
else if (c >=
'0' && c <=
'9') {
104 return tt5_code(2, 0, (c -
'0') + 1);
106 auto c_ =
static_cast<uint16_t
>(c);
107 return tt5_code(2, 0x10 | (c_ >> 5), (c_ & 0x1f));
112constexpr auto tt5_code_table_generator() noexcept
116 for (ssize_t i = 0; i != ssize(r); ++i) {
123constexpr auto tt5_code_table = tt5_code_table_generator();
125constexpr uint64_t tt5_code_from_char(uint8_t c)
noexcept
127 return static_cast<uint64_t
>(tt5_code_table[c]) << 48;
134constexpr ssize_t tt5_add_code(T &r, uint16_t code)
noexcept
139 ssize_t nr_bits =
static_cast<bool>(code >> 5) ? 10 : 5;
142 r <<= static_cast<unsigned int>(nr_bits);
158 ttlet next_page = ring & 3;
161 for (
int i = 0; i != 3; ++i) {
163 ttlet later_page = ring & 3;
164 r = r && (later_page == 3 || later_page == next_page);
179 constexpr ssize_t max_nr_bits =
sizeof (T) * CHAR_BIT;
180 uint64_t locked_page = 0;
184 uint64_t later_code = 1;
185 for (
int i = 0; i != 4; ++i) {
186 later_code = (later_code) ? tt5_code_from_char(*(str++)) : 0;
192 ttlet next_page = (ring >> 10) & 3;
194 if (next_page != 3 && next_page != locked_page) {
196 if (locked_page != 2) {
199 _parse_assert2((nr_bits += 5) <= max_nr_bits,
"String too long");
203 r |= 0x18 + next_page;
204 _parse_assert2((nr_bits += 5) <= max_nr_bits,
"String too long");
206 locked_page = next_page;
209 bool second_shift = (locked_page == 0 && next_page == 2) || (locked_page != 0 && next_page != 0);
212 r |= 0x1e +
static_cast<int>(second_shift);
213 _parse_assert2((nr_bits += 5) <= max_nr_bits,
"String too long");
217 nr_bits += tt5_add_code(r,
static_cast<uint16_t
>(ring));
218 _parse_assert2(nr_bits <= max_nr_bits,
"String too long");
221 later_code = (later_code) ? tt5_code_from_char(*(str++)) : 0;
237 return tt5_encode<T>(s.
data());
260[[nodiscard]]
constexpr uint8_t char_from_tt5_page0(
char *&str, uint8_t code, uint8_t locked_page)
noexcept
263 case 0x00: *(str++) = 0;
return locked_page;
264 case 0x1b: *(str++) =
'_';
return locked_page;
265 case 0x1c: *(str++) =
'.';
return locked_page;
266 case 0x1d: *(str++) =
'-';
return locked_page;
270 *(str++) = (
static_cast<char>(code) - 1) +
'a';
275[[nodiscard]]
constexpr uint8_t char_from_tt5_page1(
char *&str, uint8_t code, uint8_t locked_page)
noexcept
278 case 0x00: *(str++) = 0;
return locked_page;
279 case 0x1b: *(str++) =
'_';
return locked_page;
280 case 0x1c: *(str++) =
'.';
return locked_page;
281 case 0x1d: *(str++) =
'-';
return locked_page;
285 *(str++) = (
static_cast<char>(code) - 1) +
'A';
290[[nodiscard]]
constexpr uint8_t char_from_tt5_page2(
char *&str, uint8_t code, uint8_t &locked_page)
noexcept
293 case 0x00: *(str++) = 0;
return locked_page;
294 case 0x0b: *(str++) =
',';
return locked_page;
295 case 0x0c: *(str++) =
':';
return locked_page;
296 case 0x0d: *(str++) =
';';
return locked_page;
297 case 0x0e: *(str++) =
'/';
return locked_page;
298 case 0x0f: *(str++) =
'\n';
return locked_page;
299 case 0x10:
return 0x03;
300 case 0x11:
return 0x13;
301 case 0x12:
return 0x23;
302 case 0x13:
return 0x33;
303 case 0x14:
return 0x43;
304 case 0x15:
return 0x53;
305 case 0x16:
return 0x63;
306 case 0x17:
return 0x73;
307 case 0x18:
return locked_page = 0;
308 case 0x19:
return locked_page = 1;
309 case 0x1a:
return locked_page = 2;
310 case 0x1b: *(str++) =
'_';
return locked_page;
311 case 0x1c: *(str++) =
'.';
return locked_page;
312 case 0x1d: *(str++) =
'-';
return locked_page;
316 *(str++) = (
static_cast<char>(code) - 1) +
'0';
321[[nodiscard]]
constexpr uint8_t char_from_tt5_binary(
char *&str, uint8_t code, uint8_t locked_page, uint8_t high_bits)
noexcept
323 *(str++) = (high_bits << 5) | code;
335 uint8_t current_page = 0;
336 uint8_t locked_page = 0;
338 auto code =
static_cast<uint8_t
>(value_ & 0x1f);
341 switch (current_page & 3) {
342 case 0: current_page = char_from_tt5_page0(str, code, locked_page);
break;
343 case 1: current_page = char_from_tt5_page1(str, code, locked_page);
break;
344 case 2: current_page = char_from_tt5_page2(str, code, locked_page);
break;
345 case 3: current_page = char_from_tt5_binary(str, code, locked_page, current_page >> 4);
break;
346 default: tt_no_default;
359 constexpr ssize_t max_nr_bits =
sizeof(T) * CHAR_BIT;
360 constexpr ssize_t max_nr_chars = max_nr_bits / 5;
364 return {buffer.
data()};
367using tt5_64 = uint64_t;
368using tt5_128 = ubig128;
372constexpr auto operator""_tt5(
char const *str,
size_t)
noexcept
374 return tt5_encode<tt5_64>(str);
379constexpr auto operator""_tt5_64(
char const *str,
size_t)
noexcept
381 return tt5_encode<tt5_64>(str);
386constexpr auto operator""_tt5_128(
char const *str,
size_t)
noexcept
388 return tt5_encode<tt5_128>(str);
constexpr void fill_buffer_from_tt5(char *str, T const &value) noexcept
Convert a tt5 value to a string.
Definition TT5.hpp:331
constexpr T tt5_encode(char const *str)
Encode a UTF-8 string into an integer using TT5-encoding.
Definition TT5.hpp:175
constexpr uint16_t tt5_code(uint16_t page, uint16_t prefix, uint16_t value)
Create a tt5_code.
Definition TT5.hpp:78
constexpr uint16_t tt5_code_table_generate_entry(uint8_t c) noexcept
Convert a unicode character to a tt5-code.
Definition TT5.hpp:86
constexpr T tt5_reverse(T value) noexcept
Reverse the character in a TT5-packet-integer.
Definition TT5.hpp:247
std::string tt5_decode(T const &value) noexcept
Decode a TT5-packed integer into a UTF-8 string.
Definition TT5.hpp:358
constexpr bool tt5_want_to_lock(uint64_t ring) noexcept
Check if we want to use the lock command.
Definition TT5.hpp:155