rexylib/src/filerd.cpp

115 lines
2.8 KiB
C++

/**
This file is a part of rexy's general purpose library
Copyright (C) 2020 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/>.
*/
#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(fopen(f, mode)){}
filerd::~filerd(void)noexcept{
if(m_fp)
fclose(m_fp);
}
void filerd::reset(FILE* fp)noexcept{
if(m_fp)
fclose(m_fp);
m_fp = fp;
}
FILE* filerd::release(void)noexcept{
return std::exchange(m_fp, nullptr);
}
size_t filerd::length(void)noexcept{
if(!m_fp)
return 0;
size_t tmp, ret;
tmp = ftell(m_fp);
fseek(m_fp, 0, SEEK_END);
ret = ftell(m_fp);
fseek(m_fp, tmp, SEEK_SET);
return ret;
}
size_t filerd::position(void)const noexcept{
return ftell(m_fp);
}
void filerd::rewind(size_t pos)noexcept{
fseek(m_fp, pos, SEEK_SET);
}
filerd::operator FILE*(void)noexcept{
return m_fp;
}
filerd::operator const FILE*(void)const noexcept{
return m_fp;
}
FILE* filerd::get(void)noexcept{
return m_fp;
}
const FILE* filerd::get(void)const noexcept{
return m_fp;
}
filerd::operator bool(void)const noexcept{
return m_fp;
}
size_t filerd::read(char* dest, size_t bytes)noexcept{
return fread(dest, 1, bytes, m_fp);
}
rexy::string filerd::read(size_t bytes)noexcept{
rexy::string ret;
char* tmp = ret.allocator().allocate(bytes);
size_t written = read(tmp, bytes);
ret.reset(tmp, written);
return ret;
}
rexy::string filerd::readln(size_t max)noexcept{
rexy::string ret;
int c;
size_t count = 0;
for(c = fgetc(m_fp);c != EOF && c != '\n';c = fgetc(m_fp)){
char ch = c;
ret.append(&ch, 1);
if(++count == max)
break;
}
return ret;
}
rexy::binary filerd::read_bin(size_t bytes)
noexcept(std::is_nothrow_constructible<rexy::binary, rexy::steal<char*>, size_t, size_t>::value)
{
rexy::binary ret;
char* tmp = ret.allocator().allocate(bytes);
size_t written = read(tmp, bytes);
ret.reset(tmp, written);
return ret;
}
size_t filerd::write(const char* c, size_t bytes)noexcept{
return fwrite(c, 1, bytes, m_fp);
}
size_t filerd::write(const rexy::string_base<char>& c)noexcept{
return write(c.get(), c.length());
}
}