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

View File

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