[ox/std] Rework FileReader into StreamReader

This commit is contained in:
Gary Talent 2024-05-23 00:45:28 -05:00
parent aa83c2a62b
commit 660f2f5633
2 changed files with 39 additions and 24 deletions

View File

@ -8,7 +8,7 @@
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
#include <cstdio> #include <istream>
#include "array.hpp" #include "array.hpp"
#include "reader.hpp" #include "reader.hpp"
@ -16,41 +16,56 @@
namespace ox { namespace ox {
[[nodiscard]] [[nodiscard]]
constexpr int sdMap(ox::ios_base::seekdir in) noexcept { constexpr std::ios_base::seekdir sdMap(ox::ios_base::seekdir in) noexcept {
switch (in) { switch (in) {
case ox::ios_base::beg: case ox::ios_base::beg:
return SEEK_SET; return std::ios_base::seekdir::beg;
case ox::ios_base::end: case ox::ios_base::end:
return SEEK_END; return std::ios_base::seekdir::end;
case ox::ios_base::cur: case ox::ios_base::cur:
return SEEK_CUR; return std::ios_base::seekdir::cur;
} }
return -1; return std::ios_base::seekdir::beg;
} }
ox::Result<char> FileReader::peek() const noexcept { ox::Result<char> StreamReader::peek() const noexcept {
auto const c = fgetc(m_file); try {
auto const ok = c != EOF; char c{};
if (ok && ungetc(c, m_file)) [[unlikely]] { m_strm.get(c);
return OxError(1, "Unable to unget character"); auto const ok = c != EOF;
if (ok && m_strm.unget()) [[unlikely]] {
return OxError(1, "Unable to unget character");
}
return {static_cast<char>(c), OxError(!ok, "File peek failed")};
} catch (std::exception const&) {
return OxError(1, "peek failed");
} }
return {static_cast<char>(c), OxError(!ok, "File peek failed")};
} }
ox::Result<std::size_t> FileReader::read(char *v, std::size_t cnt) noexcept { ox::Result<std::size_t> StreamReader::read(char *v, std::size_t cnt) noexcept {
return fread(v, 1, cnt, m_file); return static_cast<size_t>(m_strm.read(v, static_cast<std::streamsize>(cnt)).gcount());
} }
ox::Error FileReader::seekg(std::size_t p) noexcept { ox::Error StreamReader::seekg(std::size_t p) noexcept {
return OxError(fseek(m_file, static_cast<long>(p), SEEK_CUR) != 0); try {
m_strm.seekg(static_cast<long long int>(p), std::ios_base::seekdir::cur);
} catch (std::exception const&) {
return OxError(1, "seekg failed");
}
return {};
} }
ox::Error FileReader::seekg(int64_t p, ios_base::seekdir sd) noexcept { ox::Error StreamReader::seekg(int64_t p, ios_base::seekdir sd) noexcept {
return OxError(fseek(m_file, static_cast<long>(p), sdMap(sd)) != 0); try {
m_strm.seekg(p, sdMap(sd));
} catch (std::exception const&) {
return OxError(1, "seekg failed");
}
return {};
} }
ox::Result<std::size_t> FileReader::tellg() noexcept { ox::Result<std::size_t> StreamReader::tellg() noexcept {
const auto sz = ftell(m_file); const auto sz = m_strm.tellg();
return {static_cast<std::size_t>(sz), OxError(sz == -1)}; return {static_cast<std::size_t>(sz), OxError(sz == -1)};
} }

View File

@ -9,7 +9,7 @@
#pragma once #pragma once
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
#include <cstdio> #include <istream>
#endif #endif
#include "concepts.hpp" #include "concepts.hpp"
@ -65,11 +65,11 @@ class ReaderT: public Reader_v {
}; };
#ifdef OX_USE_STDLIB #ifdef OX_USE_STDLIB
class FileReader: public Reader_v { class StreamReader: public Reader_v {
private: private:
FILE *m_file = nullptr; std::istream &m_strm;
public: public:
constexpr explicit FileReader(FILE *file) noexcept: m_file(file) {} constexpr explicit StreamReader(std::istream &stream) noexcept: m_strm(stream) {}
ox::Result<char> peek() const noexcept override; ox::Result<char> peek() const noexcept override;
ox::Result<std::size_t> read(char *v, std::size_t cnt) noexcept override; ox::Result<std::size_t> read(char *v, std::size_t cnt) noexcept override;
ox::Error seekg(std::size_t p) noexcept override; ox::Error seekg(std::size_t p) noexcept override;