Files
windows-user-space-emulator/src/emulator/binary_writer.hpp

99 lines
2.7 KiB
C++

#pragma once
namespace utils
{
template <typename Traits>
class aligned_binary_writer;
template <typename T, typename Traits>
concept Writable = requires(const T ac, aligned_binary_writer<Traits>& writer) {
{ ac.write(writer) } -> std::same_as<void>;
};
template <typename Traits>
class aligned_binary_writer
{
public:
aligned_binary_writer(memory_interface& mem, uint64_t address)
: memory(mem),
base_address(address),
current_position(address)
{
}
void write(const void* data, size_t size, size_t alignment = 1)
{
align_to(alignment);
memory.write_memory(current_position, data, size);
current_position += size;
}
template <typename T>
requires(!is_optional<T>::value)
void write(const T& value)
{
constexpr auto is_trivially_copyable = std::is_trivially_copyable_v<T>;
if constexpr (Writable<T, Traits>)
{
value.write(*this);
}
else if constexpr (is_trivially_copyable)
{
write(&value, sizeof(T), alignof(T));
}
else
{
static_assert(std::is_trivially_copyable_v<T>, "Type must be trivially copyable or be writable!");
std::abort();
}
}
void write_ndr_pointer(bool not_null)
{
write<typename Traits::PVOID>(not_null ? 0x20000 : 0);
}
void write_ndr_u16string(const std::u16string& str)
{
size_t char_count = str.size() + 1;
size_t byte_length = char_count * sizeof(char16_t);
write<typename Traits::SIZE_T>(char_count);
write<typename Traits::SIZE_T>(0);
write<typename Traits::SIZE_T>(char_count);
write(str.c_str(), byte_length);
}
void pad(size_t count)
{
std::vector<uint8_t> padding(count, 0);
write(padding.data(), count);
}
void align_to(size_t alignment)
{
size_t offset_val = static_cast<size_t>(current_position) % alignment;
if (offset_val != 0)
{
pad(alignment - offset_val);
}
}
uint64_t position() const
{
return current_position;
}
uint64_t offset() const
{
return current_position - base_address;
}
private:
memory_interface& memory; // NOLINT(cppcoreguidelines-avoid-const-or-ref-data-members)
uint64_t base_address;
uint64_t current_position;
};
}