libshit

Just some random shit
git clone https://git.neptards.moe/neptards/libshit.git
Log | Files | Refs | Submodules | README | LICENSE

low_io.hpp (4244B)


      1 #ifndef GUARD_UNREVEALINGLY_SLATY_MICROSCHIZONT_AUTOIONIZES_2256
      2 #define GUARD_UNREVEALINGLY_SLATY_MICROSCHIZONT_AUTOIONIZES_2256
      3 #pragma once
      4 
      5 #include "libshit/platform.hpp"
      6 
      7 #include <cstddef>
      8 #include <cstdint>
      9 #include <type_traits>
     10 #include <utility>
     11 
     12 namespace Libshit
     13 {
     14 
     15   class LowIo
     16   {
     17   public:
     18     using FdType = std::conditional_t<LIBSHIT_OS_IS_WINDOWS, void*, int>;
     19     static inline const FdType INVALID_FD = reinterpret_cast<FdType>(-1);
     20     using FilePosition = std::uint64_t;
     21 
     22     LowIo() noexcept {}; // can't be default due to a clang8 bug
     23     explicit LowIo(FdType fd) noexcept : fd{fd} {}
     24     LowIo(FdType fd, bool owning) noexcept : fd{fd}, owning{owning} {}
     25 
     26     enum class Permission { READ_ONLY, WRITE_ONLY, READ_WRITE };
     27     enum class Mode { OPEN_ONLY, CREATE_ONLY, OPEN_OR_CREATE, TRUNC_OR_CREATE };
     28 
     29     LowIo(const char* fname, Permission perm, Mode mode);
     30     ~LowIo() noexcept { Reset(); }
     31     void Reset() noexcept;
     32 
     33     static LowIo OpenStdOut();
     34 
     35     enum class OpenError
     36     {
     37       OK,
     38       ACCESS, // (maybe) perm related errors
     39       EXISTS, NOT_EXISTS, // (maybe) mode related errors
     40       UNKNOWN // not mapped error
     41     };
     42     using ErrorCode = std::conditional_t<
     43       LIBSHIT_OS_IS_WINDOWS, unsigned int, int>;
     44     std::pair<OpenError, ErrorCode> TryOpen(
     45       const char* fname, Permission perm, Mode mode);
     46 
     47 #if LIBSHIT_OS_IS_WINDOWS
     48     LowIo(const wchar_t* fname, Permission perm, Mode mode);
     49     std::pair<OpenError, ErrorCode> TryOpen(
     50       const wchar_t* fname, Permission perm, Mode mode);
     51 
     52 #  define LIBSHIT_LOWIO_RETHROW_OPEN_ERROR(code, fname)                        \
     53     LIBSHIT_THROW(::Libshit::WindowsError, code, "API function", "CreateFile", \
     54                   "File name", fname)
     55 #else
     56 #  define LIBSHIT_LOWIO_RETHROW_OPEN_ERROR(code, fname)                \
     57     LIBSHIT_THROW(::Libshit::ErrnoError, code, "API function", "open", \
     58                   "File name", fname)
     59 #endif
     60 
     61     LowIo(LowIo&& o) noexcept
     62       : fd{o.fd}, LIBSHIT_OS_WINDOWS(mmap_fd{o.mmap_fd},) owning{o.owning}
     63     {
     64       o.fd = INVALID_FD;
     65       LIBSHIT_OS_WINDOWS(o.mmap_fd = INVALID_FD);
     66     }
     67     LowIo& operator=(LowIo o) noexcept
     68     {
     69       swap(*this, o);
     70       return *this;
     71     }
     72 
     73     friend void swap(LowIo& a, LowIo& b) noexcept
     74     {
     75       std::swap(a.fd, b.fd);
     76       LIBSHIT_OS_WINDOWS(std::swap(a.mmap_fd, b.mmap_fd));
     77       std::swap(a.owning, b.owning);
     78     }
     79 
     80     class MmapPtr
     81     {
     82     public:
     83       MmapPtr() noexcept = default;
     84       MmapPtr(MmapPtr&& o) noexcept
     85         : ptr{o.ptr} LIBSHIT_OS_NOT_WINDOWS(, size{o.size})
     86       {
     87         o.ptr = nullptr;
     88         LIBSHIT_OS_NOT_WINDOWS(o.size = 0);
     89       }
     90       MmapPtr& operator=(MmapPtr o) noexcept
     91       {
     92         swap(*this, o);
     93         return *this;
     94       }
     95       ~MmapPtr() noexcept { Reset(); }
     96 
     97       friend void swap(MmapPtr& a, MmapPtr& b) noexcept
     98       {
     99         std::swap(a.ptr, b.ptr);
    100         LIBSHIT_OS_NOT_WINDOWS(std::swap(a.size, b.size));
    101       }
    102 
    103       explicit operator bool() const noexcept { return ptr; }
    104       void* Get() const noexcept { return ptr; }
    105 
    106       void Reset() noexcept;
    107       void* Release()
    108       {
    109         auto res = ptr;
    110         ptr = nullptr;
    111         return res;
    112       }
    113 
    114     private:
    115 #if LIBSHIT_OS_IS_WINDOWS
    116       MmapPtr(void* ptr) : ptr{ptr} {}
    117 #else
    118       MmapPtr(void* ptr, std::size_t size) : ptr{ptr}, size{size} {}
    119 #endif
    120       friend class LowIo;
    121 
    122       void* ptr = nullptr;
    123       LIBSHIT_OS_NOT_WINDOWS(std::size_t size = 0);
    124     };
    125 
    126     static constexpr const bool MMAP_SUPPORTED = !LIBSHIT_OS_IS_VITA;
    127 
    128     FilePosition GetSize() const;
    129     void Truncate(FilePosition size) const;
    130     void PrepareMmap(bool write);
    131     MmapPtr Mmap(FilePosition offs, std::size_t size, bool write) const;
    132     static void Munmap(void* ptr, std::size_t size);
    133 
    134     void Pread(void* buf, std::size_t len, FilePosition offs) const;
    135     void Read(void* buf, std::size_t len) const;
    136 
    137     void Pwrite(const void* buf, std::size_t len, FilePosition offs) const;
    138     void Write(const void* buf, std::size_t len) const;
    139 
    140     FdType GetFd() noexcept { return fd; }
    141 
    142   private:
    143     FdType fd = INVALID_FD;
    144     LIBSHIT_OS_WINDOWS(FdType mmap_fd = INVALID_FD);
    145     bool owning = true;
    146   };
    147 
    148 }
    149 #endif