/* * libfud * Copyright 2024 Dominick Allen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FUD_FILE_HPP #define FUD_FILE_HPP #include "fud_allocator.hpp" #include "fud_option.hpp" #include "fud_result.hpp" #include "fud_status.hpp" #include "fud_string_view.hpp" #include namespace fud { /** \brief Access Modes for File */ enum class FileAccessMode : uint8_t { Read = 0x01, Write = 0x02, ReadWrite = Read | Write }; enum class OpenFlagEnum : uint32_t { Append = O_APPEND, Truncate = O_TRUNC, CloseOnExec = O_CLOEXEC, DataSync = O_DSYNC, Direct = O_DIRECT, NoAtime = O_NOATIME, NonBlock = O_NONBLOCK, FileSync = O_SYNC }; class OpenFlags { public: using FlagType = std::underlying_type_t; constexpr OpenFlags() noexcept = default; constexpr OpenFlags(const OpenFlags& rhs) noexcept = default; constexpr OpenFlags(OpenFlags&& rhs) noexcept = default; constexpr ~OpenFlags() noexcept = default; constexpr OpenFlags& operator=(const OpenFlags& rhs) noexcept = default; constexpr OpenFlags& operator=(OpenFlags&& rhs) noexcept = default; constexpr OpenFlags(OpenFlagEnum mode) noexcept : m_mask{static_cast(mode)} { } constexpr OpenFlags operator|(OpenFlags rhs) const noexcept { OpenFlags mode{*this}; mode.m_mask |= rhs.m_mask; return mode; } constexpr OpenFlags& operator|=(OpenFlags rhs) noexcept { m_mask |= rhs.m_mask; return *this; } constexpr OpenFlags& operator|=(OpenFlagEnum rhs) noexcept { m_mask |= static_cast(rhs); return *this; } constexpr OpenFlags operator|(OpenFlagEnum rhs) const noexcept { OpenFlags mode{*this}; mode.m_mask |= static_cast(rhs); return mode; } constexpr FlagType flags() const noexcept { return m_mask; } constexpr bool hasFlag(OpenFlagEnum flag) noexcept { return (m_mask & static_cast(flag)) != 0; } private: FlagType m_mask{0}; }; constexpr OpenFlags operator|(OpenFlagEnum lhs, OpenFlagEnum rhs) { OpenFlags mode{lhs}; return mode | rhs; } struct [[nodiscard]] ReadResult { size_t bytesRead{0}; FudStatus status{FudStatus::Success}; }; struct [[nodiscard]] WriteResult { size_t bytesWritten{0}; FudStatus status{FudStatus::Success}; }; class RegularFile; using FileResult = Result; class RegularFile { public: static FileResult open( StringView filename, FileAccessMode mode, OpenFlags flags, Option dirFdoption, Allocator* allocator = &globalFudAllocator); static FileResult create( StringView filename, FileAccessMode mode, OpenFlags flags, bool exclusive, Option dirFdOption, Allocator* allocator = &globalFudAllocator); FudStatus close(); private: RegularFile() = default; public: RegularFile(const RegularFile& rhs) = delete; RegularFile(RegularFile&& rhs) noexcept; ~RegularFile(); RegularFile& operator=(const RegularFile& rhs) = delete; RegularFile& operator=(RegularFile&& rhs) noexcept; FudStatus take(RegularFile& rhs); private: int m_fd{-1}; FileAccessMode m_modeFlags{}; OpenFlags m_openFlags{}; }; } // namespace fud #endif