LogDoctor/logdoctor/utilities/io.cpp

239 lines
6.9 KiB
C++

#include "io.h"
#include "utilities/strings.h"
#include "utilities/vectors.h"
#include <fstream>
#include <filesystem>
IOutils::IOutils()
{
}
// test the existence of a file/folder
bool IOutils::exists( const std::string& path )
{
return std::filesystem::exists( path );
}
// tests if a path exists and points to a file
bool IOutils::isFile( const std::string& path )
{
bool result = false;
if ( std::filesystem::exists( path )) {
result = std::filesystem::is_regular_file( path );
}
return result;
}
// returns whether a file is readable/writable
bool IOutils::checkFile( const std::string& path, const bool readable, const bool writable )
{
bool result = false;
if ( IOutils::isFile( path ) == true ) {
result = true;
// check the needed permissions
auto perms = std::filesystem::status( path ).permissions();
if ( readable == true ) {
if ( (perms & std::filesystem::perms::owner_read) == std::filesystem::perms::none ) {
result = false;
}
}
if ( writable == true ) {
if ( (perms & std::filesystem::perms::owner_write) == std::filesystem::perms::none ) {
result = false;
}
}
}
return result;
}
// test if a path exists and points to a folder
bool IOutils::isDir( const std::string& path )
{
bool result = false;
if ( std::filesystem::exists( path )) {
result = std::filesystem::is_directory( path );
}
return result;
}
// returns whether a folder is readable/writable
bool IOutils::checkDir( const std::string& path, const bool readable, const bool writable )
{
bool result = false;
if ( IOutils::isDir( path ) == true ) {
result = true;
// check the needed permissions
auto perms = std::filesystem::status( path ).permissions();
if ( readable == true ) {
if ( (perms & std::filesystem::perms::owner_read) == std::filesystem::perms::none ) {
result = false;
}
}
if ( writable == true ) {
if ( (perms & std::filesystem::perms::owner_write) == std::filesystem::perms::none ) {
result = false;
}
}
}
return result;
}
// rename an entry with a trailing '.copy'
bool IOutils::renameAsCopy( const std::string& path ) noexcept(true)
{
bool result = true;
std::string new_path = path;
// loop until a valid name is found
while (true) {
new_path += ".copy";
if ( IOutils::exists( new_path ) == false ) {
// available name found
break;
}
}
try {
std::filesystem::rename( path, new_path );
} catch (...) {
result = false;
}
return result;
}
const std::vector<std::string> IOutils::readLines(const std::string& path, const int n_lines, const bool random, const bool strip_lines )
{
// read rhe first N lines only
bool result = true;
std::ifstream file;
std::string line;
std::vector<std::string> lines, aux_lines;
try {
if ( random == false ) {
// read the initial lines of the file
constexpr std::size_t read_size = std::size_t(4096);
file = std::ifstream(path);
if ( file.is_open() == false ) {
throw std::ios_base::failure( "file is not open" );
}
// add bit exceptions
file.exceptions(std::ifstream::failbit);
file.exceptions(std::ios_base::badbit);
// get non-empty lines
int n=0;
while (n < n_lines) {
if ( file.good() == false ) {
// hopefully nothing more to read
break;
}
getline(file, line);
if ( strip_lines == true ) {
line = StringOps::strip( line );
}
if ( line.size() == 0 ) {
continue;
}
// succesfully catched a line
lines.push_back( line );
n++;
}
} else {
// pick random lines
StringOps::split( aux_lines, IOutils::readFile( path ) );
int max = aux_lines.size();
if ( max > 0 ) {
if ( max <= n_lines ) {
lines = aux_lines;
} else {
time_t nTime;
srand((unsigned) time(&nTime));
int index;
std::vector<int> picked_indexes;
for( int i=0 ; i<n_lines ; i++ ) {
while (true) {
index = rand() % max;
if ( VecOps::contains( picked_indexes, index ) == true ) {
continue;
}
break;
}
line = aux_lines.at( index );
if ( strip_lines == true ) {
line = StringOps::strip( line );
}
lines.push_back( line );
}
}
}
aux_lines.clear();
}
} catch (const std::ios_base::failure& err) {
// failed reading
lines.clear();
aux_lines.clear();
result = false;
if ( file.is_open() ) {
file.close();
}
throw err;
} catch (...) {
lines.clear();
aux_lines.clear();
result = false;
if ( file.is_open() ) {
file.close();
}
throw std::exception();
}
if ( file.is_open() ) {
file.close();
}
return lines;
}
const std::string IOutils::readFile( const std::string& path )
{
// read the whole file
std::ifstream file;
std::string content = std::string();
try {
constexpr std::size_t read_size = std::size_t(4096);
std::ifstream file(path);
if ( file.is_open() == false ) {
throw std::ios_base::failure( "file is not open" );
}
if ( file.good() == false ) {
throw std::ios_base::failure( "file is not good" );
}
// add bit exceptions
file.exceptions(std::ifstream::failbit);
file.exceptions(std::ios_base::badbit);
// read the whole file
content = std::string(
(std::istreambuf_iterator<char>( file )),
std::istreambuf_iterator<char>() );
} catch (const std::ios_base::failure& err) {
// failed reading
content = "";
if ( file.is_open() == true ) {
file.close();
}
throw err;
} catch (...) {
content = "";
if ( file.is_open() == true ) {
file.close();
}
throw std::exception();
}
if ( file.is_open() == true ) {
file.close();
}
return content;
}