120 lines
3.1 KiB
C++
120 lines
3.1 KiB
C++
/**
|
|
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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#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 <cstdio> //fopen, fclose
|
|
#include <utility> //exchange, swap
|
|
#include <type_traits>
|
|
|
|
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<char> filerd::read_bin(std::size_t bytes)
|
|
noexcept(std::is_nothrow_constructible<rexy::buffer<char>, char*, std::size_t>::value)
|
|
{
|
|
rexy::buffer<char> 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());
|
|
}
|
|
|
|
}
|
|
|