2018-04-05 16:47:07 +00:00
|
|
|
|
#include "common.hh"
|
|
|
|
|
|
2018-06-05 09:38:27 +00:00
|
|
|
|
using std::uint16_t;
|
2018-06-11 14:34:35 +00:00
|
|
|
|
using std::uint8_t;
|
2018-06-05 09:38:27 +00:00
|
|
|
|
using dic_comp_t = std::map<std::pair<uint16_t, uint8_t>, uint16_t>;
|
|
|
|
|
using ustring = std::basic_string<unsigned char>;
|
2018-06-11 14:34:35 +00:00
|
|
|
|
using p_ustring = std::shared_ptr<ustring>;
|
2018-04-05 16:47:07 +00:00
|
|
|
|
|
2019-08-19 14:40:13 +00:00
|
|
|
|
[[nodiscard]] int ipow(int base, int exp) {
|
2018-06-09 21:11:27 +00:00
|
|
|
|
int result = 1;
|
|
|
|
|
for (;;) {
|
|
|
|
|
if (exp & 1) {
|
|
|
|
|
result *= base;
|
|
|
|
|
}
|
|
|
|
|
exp >>= 1;
|
|
|
|
|
if (exp == 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
base *= base;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-19 14:40:13 +00:00
|
|
|
|
[[nodiscard]] std::pair<bool, uint16_t>
|
|
|
|
|
dico(dic_comp_t &t_dictionary, const uint16_t t_nr_chaine, const uint8_t t_c) {
|
2018-05-23 14:27:54 +00:00
|
|
|
|
if (t_nr_chaine == 0xFFFF) {
|
2018-04-05 16:47:07 +00:00
|
|
|
|
return std::make_pair(true, t_c);
|
2018-05-23 14:27:54 +00:00
|
|
|
|
}
|
2018-04-05 16:47:07 +00:00
|
|
|
|
auto &e = t_dictionary[std::make_pair(t_nr_chaine, t_c)];
|
2019-08-19 14:40:13 +00:00
|
|
|
|
if (e != 0)
|
2018-11-21 00:49:30 +00:00
|
|
|
|
return std::make_pair(true, e);
|
|
|
|
|
e = static_cast<uint16_t>(t_dictionary.size() + 255);
|
|
|
|
|
return std::make_pair(false, e);
|
2018-04-05 16:47:07 +00:00
|
|
|
|
}
|
2018-06-10 19:21:06 +00:00
|
|
|
|
|
2019-08-19 14:40:13 +00:00
|
|
|
|
[[nodiscard]] ustring dico_uncompress(std::map<uint16_t, ustring> &t_dict,
|
|
|
|
|
const uint16_t t_code,
|
|
|
|
|
const uint16_t t_old) {
|
2018-06-11 14:34:35 +00:00
|
|
|
|
// le code existe dans le dictionnaire s’il est < 256
|
|
|
|
|
if (t_code < 256) {
|
|
|
|
|
ustring e{static_cast<unsigned char>(t_code)};
|
2018-06-11 19:02:59 +00:00
|
|
|
|
// 256 car on n'a pas encore tenté d'insérer de nouveau caractère
|
2018-06-11 14:34:35 +00:00
|
|
|
|
if (t_old < 256) {
|
|
|
|
|
t_dict[static_cast<uint16_t>(t_dict.size() + 256)] =
|
|
|
|
|
static_cast<unsigned char>(t_old) + e;
|
2018-06-10 22:58:01 +00:00
|
|
|
|
} else {
|
2018-06-11 14:34:35 +00:00
|
|
|
|
t_dict[static_cast<uint16_t>(t_dict.size() + 256)] = t_dict[t_old] + e;
|
2018-06-10 21:44:10 +00:00
|
|
|
|
}
|
2018-06-10 19:21:06 +00:00
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-11 14:34:35 +00:00
|
|
|
|
auto &e = t_dict[t_code];
|
|
|
|
|
auto str = (t_old < 256) ? ustring{static_cast<unsigned char>(t_old)}
|
|
|
|
|
: t_dict[t_old];
|
|
|
|
|
|
|
|
|
|
// le code existe dans le dictionnaire
|
|
|
|
|
if (!e.empty()) {
|
|
|
|
|
str += e[0];
|
2018-06-15 17:54:00 +00:00
|
|
|
|
const auto index = static_cast<uint16_t>(t_dict.size() + 256);
|
2018-06-11 14:34:35 +00:00
|
|
|
|
t_dict[index] = str;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// le code n'existe pas encore dans le dictionnaire
|
|
|
|
|
str += str[0];
|
|
|
|
|
e = str;
|
2018-06-10 22:58:01 +00:00
|
|
|
|
t_dict[t_code] = e;
|
2018-06-10 19:21:06 +00:00
|
|
|
|
return e;
|
|
|
|
|
}
|