| | |
| | |
| | |
| |
|
| | #pragma once |
| |
|
| | #include <memory> |
| | #include <span> |
| | #include <vector> |
| | #include <boost/serialization/export.hpp> |
| | #include <boost/serialization/shared_ptr.hpp> |
| | #include <boost/serialization/vector.hpp> |
| | #include "common/assert.h" |
| | #include "common/common_types.h" |
| |
|
| | |
| | class BackingMem { |
| | public: |
| | virtual ~BackingMem() = default; |
| | virtual u8* GetPtr() = 0; |
| | virtual const u8* GetPtr() const = 0; |
| | virtual std::size_t GetSize() const = 0; |
| |
|
| | private: |
| | template <class Archive> |
| | void serialize(Archive&, const unsigned int) {} |
| | friend class boost::serialization::access; |
| | }; |
| |
|
| | |
| | class BufferMem : public BackingMem { |
| | public: |
| | BufferMem() = default; |
| | explicit BufferMem(std::size_t size) : data(size) {} |
| |
|
| | u8* GetPtr() override { |
| | return data.data(); |
| | } |
| |
|
| | const u8* GetPtr() const override { |
| | return data.data(); |
| | } |
| |
|
| | std::size_t GetSize() const override { |
| | return data.size(); |
| | } |
| |
|
| | std::vector<u8>& Vector() { |
| | return data; |
| | } |
| |
|
| | const std::vector<u8>& Vector() const { |
| | return data; |
| | } |
| |
|
| | private: |
| | std::vector<u8> data; |
| |
|
| | template <class Archive> |
| | void serialize(Archive& ar, const unsigned int) { |
| | ar& boost::serialization::base_object<BackingMem>(*this); |
| | ar& data; |
| | } |
| | friend class boost::serialization::access; |
| | }; |
| |
|
| | BOOST_CLASS_EXPORT_KEY(BufferMem); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | class MemoryRef { |
| | public: |
| | MemoryRef() = default; |
| | MemoryRef(std::nullptr_t) {} |
| |
|
| | MemoryRef(std::shared_ptr<BackingMem> backing_mem_) |
| | : backing_mem(std::move(backing_mem_)), offset(0) { |
| | Init(); |
| | } |
| | MemoryRef(std::shared_ptr<BackingMem> backing_mem_, u64 offset_) |
| | : backing_mem(std::move(backing_mem_)), offset(offset_) { |
| | ASSERT(offset <= backing_mem->GetSize()); |
| | Init(); |
| | } |
| |
|
| | explicit operator bool() const { |
| | return cptr != nullptr; |
| | } |
| |
|
| | operator u8*() { |
| | return cptr; |
| | } |
| |
|
| | u8* GetPtr() { |
| | return cptr; |
| | } |
| |
|
| | operator const u8*() const { |
| | return cptr; |
| | } |
| |
|
| | const u8* GetPtr() const { |
| | return cptr; |
| | } |
| |
|
| | std::span<u8> GetWriteBytes(std::size_t size) { |
| | return std::span{cptr, std::min(size, csize)}; |
| | } |
| |
|
| | template <typename T> |
| | std::span<const T> GetReadBytes(std::size_t size) const { |
| | const auto* cptr_t = reinterpret_cast<T*>(cptr); |
| | return std::span{cptr_t, std::min(size, csize) / sizeof(T)}; |
| | } |
| |
|
| | std::size_t GetSize() const { |
| | return csize; |
| | } |
| |
|
| | MemoryRef& operator+=(u32 offset_by) { |
| | ASSERT(offset_by < csize); |
| | offset += offset_by; |
| | Init(); |
| | return *this; |
| | } |
| |
|
| | MemoryRef operator+(u32 offset_by) const { |
| | ASSERT(offset_by < csize); |
| | return MemoryRef(backing_mem, offset + offset_by); |
| | } |
| |
|
| | private: |
| | std::shared_ptr<BackingMem> backing_mem{}; |
| | u64 offset{}; |
| | |
| | u8* cptr{}; |
| | std::size_t csize{}; |
| |
|
| | void Init() { |
| | if (backing_mem) { |
| | cptr = backing_mem->GetPtr() + offset; |
| | csize = static_cast<std::size_t>(backing_mem->GetSize() - offset); |
| | } else { |
| | cptr = nullptr; |
| | csize = 0; |
| | } |
| | } |
| |
|
| | template <class Archive> |
| | void serialize(Archive& ar, const unsigned int) { |
| | ar& backing_mem; |
| | ar& offset; |
| | Init(); |
| | } |
| | friend class boost::serialization::access; |
| | }; |
| |
|