Commit c92b010b authored by Hugo Beauzée-Luyssen's avatar Hugo Beauzée-Luyssen

Add missing filesystem interfaces & unix implementation

parent 26f23b0d
#include "IDirectory.h"
#if defined(__linux__) || defined(__APPLE__)
# include "unix/Directory.h"
#else
# error No filesystem implementation for this architecture
#endif
std::unique_ptr<fs::IDirectory> fs::createDirectory( const std::string& path )
{
return std::unique_ptr<fs::IDirectory>( new fs::Directory( path ) );
}
#pragma once
#include <memory>
#include <vector>
namespace fs
{
class IFile;
class IDirectory
{
public:
virtual ~IDirectory() = default;
virtual std::vector<std::unique_ptr<IFile>> files() const = 0;
};
std::unique_ptr<IDirectory> createDirectory( const std::string& path );
}
#pragma once
#include <string>
namespace fs
{
class IFile
{
public:
virtual ~IFile() = default;
/// Returns the filename, including extension
virtual const std::string& name() const = 0;
/// Returns the path containing the file
virtual const std::string& path() const = 0;
/// Returns the entire path, plus filename
virtual const std::string& fullPath() const = 0;
virtual const std::string& extension() const = 0;
};
}
#include "Directory.h"
#include "File.h"
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <dirent.h>
#include <iostream>
#include <limits.h>
namespace fs
{
const std::vector<std::string> Directory::supportedExtensions {
// Videos
"avi", "3gp", "amv", "asf", "divx", "dv", "flv", "gxf",
"iso", "m1v", "m2v", "m2t", "m2ts", "m4v", "mkv", "mov",
"mp2", "mp4", "mpeg", "mpeg1", "mpeg2", "mpeg4", "mpg",
"mts", "mxf", "nsv", "nuv", "ogg", "ogm", "ogv", "ogx", "ps",
"rec", "rm", "rmvb", "tod", "ts", "vob", "vro", "webm", "wmv",
// Images
"png", "jpg", "jpeg",
// Audio
"a52", "aac", "ac3", "aiff", "amr", "aob", "ape",
"dts", "flac", "it", "m4a", "m4p", "mid", "mka", "mlp",
"mod", "mp1", "mp2", "mp3", "mpc", "oga", "ogg", "oma",
"rmi", "s3m", "spx", "tta", "voc", "vqf", "w64", "wav",
"wma", "wv", "xa", "xm"
};
Directory::Directory( const std::string& path )
: m_path( toAbsolute( path ) )
{
}
std::vector<std::unique_ptr<IFile>> Directory::files() const
{
auto dir = std::unique_ptr<DIR, int(*)(DIR*)>( opendir( m_path.c_str() ), closedir );
if ( dir == nullptr )
throw std::runtime_error("Failed to open directory");
auto res = std::vector<std::unique_ptr<IFile>>{};
dirent* result = nullptr;
while ( ( result = readdir( dir.get() ) ) != nullptr )
{
if ( strcmp( result->d_name, "." ) == 0 ||
strcmp( result->d_name, ".." ) == 0 )
{
continue;
}
auto file = std::unique_ptr<IFile>( new File( m_path, result->d_name ) );
if ( std::find( supportedExtensions.cbegin(), supportedExtensions.cend(),
file->extension() ) == supportedExtensions.cend() )
{
continue;
}
res.push_back( std::move ( file ) );
}
return res;
}
std::string Directory::toAbsolute(const std::string& path)
{
auto abs = std::unique_ptr<char[]>( new char[PATH_MAX] );
if ( realpath( path.c_str(), abs.get() ) == nullptr )
throw std::runtime_error( "Failed to convert to absolute path" );
return std::string{ abs.get() };
}
}
#pragma once
#include "filesystem/IDirectory.h"
namespace fs
{
class Directory : public IDirectory
{
public:
explicit Directory( const std::string& path );
virtual std::vector<std::unique_ptr<IFile>> files() const override;
public:
static const std::vector<std::string> supportedExtensions;
private:
static std::string toAbsolute( const std::string& path );
private:
const std::string m_path;
};
}
#include "File.h"
namespace fs
{
File::File( const std::string& path, const std::string& fileName )
: m_path( path )
, m_name( fileName )
, m_fullPath( path + ( *path.rbegin() != '/' ? "/" : "" ) + fileName )
, m_extension( extension( fileName ) )
{
}
const std::string& File::name() const
{
return m_name;
}
const std::string& File::path() const
{
return m_path;
}
const std::string& File::fullPath() const
{
return m_fullPath;
}
const std::string& File::extension() const
{
return m_extension;
}
std::string File::extension( const std::string& fileName )
{
auto pos = fileName.find_last_of( '.' );
if ( pos == std::string::npos || pos == fileName.length() )
return {};
return fileName.substr( pos + 1 );
}
}
#pragma once
#include "filesystem/IFile.h"
#include <string>
namespace fs
{
class File : public IFile
{
public:
File( const std::string& path, const std::string& fileName );
virtual ~File() = default;
virtual const std::string& name() const override;
virtual const std::string& path() const override;
virtual const std::string& fullPath() const override;
virtual const std::string& extension() const override;
static std::string extension( const std::string& fileName );
private:
const std::string m_path;
const std::string m_name;
const std::string m_fullPath;
const std::string m_extension;
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment