/* SPDX-License-Identifier: BSL-1.0 OR BSD-3-Clause */ #ifndef MPT_IO_IO_SPAN_HPP #define MPT_IO_IO_SPAN_HPP #include "mpt/base/macros.hpp" #include "mpt/base/memory.hpp" #include "mpt/base/namespace.hpp" #include "mpt/base/saturate_cast.hpp" #include "mpt/base/span.hpp" #include "mpt/io/base.hpp" #include #include #include namespace mpt { inline namespace MPT_INLINE_NS { namespace IO { template struct FileOperations, IO::Offset>> { private: std::pair, IO::Offset> & f; public: FileOperations(std::pair, IO::Offset> & f_) : f(f_) { return; } public: inline bool IsValid() { return (f.second >= 0); } inline bool IsReadSeekable() { MPT_UNUSED(f); return true; } inline bool IsWriteSeekable() { MPT_UNUSED(f); return true; } inline IO::Offset TellRead() { return f.second; } inline IO::Offset TellWrite() { return f.second; } inline bool SeekBegin() { f.second = 0; return true; } inline bool SeekEnd() { f.second = f.first.size(); return true; } inline bool SeekAbsolute(IO::Offset pos) { f.second = pos; return true; } inline bool SeekRelative(IO::Offset off) { if (f.second < 0) { return false; } f.second += off; return true; } inline mpt::byte_span ReadRawImpl(mpt::byte_span data) { if (f.second < 0) { return data.first(0); } if (f.second >= static_cast(f.first.size())) { return data.first(0); } std::size_t num = mpt::saturate_cast(std::min(static_cast(f.first.size()) - f.second, static_cast(data.size()))); std::copy(mpt::byte_cast(f.first.data() + f.second), mpt::byte_cast(f.first.data() + f.second + num), data.data()); f.second += num; return data.first(num); } inline bool WriteRawImpl(mpt::const_byte_span data) { if (f.second < 0) { return false; } if (f.second > static_cast(f.first.size())) { return false; } std::size_t num = mpt::saturate_cast(std::min(static_cast(f.first.size()) - f.second, static_cast(data.size()))); if (num != data.size()) { return false; } std::copy(data.data(), data.data() + num, mpt::byte_cast(f.first.data() + f.second)); f.second += num; return true; } inline bool IsEof() { return (f.second >= static_cast(f.first.size())); } inline bool Flush() { MPT_UNUSED(f); return true; } }; } // namespace IO } // namespace MPT_INLINE_NS } // namespace mpt #endif // MPT_IO_IO_SPAN_HPP