blah/src/filesystem.cpp

155 lines
3.2 KiB
C++
Raw Normal View History

#include <blah/filesystem.h>
2021-03-21 17:08:28 +08:00
#include <blah/streams/filestream.h>
#include "internal/platform.h"
2020-08-26 15:38:01 +08:00
using namespace Blah;
FileRef File::open(const FilePath& path, FileMode mode)
2020-08-26 15:38:01 +08:00
{
return Platform::file_open(path.cstr(), mode);
2020-08-26 15:38:01 +08:00
}
bool File::exists(const FilePath& path)
2020-08-26 15:38:01 +08:00
{
return Platform::file_exists(path.cstr());
2020-08-26 15:38:01 +08:00
}
bool File::destroy(const FilePath& path)
2021-03-21 17:08:28 +08:00
{
return Platform::file_delete(path.cstr());
2021-03-21 17:08:28 +08:00
}
2020-08-26 15:38:01 +08:00
bool Directory::create(const FilePath& path)
{
return Platform::dir_create(path.cstr());
2020-08-26 15:38:01 +08:00
}
bool Directory::exists(const FilePath& path)
{
return Platform::dir_exists(path.cstr());
2020-08-26 15:38:01 +08:00
}
bool Directory::destroy(const FilePath& path)
2020-08-26 15:38:01 +08:00
{
return Platform::dir_delete(path.cstr());
2020-08-26 15:38:01 +08:00
}
Vector<FilePath> Directory::enumerate(const FilePath& path, bool recursive)
2020-08-26 15:38:01 +08:00
{
Vector<FilePath> list;
2020-08-26 15:38:01 +08:00
// get files
Platform::dir_enumerate(list, path.cstr(), recursive);
2020-08-26 15:38:01 +08:00
// normalize path names
for (auto& it : list)
it.replace('\\', '/');
return list;
}
void Directory::explore(const FilePath& path)
{
Platform::dir_explore(path);
2020-08-26 15:38:01 +08:00
}
FilePath Path::get_file_name(const FilePath& path)
{
const char* cstr = path.cstr();
auto length = path.length();
for (auto n = length; n > 0; n--)
if (*(cstr + n - 1) == '/')
return FilePath(cstr + n);
2020-08-26 15:38:01 +08:00
return path;
}
FilePath Path::get_file_name_no_ext(const FilePath& path)
{
FilePath filename = get_file_name(path);
return get_path_no_ext(filename);
}
FilePath Path::get_path_no_ext(const FilePath& path)
{
const char* cstr = path.cstr();
for (int n = 0; n < path.length(); n++)
if (*(cstr + n) == '.')
return FilePath(cstr, cstr + n);
return path;
}
FilePath Path::get_directory_name(const FilePath& path)
{
FilePath directory = path;
while (directory.ends_with("/"))
directory = directory.substr(0, -1);
auto last = directory.last_index_of('/');
2020-08-26 15:38:01 +08:00
if (last >= 0)
directory = directory.substr(0, last + 1);
return directory;
}
FilePath Path::get_path_after(const FilePath& path, const FilePath& after)
{
for (int i = 0; i < path.length(); i++)
{
FilePath substr(path.begin() + i, path.end());
if (substr.starts_with(after, false))
return FilePath(path.begin() + i + after.length(), path.end());
}
return path;
}
FilePath Path::normalize(const FilePath& path)
{
FilePath normalized;
auto len = path.length();
for (auto n = 0; n < len; n++)
2020-08-26 15:38:01 +08:00
{
// normalize slashes
if (path[n] == '\\' || path[n] == '/')
{
if (normalized.length() == 0 || normalized[normalized.length() - 1] != '/')
normalized.append('/');
}
// move up a directory
else if (path[n] == '.' && n < len - 1 && path[n + 1] == '.')
{
// search backwards for last /
bool could_move_up = false;
if (normalized.length() > 0)
{
for (auto k = normalized.length() - 1; k > 0; k--)
if (normalized[k - 1] == '/')
{
normalized = normalized.substr(0, k - 1);
could_move_up = true;
break;
}
}
if (!could_move_up)
2020-08-26 15:38:01 +08:00
normalized.append('.');
else
n++;
}
else
normalized.append(path[n]);
}
return normalized;
2021-01-15 10:42:12 +08:00
}
FilePath Path::join(const FilePath& a, const FilePath& b)
{
if (a.length() <= 0)
return normalize(b);
else if (b.length() <= 0)
return normalize(a);
else
return normalize(FilePath(a).append("/").append(b));
2020-08-26 15:38:01 +08:00
}