mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 20:52:37 +01:00
Added make/remove directory functionality.
This commit is contained in:
@@ -6,8 +6,12 @@
|
||||
#ifndef BX_FILEPATH_H_HEADER_GUARD
|
||||
#define BX_FILEPATH_H_HEADER_GUARD
|
||||
|
||||
#include "error.h"
|
||||
#include "string.h"
|
||||
|
||||
BX_ERROR_RESULT(BX_ERROR_ACCESS, BX_MAKEFOURCC('b', 'x', 0, 0) );
|
||||
BX_ERROR_RESULT(BX_ERROR_NOT_DIRECTORY, BX_MAKEFOURCC('b', 'x', 0, 1) );
|
||||
|
||||
namespace bx
|
||||
{
|
||||
const int32_t kMaxFilePath = 1024;
|
||||
@@ -87,6 +91,18 @@ namespace bx
|
||||
char m_filePath[kMaxFilePath];
|
||||
};
|
||||
|
||||
/// Creates a directory named `_filePath`.
|
||||
bool make(const FilePath& _filePath, Error* _err);
|
||||
|
||||
/// Creates a directory named `_filePath` along with all necessary parents.
|
||||
bool makeAll(const FilePath& _filePath, Error* _err);
|
||||
|
||||
/// Removes file or directory.
|
||||
bool remove(const FilePath& _filePath, Error* _err);
|
||||
|
||||
/// Removes file or directory recursivelly.
|
||||
bool removeAll(const FilePath& _filePath, Error* _err);
|
||||
|
||||
} // namespace bx
|
||||
|
||||
#endif // BX_FILEPATH_H_HEADER_GUARD
|
||||
|
||||
146
src/filepath.cpp
146
src/filepath.cpp
@@ -8,10 +8,14 @@
|
||||
#include <bx/os.h>
|
||||
#include <bx/readerwriter.h>
|
||||
|
||||
#include <stdio.h> // remove
|
||||
#include <dirent.h> // opendir
|
||||
|
||||
#if BX_CRT_MSVC
|
||||
# include <direct.h> // _getcwd
|
||||
# include <direct.h> // _getcwd
|
||||
#else
|
||||
# include <unistd.h> // getcwd
|
||||
# include <sys/stat.h> // mkdir
|
||||
# include <unistd.h> // getcwd
|
||||
#endif // BX_CRT_MSVC
|
||||
|
||||
#if BX_PLATFORM_WINDOWS
|
||||
@@ -175,7 +179,7 @@ namespace bx
|
||||
BX_UNUSED(_buffer, _size);
|
||||
return NULL;
|
||||
#elif BX_CRT_MSVC
|
||||
return ::_getcwd(_buffer, (int)_size);
|
||||
return ::_getcwd(_buffer, (int32_t)_size);
|
||||
#else
|
||||
return ::getcwd(_buffer, _size);
|
||||
#endif // BX_COMPILER_
|
||||
@@ -380,4 +384,140 @@ namespace bx
|
||||
;
|
||||
}
|
||||
|
||||
bool make(const FilePath& _filePath, Error* _err)
|
||||
{
|
||||
BX_ERROR_SCOPE(_err);
|
||||
|
||||
if (!_err->isOk() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#if BX_CRT_MSVC
|
||||
int32_t result = ::_mkdir(_filePath.get() );
|
||||
#else
|
||||
int32_t result = ::mkdir(_filePath.get(), 0700);
|
||||
#endif // BX_CRT_MSVC
|
||||
|
||||
if (0 != result)
|
||||
{
|
||||
BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool makeAll(const FilePath& _filePath, Error* _err)
|
||||
{
|
||||
BX_ERROR_SCOPE(_err);
|
||||
|
||||
if (!_err->isOk() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
FileInfo fi;
|
||||
|
||||
if (stat(_filePath, fi) )
|
||||
{
|
||||
if (FileInfo::Directory == fi.m_type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const StringView dir = strRTrim(_filePath.get(), "/");
|
||||
const char* slash = strRFind(dir, '/');
|
||||
|
||||
if (NULL != slash
|
||||
&& slash - dir.getPtr() > 1)
|
||||
{
|
||||
if (!makeAll(StringView(dir.getPtr(), slash), _err) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FilePath path(dir);
|
||||
return make(path, _err);
|
||||
}
|
||||
|
||||
bool remove(const FilePath& _filePath, Error* _err)
|
||||
{
|
||||
BX_ERROR_SCOPE(_err);
|
||||
|
||||
if (!_err->isOk() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t result = ::remove(_filePath.get() );
|
||||
|
||||
if (0 != result)
|
||||
{
|
||||
BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool removeAll(const FilePath& _filePath, Error* _err)
|
||||
{
|
||||
BX_ERROR_SCOPE(_err);
|
||||
|
||||
if (remove(_filePath, _err) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
_err->reset();
|
||||
|
||||
FileInfo fi;
|
||||
|
||||
if (!stat(_filePath, fi) )
|
||||
{
|
||||
BX_ERROR_SET(_err, BX_ERROR_ACCESS, "The parent directory does not allow write permission to the process.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (FileInfo::Directory != fi.m_type)
|
||||
{
|
||||
BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
DIR* dir = opendir(_filePath.get() );
|
||||
if (NULL == dir)
|
||||
{
|
||||
BX_ERROR_SET(_err, BX_ERROR_NOT_DIRECTORY, "File already exist, and is not directory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (dirent* item = readdir(dir); NULL != item; item = readdir(dir) )
|
||||
{
|
||||
if (0 == strCmp(item->d_name, ".")
|
||||
|| 0 == strCmp(item->d_name, "..") )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
FilePath path(_filePath);
|
||||
path.join(item->d_name);
|
||||
if (!removeAll(path, _err) )
|
||||
{
|
||||
_err->reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
return remove(_filePath, _err);
|
||||
}
|
||||
|
||||
} // namespace bx
|
||||
|
||||
@@ -69,8 +69,8 @@ const char* Settings::get(const StringView& _name) const
|
||||
ini_t* ini = INI_T(m_ini);
|
||||
|
||||
FilePath uri(_name);
|
||||
const StringView path = strTrim(uri.getPath(), "/");
|
||||
const StringView& fileName = uri.getFileName();
|
||||
const StringView path(strTrim(uri.getPath(), "/") );
|
||||
const StringView& fileName(uri.getFileName() );
|
||||
int32_t section = INI_GLOBAL_SECTION;
|
||||
|
||||
if (!path.isEmpty() )
|
||||
@@ -96,8 +96,8 @@ void Settings::set(const StringView& _name, const StringView& _value)
|
||||
ini_t* ini = INI_T(m_ini);
|
||||
|
||||
FilePath uri(_name);
|
||||
const StringView path = strTrim(uri.getPath(), "/");
|
||||
const StringView& fileName = uri.getFileName();
|
||||
const StringView path(strTrim(uri.getPath(), "/") );
|
||||
const StringView& fileName(uri.getFileName() );
|
||||
|
||||
int32_t section = INI_GLOBAL_SECTION;
|
||||
|
||||
|
||||
@@ -446,6 +446,7 @@ namespace bx
|
||||
const char* ptr = _str.getPtr();
|
||||
const char* chars = _chars.getPtr();
|
||||
const uint32_t charsLen = _chars.getLength();
|
||||
|
||||
for (uint32_t ii = 0, len = _str.getLength(); ii < len; ++ii)
|
||||
{
|
||||
if (NULL == strFindUnsafe(chars, charsLen, ptr[ii]) )
|
||||
@@ -459,6 +460,11 @@ namespace bx
|
||||
|
||||
StringView strRTrim(const StringView& _str, const StringView& _chars)
|
||||
{
|
||||
if (_str.isEmpty() )
|
||||
{
|
||||
return StringView();
|
||||
}
|
||||
|
||||
const char* ptr = _str.getPtr();
|
||||
const char* chars = _chars.getPtr();
|
||||
const uint32_t charsLen = _chars.getLength();
|
||||
|
||||
@@ -123,4 +123,14 @@ TEST_CASE("FilePath temp", "")
|
||||
{
|
||||
bx::FilePath tmp(bx::Dir::Temp);
|
||||
REQUIRE(0 != bx::strCmp(".", tmp.getPath().getPtr() ) );
|
||||
|
||||
bx::Error err;
|
||||
tmp.join("test/abvgd/555333/test");
|
||||
REQUIRE(bx::makeAll(tmp, &err) );
|
||||
REQUIRE(err.isOk() );
|
||||
|
||||
tmp.set(bx::Dir::Temp);
|
||||
tmp.join("test");
|
||||
REQUIRE(bx::removeAll(tmp, &err) );
|
||||
REQUIRE(err.isOk() );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user