30#ifndef ioutils_fileUtils_hpp
31#define ioutils_fileUtils_hpp
38#include "../mxlib.hpp"
45#ifdef MXLIBTEST_NAMESPACE
46namespace MXLIBTEST_NAMESPACE
65template <
class verboseT>
73template <
class verboseT = verbose::d>
74bool exists(
const std::string &path,
83template <
class verboseT = verbose::d>
100std::string
pathStem(
const std::string &fname );
112std::string
parentPath(
const std::string &fname );
125template <
class verboseT = verbose::d>
127 const std::string &directory,
129 const std::string &prefix,
132 const std::string &substr,
135 const std::string &extension
146 const std::string &prepend,
148 const std::string &append
158 const std::string &append
168 const std::string &prepend
185 const std::string &extension =
"",
187 const int startat = 0,
218template <
class verboseT>
225 return error_t::noerror;
227 catch(
const std::bad_alloc &e )
230 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
231 return internal::mxlib_error_report<verboseT>( error_t::std_bad_alloc, e.what() );
237 catch(
const std::filesystem::filesystem_error &e )
240 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined(MXLIB_CATCH_NONALLOC_EXCEPTIONS)
241 return internal::mxlib_error_report<verboseT>( error_t::std_filesystem_error, e.what() );
247 catch(
const std::exception &e )
250 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined(MXLIB_CATCH_NONALLOC_EXCEPTIONS)
251 return internal::mxlib_error_report<verboseT>( error_t::std_exception, e.what() );
260 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined(MXLIB_CATCH_NONALLOC_EXCEPTIONS)
261 return internal::mxlib_error_report<verboseT>( error_t::exception,
"unknown exception");
269template <
class verboseT>
274 std::filesystem::path path;
278 errc = string2path<verboseT>(path, strpath);
282 internal::mxlib_error_report<verboseT>( errc,
"converting path" );
291 bool ex = std::filesystem::exists( path, ec );
293 if( ec.value() != 0 )
296 if( errc == error_t::error )
298 errc = error_t::filesystem;
301 internal::mxlib_error_report<verboseT>( errc, ec.message() );
306 errc = error_t::noerror;
310template <
class verboseT>
315 std::filesystem::path path;
319 errc = string2path<verboseT>(path, dir);
323 internal::mxlib_error_report<verboseT>( errc,
"converting path" );
332 bool exists = std::filesystem::exists( path, ec );
335 #ifdef MXLIBTEST_DIREXISTSIS_ISEXISTSERR
336 ec = std::error_code( EEXIST, std::system_category() );
340 if( ec.value() != 0 )
343 if( errc == error_t::error )
345 errc = error_t::filesystem;
348 internal::mxlib_error_report<verboseT>( errc, ec.message() );
358 bool isdir = std::filesystem::is_directory( path, ec );
361 #ifdef MXLIBTEST_DIREXISTSIS_ISDIRERR
362 ec = std::error_code( EACCES, std::system_category() );
366 if( ec.value() != 0 )
368 errc = errno2error_t( ec.value() );
374 internal::mxlib_error_report<verboseT>( errc, ec.message() );
379 errc = error_t::noerror;
383template <
class verboseT>
385 const std::string &directory,
386 const std::string &prefix,
387 const std::string &substr,
388 const std::string &extension )
394 if( std::filesystem::exists( directory ) )
396 if( std::filesystem::is_directory( directory ) )
400 if( extension.size() > 0 )
402 if( extension[0] !=
'.' )
412 bool hasprefix = ( prefix.size() > 0 );
414 bool hassub = ( substr.size() > 0 );
416 std::filesystem::directory_iterator it{ directory };
417 auto it_end = std::filesystem::directory_iterator{};
418 for( it; it != it_end; ++it )
422 if( it->path().extension() != _ext )
428 std::string p = it->path().filename().generic_string();
432 if( p.size() < prefix.size() )
443 if( p.compare( 0, prefix.size(), prefix ) != 0 )
457 size_t sspos = p.find( substr, 1 );
459 if( sspos == std::string::npos )
467 fileNames.push_back( it->path().native() );
470 std::sort( fileNames.begin(), fileNames.end() );
474 return internal::mxlib_error_report<verboseT>( error_t::invalidarg, directory +
" is not a directory" );
479 return internal::mxlib_error_report<verboseT>( error_t::dirnotfound, directory +
" was not found" );
482 return error_t::noerror;
484 catch(
const std::bad_alloc &e )
487 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS )
488 return internal::mxlib_error_report<verboseT>( error_t::std_bad_alloc, e.what() );;
494 catch(
const std::filesystem::filesystem_error &e )
497 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
498 return internal::mxlib_error_report<verboseT>( error_t::std_filesystem_error, e.what() );
500 std::throw_with_nested(
mx::exception(error_t::std_filesystem_error));
504 catch(
const std::exception &e )
507 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
508 return internal::mxlib_error_report<verboseT>( error_t::exception, e.what() );
517 #if defined( MXLIB_CATCH_ALL_EXCEPTIONS ) || defined( MXLIB_CATCH_NONALLOC_EXCEPTIONS )
518 return internal::mxlib_error_report<verboseT>( error_t::exception );
526#ifdef MXLIBTEST_NAMESPACE
Augments an exception with the source file and line.
error_t code() const
Get the error code.
error_t
The mxlib error codes.
static constexpr error_t errno2error_t(const int &err)
Convert an errno code to error_t.
@ filesystem
A general filesystem error occurred.
@ error
A general error has occurred.
error_t getFileNames(std::vector< std::string > &fileNames, const std::string &directory, const std::string &prefix, const std::string &substr, const std::string &extension)
Get a list of file names from the specified directory, specifying a prefix, a substring to match,...
std::string fileNamePrepend(const std::string &fname, const std::string &prepend)
Prepend strings to a file name, leaving the directory and extension unaltered.
std::string getSequentialFilename(const std::string &basename, const std::string &extension="", const int startat=0, int ndigit=4)
Get the next file in a numbered sequence.
error_t string2path(std::filesystem::path &path, const std::string &str)
Convert a string to a path, handling exceptions.
std::string fileNamePrependAppend(const std::string &fname, const std::string &prepend, const std::string &append)
Prepend and/or append strings to a file name, leaving the directory and extension unaltered.
std::string fileNameAppend(const std::string &fname, const std::string &append)
Append a string to a file name, leaving the directory and extension unaltered.
bool exists(const std::string &path, mx::error_t &errc)
Check if a path exists.
error_t createDirectories(const std::string &path)
Create a directory or directories.
bool dir_exists_is(const std::string &dir, mx::error_t &errc)
Check if a path exists and is a directory.
std::string parentPath(const std::string &fname)
Get the parent path from a filename.
std::string pathStem(const std::string &fname)
Get the stem of the filename.
off_t fileSize(int fd)
Get the size in bytes of a file.
std::string pathFilename(const std::string &fname)
Get the base filename.