fix(baseN): basen::Exception

This commit is contained in:
2024-09-30 17:23:23 +03:00
parent 4eaf5b53c0
commit 227579d1e2
4 changed files with 43 additions and 14 deletions

View File

@ -4,6 +4,7 @@
#include <stdexcept>
#include <basen/baseN.hpp>
#include <basen/Exception.hpp>
static constexpr auto log256 = std::log(256);
@ -16,7 +17,7 @@ namespace baseN
{
if (map[(uint8_t)digits[i]] != 255)
{
throw std::logic_error("baseN::digitsMap: alphabet contain same chars");
throw basen::Exception(basen::Exception::Code::ALPH_COLLISION);
}
map[(uint8_t)digits[i]] = i;
}
@ -32,17 +33,25 @@ namespace baseN
}
size_t sizeEncoded(std::span<const uint8_t> data, uint8_t base)
{
if (base < 2 || base > 254)
{
throw basen::Exception(basen::Exception::Code::BASE);
}
std::span<const uint8_t> dv(std::find_if(data.begin(), data.end(), [](uint8_t item)
{ return item != 0; }),
data.end());
if (dv.size() > std::numeric_limits<size_t>::max() / log256)
{
throw std::overflow_error("baseN::sizeEncoded: overflow");
throw basen::Exception(basen::Exception::Code::OVERFLOW);
}
return dv.size() * log256 / std::log(base) + 1 + (data.size() - dv.size());
}
size_t sizeDecoded(std::string_view str, uint8_t base, const char *digits) noexcept
size_t sizeDecoded(std::string_view str, uint8_t base, const char *digits)
{
if (base < 2 || base > 254)
{
throw basen::Exception(basen::Exception::Code::BASE);
}
std::string_view sv(std::find_if(str.begin(), str.end(), [digits](uint8_t ch)
{ return ch != digits[0]; }),
str.end());
@ -50,6 +59,10 @@ namespace baseN
}
size_t encode(const uint8_t *data, size_t data_size, char *str, size_t str_size, uint8_t base, const char *digits)
{
if (base < 2 || base > 254)
{
throw basen::Exception(basen::Exception::Code::BASE);
}
std::vector<uint8_t> dv(std::find_if(data, data + data_size, [](uint8_t item)
{ return item != 0; }),
data + data_size);
@ -92,7 +105,7 @@ namespace baseN
}
return std::distance(sv_it, sv.rend());
}
std::string encode(std::span<const uint8_t> data, uint8_t base, const char *digits) noexcept
std::string encode(std::span<const uint8_t> data, uint8_t base, const char *digits)
{
std::string str(baseN::sizeEncoded(data, base), ' ');
size_t offset = baseN::encode(data.data(), data.size(), str.data(), str.size(), base, digits);
@ -101,12 +114,16 @@ namespace baseN
}
size_t decode(const char *str, size_t str_size, uint8_t *data, size_t data_size, uint8_t base, const char *digits, const uint8_t *map)
{
if (base < 2 || base > 254)
{
throw basen::Exception(basen::Exception::Code::BASE);
}
std::string_view sv(std::find_if(str, str + str_size, [digits](char ch)
{ return ch != digits[0]; }),
str + str_size);
if (!baseN::isValid(sv, map))
{
throw std::logic_error("baseN::decode: out of digits map");
throw basen::Exception(basen::Exception::Code::OUT_OF_ALPH);
}
std::span<uint8_t> dv(data, data_size);
auto sv_it = sv.begin();
@ -141,7 +158,7 @@ namespace baseN
}
return std::distance(quo_it_last, dv.rend());
}
std::vector<uint8_t> decode(std::string_view str, uint8_t base, const char *digits, const uint8_t *map) noexcept
std::vector<uint8_t> decode(std::string_view str, uint8_t base, const char *digits, const uint8_t *map)
{
std::vector<uint8_t> data(baseN::sizeDecoded(str, base, digits));
size_t offset = baseN::decode(str.data(), str.size(), data.data(), data.size(), base, digits, map);