aries: Implement DecodeBinaryTagData
Not the prettiest implementation, but it seems to work.
This commit is contained in:
parent
a5bf226d11
commit
8e78492728
|
@ -1,8 +1,9 @@
|
|||
#include <aries/Tags.hpp>
|
||||
#include <string_view>
|
||||
|
||||
namespace ls::aries {
|
||||
|
||||
bool ParseTagFieldsToMap(const std::string_view tagFieldData, TagMap& outMap) {
|
||||
bool ParseTagFieldsToMap(const std::string_view tagFieldData, TagMap& outMap) {
|
||||
// Nothing to parse,
|
||||
// which isn't exclusively a failure condition.
|
||||
if(tagFieldData.empty())
|
||||
|
@ -83,35 +84,62 @@ namespace ls::aries {
|
|||
}
|
||||
|
||||
void SerializeTagFields(const TagMap& map, std::string& outStr) {
|
||||
std::string tagFieldBuffer{};
|
||||
std::string tagFieldBuffer {};
|
||||
|
||||
// Reserve a sane amount, to avoid allocations when serializing
|
||||
// (in most cases; larger tag count MIGHT still cause some allocation pressure).
|
||||
tagFieldBuffer.reserve(512);
|
||||
|
||||
// Serialize the tag fields
|
||||
// Serialize the tag fields
|
||||
for(auto [key, value] : map)
|
||||
tagFieldBuffer += std::format("{}={}\n", key, value);
|
||||
|
||||
// Null terminate it. (TODO: We shouldn't have to do this anymore, std::string does this on its own)
|
||||
//tagFieldBuffer.push_back('\0');
|
||||
|
||||
outStr = std::move(tagFieldBuffer);
|
||||
}
|
||||
|
||||
std::vector<u8> DecodeBinaryTagData(std::string_view tagData) {
|
||||
namespace impl {
|
||||
static constexpr std::byte HexCharToByte(char nibble1, char nibble2) {
|
||||
// mmm so sexy
|
||||
constexpr auto convertOneNibble = [](char nibbleChar) -> char {
|
||||
if(nibbleChar >= '0' && nibbleChar <= '9') {
|
||||
return nibbleChar - '0';
|
||||
} else if(nibbleChar >= 'A' && nibbleChar <= 'F') {
|
||||
return nibbleChar - 'A' + 10;
|
||||
} else if(nibbleChar >= 'a' && nibbleChar <= 'f') {
|
||||
return nibbleChar - 'a' + 10;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
return static_cast<std::byte>((convertOneNibble(nibble1) << 4) | (convertOneNibble(nibble2)));
|
||||
}
|
||||
} // namespace impl
|
||||
|
||||
std::vector<std::byte> DecodeBinaryTagData(std::string_view tagData) {
|
||||
// This could be more ergonomic as an optional or something.
|
||||
std::vector<std::byte> res;
|
||||
|
||||
if(tagData.empty())
|
||||
return {};
|
||||
return res;
|
||||
|
||||
// Marker for binary data
|
||||
// Aries tagfield's marker for binary data is the $ character.
|
||||
// If this isn't at the start of a binary payload, it's probably invalid.
|
||||
if(tagData[0] != '$')
|
||||
return {};
|
||||
return res;
|
||||
|
||||
// TODO: Implement me fully!
|
||||
// remove the '$' marker from consideration
|
||||
const auto hexPointLength = tagData.length() - 1;
|
||||
const auto byteSize = hexPointLength / 2;
|
||||
|
||||
return {};
|
||||
res.resize(byteSize);
|
||||
|
||||
const auto dataView = std::string_view(tagData.data() + 1, hexPointLength);
|
||||
for(auto i = 0; i < byteSize; ++i) {
|
||||
res[i] = impl::HexCharToByte(dataView[i * 2], dataView[i * 2 + 1]);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace ls::aries
|
|
@ -4,21 +4,21 @@
|
|||
|
||||
namespace ls::aries {
|
||||
|
||||
using TagMap = std::unordered_map<std::string, std::string>;
|
||||
/// A map of tag fields and their values.
|
||||
using TagMap = std::unordered_map<std::string, std::string>;
|
||||
|
||||
/// Parses tag field data to a TagMap.
|
||||
/// # Returns
|
||||
/// True on success; false otherwise (TODO: Move to exceptions or error_category)
|
||||
bool ParseTagFieldsToMap(const std::string_view tagFieldData, TagMap& outMap);
|
||||
/// Parses tag field data to a TagMap.
|
||||
/// # Returns
|
||||
/// True on success; false otherwise (TODO: Move to exceptions or error_category)
|
||||
bool ParseTagFieldsToMap(const std::string_view tagFieldData, TagMap& outMap);
|
||||
|
||||
/// Serializes a TagMap to a string.
|
||||
void SerializeTagFields(const TagMap& map, std::string& outStr);
|
||||
/// Serializes a TagMap to a string.
|
||||
void SerializeTagFields(const TagMap& map, std::string& outStr);
|
||||
|
||||
/// Decodes a binary tag to binary data.
|
||||
std::vector<u8> DecodeBinaryTagData(std::string_view tagData);
|
||||
/// Decodes a binary tag to binary data.
|
||||
std::vector<std::byte> DecodeBinaryTagData(std::string_view tagData);
|
||||
|
||||
|
||||
// TODO: Maybe also a in-Aries implementation of "CryptoSSC2"/other dirtysock crypto primitives so that we can rehash
|
||||
// passwords to an actually sane password hash (e.g: argon2di).
|
||||
// TODO: Maybe also a in-Aries implementation of "CryptoSSC2"/other dirtysock crypto primitives so that we can rehash
|
||||
// passwords to an actually sane password hash (e.g: argon2di).
|
||||
|
||||
}
|
||||
} // namespace ls::aries
|
|
@ -28,7 +28,13 @@ TEST_CASE("Aries tag field serde functions as expected", "[Aries] [TagFields]")
|
|||
TEST_CASE("DecodeBinaryTagData() works", "[Aries] [TagFields] [DecodeBinarytagData]") {
|
||||
// should decode to [ 0x12, 0x34, 0x56, 0x78 ]
|
||||
std::string testCorpus = "$12345678";
|
||||
const static std::vector<u8> expectedOutput = { 0x12, 0x34, 0x56, 0x78 };
|
||||
const static std::vector<std::byte> expectedOutput = { static_cast<std::byte>(0x12), static_cast<std::byte>(0x34), static_cast<std::byte>(0x56), static_cast<std::byte>(0x78) };
|
||||
|
||||
REQUIRE(aries::DecodeBinaryTagData(testCorpus) == expectedOutput);
|
||||
std::string testCorpus2 = "$feffffeeffffffff";
|
||||
const static std::vector<std::byte> expectedOutput2 = { static_cast<std::byte>(0xfe), static_cast<std::byte>(0xff), static_cast<std::byte>(0xff), static_cast<std::byte>(0xee), static_cast<std::byte>(0xff), static_cast<std::byte>(0xff), static_cast<std::byte>(0xff), static_cast<std::byte>(0xff) };
|
||||
|
||||
REQUIRE(aries::DecodeBinaryTagData(testCorpus) == expectedOutput);
|
||||
REQUIRE(aries::DecodeBinaryTagData(testCorpus2) == expectedOutput2);
|
||||
|
||||
REQUIRE(aries::DecodeBinaryTagData("invalid").empty());
|
||||
}
|
Loading…
Reference in New Issue