From 9967b41eaeacbb80810b76bba4addcba16dda671 Mon Sep 17 00:00:00 2001 From: Simon Rozman Date: Wed, 6 Dec 2023 11:02:12 +0100 Subject: [PATCH] stream: make memory_file properly copyable and movable Signed-off-by: Simon Rozman --- include/stdex/stream.hpp | 119 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) diff --git a/include/stdex/stream.hpp b/include/stdex/stream.hpp index 935536b4d..4fe6f8c10 100644 --- a/include/stdex/stream.hpp +++ b/include/stdex/stream.hpp @@ -3204,8 +3204,10 @@ namespace stdex m_reserved(size), m_manage(true) { - if (!m_data) + if (!m_data) { + m_state = state_t::fail; throw std::bad_alloc(); + } #if SET_FILE_OP_TIMES m_ctime = m_atime = m_mtime = time_point::now(); #endif @@ -3266,6 +3268,121 @@ namespace stdex /// inline memory_file(_In_ const stdex::sstring& filename, _In_ int mode) : memory_file(filename.c_str(), mode) {} + /// + /// Copies content from another file + /// + /// \param[in] other Other file + /// + memory_file(_In_ const memory_file& other) : + basic_file(other), + m_data(reinterpret_cast(malloc(other.m_size))), + m_offset(other.m_offset), + m_size(other.m_size), + m_reserved(other.m_size), + m_manage(true) +#if SET_FILE_OP_TIMES + , m_ctime(other.m_ctime) + , m_atime(other.m_atime) + , m_mtime(other.m_mtime) +#endif + { + if (!m_data) { + m_state = state_t::fail; + throw std::bad_alloc(); + } + memcpy(m_data, other.m_data, other.m_size); + } + + /// + /// Copies content from another file + /// + /// \param[in] other Other file + /// + memory_file& operator=(_In_ const memory_file& other) + { + if (this != std::addressof(other)) { + *static_cast(this) = other; + if (m_manage && m_data) + free(m_data); + m_data = reinterpret_cast(malloc(other.m_size)); + if (!m_data) { + m_state = state_t::fail; + throw std::bad_alloc(); + } + memcpy(m_data, other.m_data, other.m_size); + m_offset = other.m_offset; + m_size = other.m_size; + m_reserved = other.m_size; + m_manage = true; +#if SET_FILE_OP_TIMES + m_ctime = other.m_ctime; + m_atime = other.m_atime; + m_mtime = other.m_mtime; +#endif + } + return *this; + } + + /// + /// Moves content from another file + /// + /// \param[in] other Other file + /// + memory_file(_Inout_ memory_file&& other) noexcept : + basic_file(std::move(other)), + m_data(other.m_data), + m_offset(other.m_offset), + m_size(other.m_size), + m_reserved(other.m_reserved), + m_manage(other.m_manage) +#if SET_FILE_OP_TIMES + , m_ctime(other.m_ctime) + , m_atime(other.m_atime) + , m_mtime(other.m_mtime) +#endif + { + other.m_state = state_t::ok; + other.m_data = nullptr; + other.m_offset = 0; + other.m_size = 0; + other.m_reserved = 0; + other.m_manage = true; +#if SET_FILE_OP_TIMES + other.m_ctime = other.m_atime = other.m_mtime = time_point::now(); +#endif + } + + /// + /// Moves content from another file + /// + /// \param[in] other Other file + /// + memory_file& operator=(_Inout_ memory_file&& other) noexcept + { + if (this != std::addressof(other)) { + *static_cast(this) = std::move(other); + if (m_manage && m_data) + free(m_data); + m_data = other.m_data; + other.m_data = nullptr; + m_offset = other.m_offset; + other.m_offset = 0; + m_size = other.m_size; + other.m_size = 0; + m_reserved = other.m_reserved; + other.m_reserved = 0; + m_manage = other.m_manage; + other.m_manage = true; +#if SET_FILE_OP_TIMES + m_ctime = other.m_ctime; + m_atime = other.m_atime; + m_mtime = other.m_mtime; + other.m_ctime = other.m_atime = other.m_mtime = time_point::now(); +#endif + } + return *this; + } + virtual ~memory_file() { if (m_manage && m_data)