/**
This file is a part of rexy's general purpose library
Copyright (C) 2020-2022 rexy712
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#ifdef _MSC_VER
//Disable warning from msvc for not using fopen_s
//which is not standard in c++ as of c++23, though it is in c since c11.
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "rexy/filerd.hpp"
#include //fopen, fclose
#include //exchange, swap
#include
namespace rexy{
filerd::filerd(const char* f, const char* mode)noexcept:
m_fp(std::fopen(f, mode)){}
filerd::~filerd(void)noexcept{
if(m_fp)
std::fclose(m_fp);
}
void filerd::reset(std::FILE* fp)noexcept{
if(m_fp)
std::fclose(m_fp);
m_fp = fp;
}
std::FILE* filerd::release(void)noexcept{
return std::exchange(m_fp, nullptr);
}
std::size_t filerd::length(void)noexcept{
if(!m_fp)
return 0;
std::size_t tmp, ret;
tmp = std::ftell(m_fp);
std::fseek(m_fp, 0, SEEK_END);
ret = std::ftell(m_fp);
std::fseek(m_fp, long(tmp), SEEK_SET);
return ret;
}
std::size_t filerd::position(void)const noexcept{
return std::ftell(m_fp);
}
void filerd::rewind(std::size_t pos)noexcept{
std::fseek(m_fp, long(pos), SEEK_SET);
}
filerd::operator std::FILE*(void)noexcept{
return m_fp;
}
filerd::operator const std::FILE*(void)const noexcept{
return m_fp;
}
std::FILE* filerd::get(void)noexcept{
return m_fp;
}
const std::FILE* filerd::get(void)const noexcept{
return m_fp;
}
filerd::operator bool(void)const noexcept{
return m_fp;
}
std::size_t filerd::read(char* dest, std::size_t bytes)noexcept{
return std::fread(dest, 1, bytes, m_fp);
}
rexy::string filerd::read(std::size_t bytes)noexcept{
rexy::string ret;
char* tmp = ret.allocator().allocate(bytes);
std::size_t written = read(tmp, bytes);
ret.reset(tmp, written);
return ret;
}
rexy::string filerd::readln(std::size_t max)noexcept{
rexy::string ret;
int c;
std::size_t count = 0;
for(c = std::fgetc(m_fp);c != EOF && c != '\n';c = std::fgetc(m_fp)){
char ch = c;
ret.append(&ch, 1);
if(++count == max)
break;
}
return ret;
}
rexy::buffer filerd::read_bin(std::size_t bytes)
noexcept(std::is_nothrow_constructible, char*, std::size_t>::value)
{
rexy::buffer ret{bytes};
std::size_t written = read(ret.data(), bytes);
ret.set_size(written);
return ret;
}
std::size_t filerd::write(const char* c, std::size_t bytes)noexcept{
return std::fwrite(c, 1, bytes, m_fp);
}
std::size_t filerd::write(rexy::string_view c)noexcept{
return write(c.data(), c.length());
}
}