2022-12-21 02:34:04 +01:00
|
|
|
#include "json_binary_proxy.h"
|
2023-04-13 15:50:13 +02:00
|
|
|
|
2022-09-28 18:13:37 +02:00
|
|
|
#include <oxenc/base64.h>
|
2023-04-13 15:50:13 +02:00
|
|
|
#include <oxenc/hex.h>
|
2021-08-06 20:00:29 +02:00
|
|
|
|
2022-12-21 02:34:04 +01:00
|
|
|
namespace tools {
|
2021-08-06 20:00:29 +02:00
|
|
|
|
2023-04-13 15:50:13 +02:00
|
|
|
void load_binary_parameter_impl(
|
|
|
|
std::string_view bytes, size_t raw_size, bool allow_raw, uint8_t* val_data) {
|
2021-08-06 20:00:29 +02:00
|
|
|
if (allow_raw && bytes.size() == raw_size) {
|
2023-04-13 15:50:13 +02:00
|
|
|
std::memcpy(val_data, bytes.data(), bytes.size());
|
2021-08-26 21:22:07 +02:00
|
|
|
return;
|
2023-04-13 15:50:13 +02:00
|
|
|
} else if (bytes.size() == raw_size * 2) {
|
|
|
|
if (oxenc::is_hex(bytes)) {
|
|
|
|
oxenc::from_hex(bytes.begin(), bytes.end(), val_data);
|
|
|
|
return;
|
|
|
|
}
|
2021-08-06 20:00:29 +02:00
|
|
|
} else {
|
2023-04-13 15:50:13 +02:00
|
|
|
const size_t b64_padded = (raw_size + 2) / 3 * 4;
|
|
|
|
const size_t b64_padding = raw_size % 3 == 1 ? 2 : raw_size % 3 == 2 ? 1 : 0;
|
|
|
|
const size_t b64_unpadded = b64_padded - b64_padding;
|
|
|
|
const std::string_view b64_padding_string = b64_padding == 2 ? "=="sv
|
|
|
|
: b64_padding == 1 ? "="sv
|
|
|
|
: ""sv;
|
|
|
|
if (bytes.size() == b64_unpadded || (b64_padding > 0 && bytes.size() == b64_padded &&
|
|
|
|
bytes.substr(b64_unpadded) == b64_padding_string)) {
|
|
|
|
if (oxenc::is_base64(bytes)) {
|
|
|
|
oxenc::from_base64(bytes.begin(), bytes.end(), val_data);
|
|
|
|
return;
|
|
|
|
}
|
2021-08-26 21:22:07 +02:00
|
|
|
}
|
2021-08-06 20:00:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
throw std::runtime_error{"Invalid binary value: unexpected size and/or encoding"};
|
2023-04-13 15:50:13 +02:00
|
|
|
}
|
2021-08-06 20:00:29 +02:00
|
|
|
|
2023-04-13 15:50:13 +02:00
|
|
|
nlohmann::json& json_binary_proxy::operator=(std::string_view binary_data) {
|
2021-08-06 20:00:29 +02:00
|
|
|
switch (format) {
|
2023-04-13 15:50:13 +02:00
|
|
|
case fmt::bt: return e = binary_data;
|
|
|
|
case fmt::hex: return e = oxenc::to_hex(binary_data);
|
|
|
|
case fmt::base64: return e = oxenc::to_base64(binary_data);
|
2021-08-06 20:00:29 +02:00
|
|
|
}
|
|
|
|
throw std::runtime_error{"Internal error: invalid binary encoding"};
|
|
|
|
}
|
2023-04-13 15:50:13 +02:00
|
|
|
|
|
|
|
} // namespace tools
|