Skip to content

Commit

Permalink
hex: Add from_spaced_hex()
Browse files Browse the repository at this point in the history
The from_spaced_hex() is from_hex() extension where the whitespace in
the input is ignored.
  • Loading branch information
chfast committed Jun 3, 2022
1 parent 64a0f99 commit b2b0879
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 24 deletions.
24 changes: 22 additions & 2 deletions include/evmc/hex.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
// Licensed under the Apache License, Version 2.0.
#pragma once

#include <evmc/filter_iterator.hpp>
#include <cstdint>
#include <iterator>
#include <optional>
#include <string>
#include <string_view>
Expand Down Expand Up @@ -104,7 +104,6 @@ inline bool validate_hex(std::string_view hex) noexcept
///
/// In case the input is invalid the returned value is std::nullopt.
/// This can happen if a non-hex digit or odd number of digits is encountered.
/// Whitespace in the input is ignored.
inline std::optional<bytes> from_hex(std::string_view hex)
{
bytes bs;
Expand Down Expand Up @@ -135,4 +134,25 @@ constexpr std::optional<T> from_hex(std::string_view s) noexcept
return {};
return r;
}

/// Decodes hex encoded string to bytes. The whitespace in the input is ignored.
///
/// In case the input is invalid the returned value is std::nullopt.
/// This can happen if a non-hex digit or odd number of digits is encountered.
/// The whitespace (as defined by std::isspace) in the input is ignored.
template <typename InputIterator>
std::optional<bytes> from_spaced_hex(InputIterator begin, InputIterator end) noexcept
{
bytes bs;
if (!from_hex(skip_space_iterator{begin, end}, skip_space_iterator{end, end},
std::back_inserter(bs)))
return {};
return bs;
}

/// @copydoc from_spaced_hex
inline std::optional<bytes> from_spaced_hex(std::string_view hex) noexcept
{
return from_spaced_hex(hex.begin(), hex.end());
}
} // namespace evmc
20 changes: 5 additions & 15 deletions test/unittests/hex_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Copyright 2021 The EVMC Authors.
// Licensed under the Apache License, Version 2.0.

#include <evmc/filter_iterator.hpp>
#include <evmc/hex.hpp>
#include <gtest/gtest.h>

Expand Down Expand Up @@ -82,21 +81,12 @@ TEST(hex, validate_hex)
EXPECT_FALSE(validate_hex("WXYZ"));
}

TEST(hex, from_hex_skip_space)
TEST(hex, from_spaced_hex)
{
// Combine from_hex with skip_space_iterator.
static constexpr auto from_hex_skip_space = [](std::string_view hex) {
bytes out;
const auto status =
from_hex(skip_space_iterator{hex.begin(), hex.end()},
skip_space_iterator{hex.end(), hex.end()}, std::back_inserter(out));
EXPECT_TRUE(status);
return out;
};
EXPECT_EQ(from_hex_skip_space("0x010203"), (bytes{0x01, 0x02, 0x03}));
EXPECT_EQ(from_hex_skip_space("0x 010203 "), (bytes{0x01, 0x02, 0x03}));
EXPECT_EQ(from_hex_skip_space(" 0 x 0 1 0 2 0 3 "), (bytes{0x01, 0x02, 0x03}));
EXPECT_EQ(from_hex_skip_space("\f 0\r x 0 1\t 0 2 \v0 3 \n"), (bytes{0x01, 0x02, 0x03}));
EXPECT_EQ(from_spaced_hex("0x010203"), (bytes{0x01, 0x02, 0x03}));
EXPECT_EQ(from_spaced_hex("0x 010203 "), (bytes{0x01, 0x02, 0x03}));
EXPECT_EQ(from_spaced_hex(" 0 x 0 1 0 2 0 3 "), (bytes{0x01, 0x02, 0x03}));
EXPECT_EQ(from_spaced_hex("\f 0\r x 0 1\t 0 2 \v0 3 \n"), (bytes{0x01, 0x02, 0x03}));
}

TEST(hex, from_hex_to_custom_type)
Expand Down
11 changes: 4 additions & 7 deletions tools/evmc/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// Licensed under the Apache License, Version 2.0.

#include <CLI/CLI.hpp>
#include <evmc/filter_iterator.hpp>
#include <evmc/hex.hpp>
#include <evmc/loader.h>
#include <evmc/tooling.hpp>
Expand All @@ -20,13 +19,11 @@ evmc::bytes load_from_hex(const std::string& str)
{
const auto path = str.substr(1);
std::ifstream file{path};
const std::istreambuf_iterator<char> file_begin{file};
const std::istreambuf_iterator<char> file_end;
evmc::bytes out;
if (!evmc::from_hex(evmc::skip_space_iterator{file_begin, file_end},
evmc::skip_space_iterator{file_end, file_end}, std::back_inserter(out)))
auto out = evmc::from_spaced_hex(std::istreambuf_iterator<char>{file},
std::istreambuf_iterator<char>{});
if (!out)
throw std::invalid_argument{"invalid hex in " + path};
return out;
return out.value();
}

return evmc::from_hex(str).value(); // Should be validated already.
Expand Down

0 comments on commit b2b0879

Please sign in to comment.