feat(hex, base64): sizeEncoded, sizeDecoded

This commit is contained in:
2024-09-17 14:58:21 +03:00
parent 961b5f6b0c
commit 94661af528
4 changed files with 40 additions and 6 deletions

View File

@ -10,6 +10,9 @@ namespace base64
bool isValid(const char *str, uint64_t str_size) noexcept; bool isValid(const char *str, uint64_t str_size) noexcept;
bool isValid(std::string_view str) noexcept; bool isValid(std::string_view str) noexcept;
uint64_t sizeEncoded(uint64_t data_size);
uint64_t sizeDecoded(uint64_t str_size) noexcept;
void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size); void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size);
std::string encode(std::span<const uint8_t> data) noexcept; std::string encode(std::span<const uint8_t> data) noexcept;

View File

@ -10,6 +10,9 @@ namespace hex
bool isValid(const char *str, uint64_t str_size) noexcept; bool isValid(const char *str, uint64_t str_size) noexcept;
bool isValid(std::string_view str) noexcept; bool isValid(std::string_view str) noexcept;
uint64_t sizeEncoded(uint64_t data_size);
uint64_t sizeDecoded(uint64_t str_size) noexcept;
void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size); void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size);
std::string encode(std::span<const uint8_t> data) noexcept; std::string encode(std::span<const uint8_t> data) noexcept;

View File

@ -1,4 +1,5 @@
#include <algorithm> #include <algorithm>
#include <limits>
#include <stdexcept> #include <stdexcept>
#include <base/base64.hpp> #include <base/base64.hpp>
@ -44,9 +45,23 @@ namespace base64
} }
return baseN::isValid(sv, b64map); return baseN::isValid(sv, b64map);
} }
uint64_t sizeEncoded(uint64_t data_size)
{
uint64_t str_size = data_size / 3;
if (str_size > std::numeric_limits<uint64_t>::max() / 4)
{
throw std::overflow_error("base64::sizeEncoded: overflow");
}
str_size = str_size * 4 + (data_size % 3 ? 4 : 0);
return str_size;
}
// uint64_t sizeDecoded(uint64_t str_size) noexcept
// {
// }
void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size) void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size)
{ {
if (str_size < data_size / 3 * 4 + (data_size % 3 ? 4 : 0)) if (str_size < base64::sizeEncoded(data_size))
{ {
throw std::logic_error("base64::encode: not enough allocated length"); throw std::logic_error("base64::encode: not enough allocated length");
} }
@ -81,7 +96,7 @@ namespace base64
} }
std::string encode(std::span<const uint8_t> data) noexcept std::string encode(std::span<const uint8_t> data) noexcept
{ {
std::string str(data.size() / 3 * 4 + (data.size() % 3 ? 4 : 0), ' '); std::string str(base64::sizeEncoded(data.size()), ' ');
base64::encode(data.data(), data.size(), str.data(), str.size()); base64::encode(data.data(), data.size(), str.data(), str.size());
return str; return str;
} }

View File

@ -1,3 +1,4 @@
#include <limits>
#include <stdexcept> #include <stdexcept>
#include <base/baseN.hpp> #include <base/baseN.hpp>
@ -35,9 +36,21 @@ namespace hex
{ {
return baseN::isValid(str, hexmap); return baseN::isValid(str, hexmap);
} }
uint64_t sizeEncoded(uint64_t data_size)
{
if (data_size > std::numeric_limits<uint64_t>::max() / 2)
{
throw std::overflow_error("hex::sizeEncoded: overflow");
}
return data_size * 2;
}
uint64_t sizeDecoded(uint64_t str_size) noexcept
{
return str_size / 2;
}
void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size) void encode(const uint8_t *data, uint64_t data_size, char *str, uint64_t str_size)
{ {
if (str_size < data_size * 2) if (str_size < hex::sizeEncoded(data_size))
{ {
throw std::logic_error("hex::encode: not enough allocated length"); throw std::logic_error("hex::encode: not enough allocated length");
} }
@ -49,7 +62,7 @@ namespace hex
} }
std::string encode(std::span<const uint8_t> data) noexcept std::string encode(std::span<const uint8_t> data) noexcept
{ {
std::string str(data.size() * 2, ' '); std::string str(hex::sizeEncoded(data.size()), ' ');
hex::encode(data.data(), data.size(), str.data(), str.size()); hex::encode(data.data(), data.size(), str.data(), str.size());
return str; return str;
} }
@ -59,7 +72,7 @@ namespace hex
{ {
throw std::logic_error("hex::decode: isn't hex"); throw std::logic_error("hex::decode: isn't hex");
} }
if (data_size < str_size / 2) if (data_size < hex::sizeDecoded(str_size))
{ {
throw std::logic_error("hex::decode: not enough allocated length"); throw std::logic_error("hex::decode: not enough allocated length");
} }
@ -74,7 +87,7 @@ namespace hex
} }
std::vector<uint8_t> decode(std::string_view str) noexcept std::vector<uint8_t> decode(std::string_view str) noexcept
{ {
std::vector<uint8_t> data(str.size() / 2); std::vector<uint8_t> data(hex::sizeDecoded(str.size()));
hex::decode(str.data(), str.size(), data.data(), data.size()); hex::decode(str.data(), str.size(), data.data(), data.size());
return data; return data;
} }