AsmGrader 0.0.0
Loading...
Searching...
No Matches
memory_io_serde.hpp
Go to the documentation of this file.
1#pragma once
2
9
10#include <range/v3/algorithm/copy.hpp>
11
12#include <array>
13#include <concepts>
14#include <cstddef>
15#include <cstdint>
16#include <ctime>
17#include <iterator>
18#include <string>
19#include <string_view>
20#include <type_traits>
21#include <vector>
22
23namespace asmgrader {
24
33template <typename T>
35
36namespace detail {
37
38// FIXME: Some of this is probably UB
39
40template <typename T>
42 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
43 const auto* first = reinterpret_cast<const std::byte*>(&data);
44
45 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
46 return NativeByteVector{first, first + sizeof(data)};
47}
48
49template <typename T>
50const T* reinterpret_raw(const std::vector<std::byte>& data) {
51 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
52 return reinterpret_cast<const T*>(data.data());
53}
54
55template <typename T>
57 constexpr std::size_t VALUE_SIZE = sizeof(typename T::value_type);
58 const std::size_t size = std::size(range) * VALUE_SIZE;
59 NativeByteVector result(size);
60
61 for (auto it = result.begin(); const auto& elem : range) {
62 it = ranges::copy(reinterpret_raw(elem), it).out;
63 }
64
65 return result;
66}
67
68} // namespace detail
69
70template <>
72{
73 static NativeByteVector to_bytes(const NativeByteVector& data) { return data; }
74};
75
76// "Raw" conversions (essentially just reinterpret_cast)
77template <typename T>
78 requires std::is_arithmetic_v<T> || std::same_as<T, std::timespec> || std::is_pointer_v<T> ||
79 std::is_bounded_array_v<T> || (std::is_aggregate_v<T> && !std::is_array_v<T>)
81{
82 static Result<T> read(std::uintptr_t address, MemoryIOBase& mio) {
83 const auto raw_data = TRY(mio.read_block_impl(address, sizeof(T)));
84
85 return raw_data.bit_cast_to<T>();
86 }
87
88 static NativeByteVector to_bytes(const T& data) { return detail::reinterpret_raw(data); }
89};
90
91template <>
92struct MemoryIOSerde<std::string>
93{
94 static Result<std::string> read(std::uintptr_t address, MemoryIOBase& mio) {
95 auto is_null_term = [](Byte chr) { return static_cast<char>(chr.value) == '\0'; };
96 const auto raw_data = TRY(mio.read_until(address, is_null_term));
97
98 return data_to_str(raw_data);
99 }
100
101 static NativeByteVector to_bytes(const std::string& data) {
102 // Include '\0'
103 auto raw_data = asmgrader::to_bytes<NativeByteVector>(data);
104 raw_data.push_back(static_cast<std::byte>('\0'));
105
106 return raw_data;
107 }
108
109 static std::string data_to_str(const NativeByteVector& data) { return data.to_range<std::string>(); }
110};
111
112template <std::size_t Length>
114{
115 static Result<NonTermString<Length>> read(std::uintptr_t address, MemoryIOBase& mio) {
116 const auto raw_data = TRY(mio.read_block_impl(address, Length));
117
118 return {.string = MemoryIOSerde<std::string>::data_to_str(raw_data)};
119 }
120
122 return detail::reinterpret_raw_each(std::string_view{data.string, data.string + data.LENGTH});
123 }
124};
125
126} // namespace asmgrader
Definition byte_vector.hpp:34
auto begin()
Definition byte_vector.hpp:87
Range to_range() const
T should be a stdlib-compatible container type where Byte is convertible to T::value_type.
Definition byte_vector.hpp:114
More user-friendly interface wrapper for a byte-like integral.
Definition byte.hpp:18
std::variant wrapper for a partial implementation of C++23's expected type
Definition expected.hpp:34
Base class for interacting with a tracee's memory in a variety of ways at a (relatively) high-level F...
Definition memory_io_base.hpp:25
#define TRY(val)
If the supplied argument is an error (unexpected) type, then propegate it up the call stack....
Definition error_types.hpp:52
NativeByteVector reinterpret_raw(const T &data)
Definition memory_io_serde.hpp:41
NativeByteVector reinterpret_raw_each(const T &range)
Definition memory_io_serde.hpp:56
Definition asm_buffer.hpp:20
constexpr auto to_bytes(const Range &range)
Reinterpret a range of trivially copyable values as a ByteVector of specified endianness,...
Definition bit_casts.hpp:72
Definition byte_array.hpp:94
static NativeByteVector to_bytes(const NativeByteVector &data)
Definition memory_io_serde.hpp:73
static NativeByteVector to_bytes(const NonTermString< Length > &data)
Definition memory_io_serde.hpp:121
static Result< NonTermString< Length > > read(std::uintptr_t address, MemoryIOBase &mio)
Definition memory_io_serde.hpp:115
static NativeByteVector to_bytes(const T &data)
Definition memory_io_serde.hpp:88
static Result< T > read(std::uintptr_t address, MemoryIOBase &mio)
Definition memory_io_serde.hpp:82
static std::string data_to_str(const NativeByteVector &data)
Definition memory_io_serde.hpp:109
static NativeByteVector to_bytes(const std::string &data)
Definition memory_io_serde.hpp:101
static Result< std::string > read(std::uintptr_t address, MemoryIOBase &mio)
Definition memory_io_serde.hpp:94
Example class implementation:
Definition memory_io_serde.hpp:34
Definition non_terminated_str.hpp:10
static constexpr auto LENGTH
Definition non_terminated_str.hpp:12
const char * string
Definition non_terminated_str.hpp:11