[DEV] path and filesystem start to be good
This commit is contained in:
parent
5a1160fb89
commit
f6ffdb9b25
@ -28,7 +28,7 @@ void etk::unInit() {
|
|||||||
nbTimeInit = 0;
|
nbTimeInit = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
etk::theme::uninit();
|
etk::theme::unInit();
|
||||||
TK_INFO("ETK system un-init (BEGIN)");
|
TK_INFO("ETK system un-init (BEGIN)");
|
||||||
ETK_MEM_SHOW_LOG();
|
ETK_MEM_SHOW_LOG();
|
||||||
TK_INFO("ETK system un-init (END)");
|
TK_INFO("ETK system un-init (END)");
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
#include <etk/fileSystem/Path.hpp>
|
#include <etk/fileSystem/Path.hpp>
|
||||||
#include <etk/log.hpp>
|
#include <etk/debug.hpp>
|
||||||
|
#include <etk/Exception.hpp>
|
||||||
|
|
||||||
#include <etk/typeInfo.hpp>
|
#include <etk/typeInfo.hpp>
|
||||||
ETK_DECLARE_TYPE(etk::Path);
|
ETK_DECLARE_TYPE(etk::Path);
|
||||||
@ -12,183 +13,204 @@ ETK_DECLARE_TYPE(etk::Path);
|
|||||||
//#define TK_DBG_MODE TK_VERBOSE
|
//#define TK_DBG_MODE TK_VERBOSE
|
||||||
#define TK_DBG_MODE TK_WARNING
|
#define TK_DBG_MODE TK_WARNING
|
||||||
|
|
||||||
static etk::Pair<etk::fileSystem::Type, etk::String> parsePath(etk::String _path) {
|
|
||||||
// Reset ALL DATA :
|
static etk::String simplifyPath(etk::String _input) {
|
||||||
m_data = "";
|
// step 1 : for windows change \ in /:
|
||||||
m_type = etk::fileSystem::Type::Unknow;
|
TK_DEBUG("Simplify(1) : '" << _input << "'");
|
||||||
TK_DBG_MODE("1 : Set Name : \"" << _path << "\"");
|
size_t currentPos = 0;
|
||||||
#ifdef __TARGET_OS__Windows
|
if (_input.size() == 0) {
|
||||||
_path.replace("\\", "/");
|
return _input;
|
||||||
for (char iii='a' ; iii<='z' ; iii++) {
|
}
|
||||||
char tmpVal[10];
|
while(currentPos < _input.size()) {
|
||||||
char tmpDest[10];
|
if (_input[currentPos] == '\\') {
|
||||||
sprintf(tmpVal, "%c:/", iii);
|
_input[currentPos] = '/';
|
||||||
sprintf(tmpDest, "/%c/", iii);
|
|
||||||
if(etk::start_with(_path, tmpVal) == true) {
|
|
||||||
_path.replace(tmpVal, tmpDest);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (char iii='A' ; iii<='Z' ; iii++) {
|
currentPos++;
|
||||||
char tmpVal[10];
|
continue;
|
||||||
char tmpDest[10];
|
}
|
||||||
sprintf(tmpVal, "%c:/", iii);
|
// step 2 : remove all '//'
|
||||||
sprintf(tmpDest, "/%c/", iii+'a'-'A');
|
TK_DBG_MODE("Simplify(2) : '" << _input << "'");
|
||||||
if(etk::start_with(_path, tmpVal) == true) {
|
currentPos = 0;
|
||||||
_path.replace(tmpVal, tmpDest);
|
if (_input.size() <= 1) {
|
||||||
break;
|
return _input;
|
||||||
|
}
|
||||||
|
while(currentPos < _input.size()-1) {
|
||||||
|
if ( _input[currentPos] != '/'
|
||||||
|
|| _input[currentPos+1] != '/') {
|
||||||
|
currentPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_input.erase(currentPos, 1);
|
||||||
|
}
|
||||||
|
// step 3 : remove all '/./'
|
||||||
|
TK_DBG_MODE("Simplify(3) : '" << _input << "'");
|
||||||
|
currentPos = 0;
|
||||||
|
if (_input.size() <= 1) {
|
||||||
|
return _input;
|
||||||
|
}
|
||||||
|
while( currentPos < _input.size()-2
|
||||||
|
&& _input.size() > 2) {
|
||||||
|
if ( _input[currentPos] != '/'
|
||||||
|
|| _input[currentPos+1] != '.'
|
||||||
|
|| _input[currentPos+2] != '/') {
|
||||||
|
currentPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_input.erase(currentPos, 2);
|
||||||
|
}
|
||||||
|
if (end_with(_input, "/.") == true) {
|
||||||
|
_input.erase(_input.size()-1, 1);
|
||||||
|
}
|
||||||
|
// step 4 remove xxx/..
|
||||||
|
TK_DBG_MODE("Simplify(4) : '" << _input << "'");
|
||||||
|
size_t lastSlashPos = etk::String::npos;
|
||||||
|
currentPos = 0;
|
||||||
|
while( currentPos < _input.size()-2
|
||||||
|
&& _input.size() > 2) {
|
||||||
|
if ( _input[currentPos] != '/'
|
||||||
|
|| _input[currentPos+1] != '.'
|
||||||
|
|| _input[currentPos+2] != '.') {
|
||||||
|
if (_input[currentPos] == '/') {
|
||||||
|
lastSlashPos = currentPos;
|
||||||
}
|
}
|
||||||
|
currentPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (lastSlashPos == etk::String::npos) {
|
||||||
|
currentPos++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_input.erase(lastSlashPos, currentPos+2-lastSlashPos+1);
|
||||||
|
TK_DEBUG("update : '" << _input << "'");
|
||||||
|
lastSlashPos = etk::String::npos;
|
||||||
|
currentPos = 0;
|
||||||
|
}
|
||||||
|
TK_DBG_MODE("Simplify(5) : '" << _input << "'");
|
||||||
|
if (_input.size() == 0) {
|
||||||
|
_input = "/";
|
||||||
|
}
|
||||||
|
#ifdef __TARGET_OS__Windows
|
||||||
|
etk::String base;
|
||||||
|
base += _input[0];
|
||||||
|
base += ":";
|
||||||
|
if ( _input == base + "/../"
|
||||||
|
|| _input == base + "/.."
|
||||||
|
|| _input == base + "/./"
|
||||||
|
|| _input == base + "/."
|
||||||
|
|| _input == "/") {
|
||||||
|
_input = base + "/";
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if ( _input == "/../"
|
||||||
|
|| _input == "/.."
|
||||||
|
|| _input == "/./"
|
||||||
|
|| _input == "/.") {
|
||||||
|
_input = "/";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// generate destination name in case of the input error
|
TK_DEBUG("Simplify(end) : '" << _input << "'");
|
||||||
if (_path.size() == 0) {
|
return _input;
|
||||||
// if no name ==> go to the root Folder
|
|
||||||
_path = "ROOT:";
|
|
||||||
}
|
|
||||||
if (_path[0] == '/') {
|
|
||||||
TK_DBG_MODE(" ==> detect root");
|
|
||||||
_path.erase(0, 1);
|
|
||||||
m_type = etk::fileSystem::Type::Direct;
|
|
||||||
} else if (start_with(_path, "ROOT:", false) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect root 2 ");
|
|
||||||
_path.erase(0, 5);
|
|
||||||
m_type = etk::fileSystem::Type::Direct;
|
|
||||||
if(start_with(_path, "~") == true) {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
m_type = etk::fileSystem::Type::Home;
|
|
||||||
}
|
|
||||||
} else if (start_with(_path, "DIRECT:", false) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect direct");
|
|
||||||
_path.erase(0, 7);
|
|
||||||
m_type = etk::fileSystem::Type::Direct;
|
|
||||||
if(start_with(_path, "~") == true) {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
m_type = etk::fileSystem::Type::Home;
|
|
||||||
}
|
|
||||||
} else if (start_with(_path, "DATA:", false) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect data");
|
|
||||||
_path.erase(0, 5);
|
|
||||||
m_type = etk::fileSystem::Type::Data;
|
|
||||||
} else if (start_with(_path, "USERDATA:", false) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect User-data");
|
|
||||||
_path.erase(0, 9);
|
|
||||||
m_type = etk::fileSystem::Type::UserData;
|
|
||||||
} else if (start_with(_path, "CACHE:", false) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect Cache");
|
|
||||||
_path.erase(0, 6);
|
|
||||||
m_type = etk::fileSystem::Type::Cache;
|
|
||||||
} else if (start_with(_path, "THEME:", false) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect theme");
|
|
||||||
_path.erase(0, 6);
|
|
||||||
m_type = etk::fileSystem::Type::Theme;
|
|
||||||
} else if (start_with(_path, "./") == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect relatif 1");
|
|
||||||
_path.erase(0, 2);
|
|
||||||
while (_path.size()>0 && _path[0] == '/') {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
}
|
|
||||||
m_type = etk::FSNType_relatif;
|
|
||||||
} else if (start_with(_path, "REL:", false) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect relatif 2");
|
|
||||||
_path.erase(0, 4);
|
|
||||||
while (_path.size()>0 && _path[0] == '/') {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
}
|
|
||||||
m_type = etk::FSNType_relatif;
|
|
||||||
} else if (start_with(_path, baseRunPath) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect relatif 3 (run path=" << baseRunPath << ")");
|
|
||||||
_path.erase(0, baseRunPath.size());
|
|
||||||
while (_path.size()>0 && _path[0] == '/') {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
}
|
|
||||||
m_type = etk::FSNType_relatif;
|
|
||||||
} else if (( baseRunPath != baseRunPathInHome
|
|
||||||
&& ( start_with(_path, "~" + baseRunPathInHome) == true
|
|
||||||
|| start_with(_path, "HOME:" + baseRunPathInHome, false) == true ) ) ) {
|
|
||||||
TK_DBG_MODE(" ==> detect relatif 4");
|
|
||||||
if (start_with(_path, "~" + baseRunPathInHome) == true) {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
} else {
|
|
||||||
_path.erase(0, 5);
|
|
||||||
}
|
|
||||||
_path.erase(0, baseRunPathInHome.size());
|
|
||||||
while (_path.size()>0 && _path[0] == '/') {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
}
|
|
||||||
m_type = etk::FSNType_relatif;
|
|
||||||
} else if (start_with(_path, "~")) {
|
|
||||||
TK_DBG_MODE(" ==> detect home 2");
|
|
||||||
_path.erase(0, 1);
|
|
||||||
m_type = etk::fileSystem::Type::Home;
|
|
||||||
} else if (start_with(_path, "HOME:", false) == true ) {
|
|
||||||
TK_DBG_MODE(" ==> detect home 3");
|
|
||||||
_path.erase(0, 5);
|
|
||||||
m_type = etk::fileSystem::Type::Home;
|
|
||||||
if(start_with(_path, "~") == true) {
|
|
||||||
_path.erase(0, 1);
|
|
||||||
}
|
|
||||||
} else if (start_with(_path, baseFolderHome) == true) {
|
|
||||||
TK_DBG_MODE(" ==> detect home");
|
|
||||||
_path.erase(0, baseFolderHome.size());
|
|
||||||
m_type = etk::fileSystem::Type::Home;
|
|
||||||
} else {
|
|
||||||
TK_DBG_MODE(" ==> detect other");
|
|
||||||
// nothing to remove
|
|
||||||
//Other type is Relative :
|
|
||||||
m_type = etk::FSNType_relatif;
|
|
||||||
}
|
|
||||||
m_data = _path;
|
|
||||||
TK_DBG_MODE("3 : parse done : [" << m_type << "]->\"" << m_data << "\"");
|
|
||||||
|
|
||||||
// Now we reduce the path with all un-needed ../ and other thinks ...
|
|
||||||
// TODO : Do it whith link and the other sub thinks ...
|
|
||||||
m_userFileName = simplifyPath(m_userFileName);
|
|
||||||
TK_DBG_MODE("4 : Path simplification : [" << m_type << "]->\"" << m_userFileName << "\"");
|
|
||||||
|
|
||||||
// Now we generate the real FS path:
|
|
||||||
generateFileSystemPath();
|
|
||||||
TK_DBG_MODE("5 : file System Real name : \"" << m_systemFileName << "\"");
|
|
||||||
|
|
||||||
// now we get all the right if the file existed:
|
|
||||||
updateFileSystemProperty();
|
|
||||||
TK_DBG_MODE("6 : type : [" << m_typeNode << "] right :" << m_rights);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static etk::String parsePath(etk::String _path) {
|
||||||
|
etk::String out = _path;
|
||||||
|
TK_DBG_MODE("1 : Set Name : '" << out << "'");
|
||||||
|
// Replace all time to prevent Windows user error when port on Unix
|
||||||
|
out.replace("\\", "/");
|
||||||
|
if ( out.size() > 3
|
||||||
|
&& out[1] == ':'
|
||||||
|
&& out[2] == '/') {
|
||||||
|
#ifndef __TARGET_OS__Windows
|
||||||
|
TK_WARNING("Path name have a windows form: '" << _path << "' c:/ but not a windwos platform");
|
||||||
|
#endif
|
||||||
|
if ( out[0] >= 'A'
|
||||||
|
&& out[0] <= 'Z') {
|
||||||
|
out[1] = out[0] + 'a' - 'A';
|
||||||
|
} else {
|
||||||
|
out[1] = out[0];
|
||||||
|
}
|
||||||
|
out[0] = '/';
|
||||||
|
}
|
||||||
|
out = simplifyPath(out);
|
||||||
|
TK_DBG_MODE("3 : parse done : '" << _path << "' ==>\"" << out << "\"");
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
etk::Path::Path(const etk::String& _value) {
|
etk::Path::Path(const etk::String& _value) {
|
||||||
m_type =
|
m_data = parsePath(_value);
|
||||||
m_data =
|
|
||||||
}
|
|
||||||
|
|
||||||
etk::Path::Path(fileSystem::Type _type, const etk::String& _value) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::String etk::Path::getString() const {
|
etk::String etk::Path::getString() const {
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::String etk::Path::getStringWindows() const {
|
||||||
|
etk::String out = m_data;
|
||||||
|
out.replace("/", "\\");
|
||||||
|
if ( out.size() > 3
|
||||||
|
&& out[0] == '/'
|
||||||
|
&& out[2] == '/') {
|
||||||
|
out[0] = out[1];
|
||||||
|
out[0] = ':';
|
||||||
|
}
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::String etk::Path::getRelative() const {
|
etk::String etk::Path::getRelative() const {
|
||||||
|
// TODO : plouf ...
|
||||||
}
|
return "todo";
|
||||||
|
|
||||||
etk::String etk::Path::getDecorated() const {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::String etk::Path::getNative() const {
|
etk::String etk::Path::getNative() const {
|
||||||
|
#ifdef __TARGET_OS__Windows
|
||||||
|
return getStringWindows();
|
||||||
|
#else
|
||||||
|
return getString();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::Path::isRelative() const {
|
||||||
|
if ( m_data.size() >= 1
|
||||||
|
&& m_data[0] != '/') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::Path::isAbsolute() const {
|
||||||
|
if ( m_data.size() >= 1
|
||||||
|
&& m_data[0] == '/') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void etk::Path::parent() {
|
||||||
|
size_t pos = m_data.rfind('/');
|
||||||
|
if (pos == etk::String::npos) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pos == 0) {
|
||||||
|
// Last root element ==> do nothing.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_data = m_data.extract(0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Path etk::Path::getParent() const {
|
||||||
|
etk::Path out = *this;
|
||||||
|
out.parent();
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::Path::operator== (const etk::Path &_obj) const {
|
bool etk::Path::operator== (const etk::Path &_obj) const {
|
||||||
return m_type == _obj.m_type
|
return m_data == _obj.m_data;
|
||||||
&& m_data == _obj.m_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::Path::operator!= (const etk::Path &_obj) const {
|
bool etk::Path::operator!= (const etk::Path &_obj) const {
|
||||||
return m_type != _obj.m_type
|
return m_data != _obj.m_data;
|
||||||
|| m_data != _obj.m_data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::Path etk::Path::operator/ (const etk::String & _element) const {
|
etk::Path etk::Path::operator/ (const etk::String & _element) const {
|
||||||
@ -197,11 +219,33 @@ etk::Path etk::Path::operator/ (const etk::String & _element) const {
|
|||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etk::Path etk::Path::operator/ (const etk::Path & _path) const {
|
||||||
|
etk::Path tmp = *this;
|
||||||
|
tmp /= _path;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
etk::Path& etk::Path::operator/= (const etk::String & _element) {
|
etk::Path& etk::Path::operator/= (const etk::String & _element) {
|
||||||
if (_element.size() == 0) {
|
if (_element.size() == 0) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
m_data += "/" + _element;
|
if (_element[0] == '/') {
|
||||||
|
ETK_THROW_EXCEPTION(etk::exception::InvalidArgument("add path that is absolute"));
|
||||||
|
}
|
||||||
|
m_data += '/' + _element;
|
||||||
|
m_data = simplifyPath(m_data);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Path& etk::Path::operator/= (const etk::Path & _path) {
|
||||||
|
if (_path.m_data.size() == 0) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
if (_path.m_data[0] == '/') {
|
||||||
|
ETK_THROW_EXCEPTION(etk::exception::InvalidArgument("add path that is absolute"));
|
||||||
|
}
|
||||||
|
m_data += '/' + _path.m_data;
|
||||||
|
m_data = simplifyPath(m_data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,6 +260,12 @@ etk::Path& etk::Path::operator+= (const etk::String & _element) {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
m_data += _element;
|
m_data += _element;
|
||||||
|
m_data = simplifyPath(m_data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etk::Stream& etk::operator <<(etk::Stream &_os, const etk::Path &_obj) {
|
||||||
|
_os << _obj.getString();
|
||||||
|
return _os;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <etk/types.hpp>
|
#include <etk/types.hpp>
|
||||||
#include <etk/fileSystem/Type.hpp>
|
#include <etk/fileSystem/Type.hpp>
|
||||||
|
#include <etk/String.hpp>
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
/**
|
/**
|
||||||
@ -15,7 +16,6 @@ namespace etk {
|
|||||||
*/
|
*/
|
||||||
class Path {
|
class Path {
|
||||||
private:
|
private:
|
||||||
fileSystem::Type m_type; //!< the Type of data requested by the User.
|
|
||||||
etk::String m_data; //!< Raw data of the path.
|
etk::String m_data; //!< Raw data of the path.
|
||||||
public:
|
public:
|
||||||
ETK_CONSTRUCTOR_MOVE_DEFAULT(Path);
|
ETK_CONSTRUCTOR_MOVE_DEFAULT(Path);
|
||||||
@ -29,32 +29,47 @@ namespace etk {
|
|||||||
* @param[in] _value Element basic path
|
* @param[in] _value Element basic path
|
||||||
*/
|
*/
|
||||||
Path(const etk::String& _value);
|
Path(const etk::String& _value);
|
||||||
/**
|
|
||||||
* @brief Contructor with basic path.
|
|
||||||
* @param[in] _type type of path
|
|
||||||
* @param[in] _value offset in the path
|
|
||||||
*/
|
|
||||||
Path(fileSystem::Type _type, const etk::String& _value);
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the absolute path
|
* @brief Get the absolute path
|
||||||
* @return string like /home/userXXX/aaa/bbb/*** or /c/userXXX/aaa/bbb/***
|
* @return string like /home/userXXX/aaa/bbb/### or /c/userXXX/aaa/bbb/###
|
||||||
*/
|
*/
|
||||||
etk::String getString() const;
|
etk::String getString() const;
|
||||||
|
/**
|
||||||
|
* @brief Get the absolute path
|
||||||
|
* @return string like /home/userXXX/aaa/bbb/### or /c/userXXX/aaa/bbb/###
|
||||||
|
*/
|
||||||
|
etk::String getStringWindows() const;
|
||||||
/**
|
/**
|
||||||
* @brief Get the relative path.
|
* @brief Get the relative path.
|
||||||
* @return string like ../../aaa/bbb/***
|
* @return string like ../../aaa/bbb/###
|
||||||
*/
|
*/
|
||||||
etk::String getRelative() const;
|
etk::String getRelative() const;
|
||||||
/**
|
|
||||||
* @brief Get the Decorated path.
|
|
||||||
* @return string like DATA:aaa/bbb/***
|
|
||||||
*/
|
|
||||||
etk::String getDecorated() const;
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the absolute path
|
* @brief Get the absolute path
|
||||||
* @return string like /home/userXXX/aaa/bbb/*** or c:\userXXX\aaa\bbb\***
|
* @return string like /home/userXXX/aaa/bbb/### or c:\userXXX\aaa\bbb\###
|
||||||
*/
|
*/
|
||||||
etk::String getNative() const;
|
etk::String getNative() const;
|
||||||
|
/**
|
||||||
|
* @brief Check if the path is relative or not.
|
||||||
|
* @return true The path is relative.
|
||||||
|
* @return false The path is not relative.
|
||||||
|
*/
|
||||||
|
bool isRelative() const;
|
||||||
|
/**
|
||||||
|
* @brief Check if the path is absolute or not.
|
||||||
|
* @return true The path is absolute.
|
||||||
|
* @return false The path is not absolute.
|
||||||
|
*/
|
||||||
|
bool isAbsolute() const;
|
||||||
|
/**
|
||||||
|
* @brief remove the last child element of the path.
|
||||||
|
*/
|
||||||
|
void parent();
|
||||||
|
/**
|
||||||
|
* @brief Get the path of the parent.
|
||||||
|
* @return Parent path.
|
||||||
|
*/
|
||||||
|
etk::Path getParent() const;
|
||||||
/**
|
/**
|
||||||
* @brief Check if the 2 Path are identical.
|
* @brief Check if the 2 Path are identical.
|
||||||
* @param[in] _obj Path to compare.
|
* @param[in] _obj Path to compare.
|
||||||
@ -74,7 +89,11 @@ namespace etk {
|
|||||||
*/
|
*/
|
||||||
Path operator/ (const etk::String & _element) const;
|
Path operator/ (const etk::String & _element) const;
|
||||||
//! @preivious
|
//! @preivious
|
||||||
Path& operator=/ (const etk::String & _element);
|
Path& operator/= (const etk::String & _element);
|
||||||
|
//! @preivious
|
||||||
|
Path operator/ (const etk::Path & _element) const;
|
||||||
|
//! @preivious
|
||||||
|
Path& operator/= (const etk::Path & _element);
|
||||||
/**
|
/**
|
||||||
* @brief Add a subfolder on the current path.
|
* @brief Add a subfolder on the current path.
|
||||||
* @param[in] _element sub folder or file to add.
|
* @param[in] _element sub folder or file to add.
|
||||||
@ -83,8 +102,12 @@ namespace etk {
|
|||||||
Path operator+ (const etk::String & _element) const;
|
Path operator+ (const etk::String & _element) const;
|
||||||
//! @preivious
|
//! @preivious
|
||||||
Path& operator+= (const etk::String & _element);
|
Path& operator+= (const etk::String & _element);
|
||||||
|
//! @preivious
|
||||||
|
Path operator+ (const etk::Path & _element) const;
|
||||||
|
//! @preivious
|
||||||
|
Path& operator+= (const etk::Path & _element);
|
||||||
};
|
};
|
||||||
|
//! @not_in_doc
|
||||||
|
etk::Stream& operator <<(etk::Stream &_os, const etk::Path &_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,11 @@
|
|||||||
#include <etk/os/FSNodeRight.hpp>
|
#include <etk/os/FSNodeRight.hpp>
|
||||||
#include <etk/stdTools.hpp>
|
#include <etk/stdTools.hpp>
|
||||||
#include <etk/typeInfo.hpp>
|
#include <etk/typeInfo.hpp>
|
||||||
|
#include <etk/fileSystem/Permissions.hpp>
|
||||||
|
|
||||||
|
|
||||||
#include <etk/typeInfo.hpp>
|
#include <etk/typeInfo.hpp>
|
||||||
ETK_DECLARE_TYPE(etk::filesystem::Permissions);
|
ETK_DECLARE_TYPE(etk::fileSystem::Permissions);
|
||||||
|
|
||||||
|
|
||||||
// Right Flags:
|
// Right Flags:
|
||||||
@ -27,44 +28,42 @@ enum {
|
|||||||
right_user_read = 1 << 8,
|
right_user_read = 1 << 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
ETK_DECLARE_TYPE(etk::filesystem::Permissions);
|
etk::fileSystem::Permissions::Permissions(uint16_t _newRight) :
|
||||||
|
|
||||||
etk::filesystem::Permissions::Permissions(uint16_t _newRight) :
|
|
||||||
m_rights(_newRight&0x01FF) {
|
m_rights(_newRight&0x01FF) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t etk::filesystem::Permissions::getRight() const {
|
uint16_t etk::fileSystem::Permissions::getRightValue() const {
|
||||||
return m_rights;
|
return m_rights;
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::filesystem::Permissions& etk::filesystem::Permissions::operator= (const etk::filesystem::Permissions &_obj ) {
|
etk::fileSystem::Permissions& etk::fileSystem::Permissions::operator= (const etk::fileSystem::Permissions &_obj ) {
|
||||||
m_rights = _obj.m_rights;
|
m_rights = _obj.m_rights;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::filesystem::Permissions& etk::filesystem::Permissions::operator= (const uint32_t _newVal) {
|
etk::fileSystem::Permissions& etk::fileSystem::Permissions::operator= (const uint32_t _newVal) {
|
||||||
m_rights = _newVal&0x01FF;
|
m_rights = _newVal&0x01FF;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::clear() {
|
void etk::fileSystem::Permissions::clear() {
|
||||||
m_rights = 0;
|
m_rights = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isUserReadable() const {
|
bool etk::fileSystem::Permissions::isUserReadable() const {
|
||||||
return ((m_rights&right_user_read)!=0)?true:false;
|
return ((m_rights&right_user_read)!=0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isUserWritable() const {
|
bool etk::fileSystem::Permissions::isUserWritable() const {
|
||||||
return ((m_rights&right_user_write)!=0)?true:false;
|
return ((m_rights&right_user_write)!=0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isUserRunable() const {
|
bool etk::fileSystem::Permissions::isUserRunable() const {
|
||||||
return ((m_rights&right_user_execute)!=0)?true:false;
|
return ((m_rights&right_user_execute)!=0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setUserReadable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setUserReadable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_user_read);
|
m_rights &= (0xFFFFFFFF - right_user_read);
|
||||||
if (_newStatus == true) {
|
if (_newStatus == true) {
|
||||||
@ -72,7 +71,7 @@ void etk::filesystem::Permissions::setUserReadable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setUserWritable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setUserWritable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_user_write);
|
m_rights &= (0xFFFFFFFF - right_user_write);
|
||||||
if (_newStatus == true) {
|
if (_newStatus == true) {
|
||||||
@ -80,7 +79,7 @@ void etk::filesystem::Permissions::setUserWritable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setUserRunable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setUserRunable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_user_execute);
|
m_rights &= (0xFFFFFFFF - right_user_execute);
|
||||||
if (_newStatus == true) {
|
if (_newStatus == true) {
|
||||||
@ -88,19 +87,19 @@ void etk::filesystem::Permissions::setUserRunable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isGroupReadable() const {
|
bool etk::fileSystem::Permissions::isGroupReadable() const {
|
||||||
return ((m_rights&right_group_read)!=0)?true:false;
|
return ((m_rights&right_group_read)!=0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isGroupWritable() const {
|
bool etk::fileSystem::Permissions::isGroupWritable() const {
|
||||||
return ((m_rights&right_group_write)!=0)?true:false;
|
return ((m_rights&right_group_write)!=0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isGroupRunable() const {
|
bool etk::fileSystem::Permissions::isGroupRunable() const {
|
||||||
return ((m_rights&right_group_execute)!=0)?true:false;
|
return ((m_rights&right_group_execute)!=0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setGroupReadable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setGroupReadable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_group_read);
|
m_rights &= (0xFFFFFFFF - right_group_read);
|
||||||
if (true == _newStatus) {
|
if (true == _newStatus) {
|
||||||
@ -108,7 +107,7 @@ void etk::filesystem::Permissions::setGroupReadable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setGroupWritable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setGroupWritable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_group_write);
|
m_rights &= (0xFFFFFFFF - right_group_write);
|
||||||
if (true == _newStatus) {
|
if (true == _newStatus) {
|
||||||
@ -116,7 +115,7 @@ void etk::filesystem::Permissions::setGroupWritable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setGroupRunable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setGroupRunable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_group_execute);
|
m_rights &= (0xFFFFFFFF - right_group_execute);
|
||||||
if (true == _newStatus) {
|
if (true == _newStatus) {
|
||||||
@ -124,19 +123,19 @@ void etk::filesystem::Permissions::setGroupRunable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isOtherReadable() const {
|
bool etk::fileSystem::Permissions::isOtherReadable() const {
|
||||||
return ((m_rights&right_other_read) != 0)?true:false;
|
return ((m_rights&right_other_read) != 0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isOtherWritable() const {
|
bool etk::fileSystem::Permissions::isOtherWritable() const {
|
||||||
return ((m_rights&right_other_write) != 0)?true:false;
|
return ((m_rights&right_other_write) != 0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool etk::filesystem::Permissions::isOtherRunable() const {
|
bool etk::fileSystem::Permissions::isOtherRunable() const {
|
||||||
return ((m_rights&right_other_execute) != 0)?true:false;
|
return ((m_rights&right_other_execute) != 0)?true:false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setOtherReadable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setOtherReadable(bool _newStatus) {
|
||||||
// reset the flag:
|
// reset the flag:
|
||||||
m_rights &= (0xFFFFFFFF - right_other_read);
|
m_rights &= (0xFFFFFFFF - right_other_read);
|
||||||
if (_newStatus == true) {
|
if (_newStatus == true) {
|
||||||
@ -144,7 +143,7 @@ void etk::filesystem::Permissions::setOtherReadable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setOtherWritable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setOtherWritable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_other_write);
|
m_rights &= (0xFFFFFFFF - right_other_write);
|
||||||
if (_newStatus == true) {
|
if (_newStatus == true) {
|
||||||
@ -152,7 +151,7 @@ void etk::filesystem::Permissions::setOtherWritable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::filesystem::Permissions::setOtherRunable(bool _newStatus) {
|
void etk::fileSystem::Permissions::setOtherRunable(bool _newStatus) {
|
||||||
// reset the flag :
|
// reset the flag :
|
||||||
m_rights &= (0xFFFFFFFF - right_other_execute);
|
m_rights &= (0xFFFFFFFF - right_other_execute);
|
||||||
if (_newStatus == true) {
|
if (_newStatus == true) {
|
||||||
@ -160,7 +159,7 @@ void etk::filesystem::Permissions::setOtherRunable(bool _newStatus) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::String etk::filesystem::Permissions::getRight() const {
|
etk::String etk::fileSystem::Permissions::getRight() const {
|
||||||
etk::String tmp;
|
etk::String tmp;
|
||||||
if (isUserReadable() == true) {
|
if (isUserReadable() == true) {
|
||||||
tmp += "r";
|
tmp += "r";
|
||||||
@ -211,7 +210,7 @@ etk::String etk::filesystem::Permissions::getRight() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
etk::Stream& etk::operator <<(etk::Stream &_os, const etk::filesystem::Permissions &_obj) {
|
etk::Stream& etk::operator <<(etk::Stream &_os, const etk::fileSystem::Permissions &_obj) {
|
||||||
_os << _obj.getRight();
|
_os << _obj.getRight();
|
||||||
return _os;
|
return _os;
|
||||||
};
|
};
|
||||||
|
@ -11,146 +11,148 @@
|
|||||||
#include <etk/String.hpp>
|
#include <etk/String.hpp>
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
/**
|
namespace fileSystem {
|
||||||
* @brief File System Right management
|
/**
|
||||||
*/
|
* @brief File System Right management
|
||||||
class Permissions {
|
*/
|
||||||
private:
|
class Permissions {
|
||||||
uint16_t m_rights; //!< right manage in a bit field
|
private:
|
||||||
public:
|
uint16_t m_rights; //!< right manage in a bit field
|
||||||
/**
|
public:
|
||||||
* @brief Right contructor.
|
/**
|
||||||
* @param[in] _newRight Right to set by default
|
* @brief Right contructor.
|
||||||
*/
|
* @param[in] _newRight Right to set by default
|
||||||
Permissions(uint16_t _newRight = 0);
|
*/
|
||||||
/**
|
Permissions(uint16_t _newRight = 0);
|
||||||
* @brief Get Raw right
|
/**
|
||||||
* @return the internal value.
|
* @brief Get Raw right
|
||||||
*/
|
* @return the internal value.
|
||||||
uint16_t getRight() const;
|
*/
|
||||||
/**
|
uint16_t getRightValue() const;
|
||||||
* @brief Copy asignement operator (operator=)
|
/**
|
||||||
* @param[in] _obj Object to copy
|
* @brief Copy asignement operator (operator=)
|
||||||
* @return Local reference on the object
|
* @param[in] _obj Object to copy
|
||||||
*/
|
* @return Local reference on the object
|
||||||
etk::filesystem::Permissions& operator= (const etk::filesystem::Permissions &_obj);
|
*/
|
||||||
/**
|
Permissions& operator= (const Permissions &_obj);
|
||||||
* @brief Asignement operator (operator=)
|
/**
|
||||||
* @param[in] _newVal Value to set on the right
|
* @brief Asignement operator (operator=)
|
||||||
* @return Local reference on the object
|
* @param[in] _newVal Value to set on the right
|
||||||
*/
|
* @return Local reference on the object
|
||||||
etk::filesystem::Permissions& operator= (const uint32_t _newVal );
|
*/
|
||||||
/**
|
Permissions& operator= (const uint32_t _newVal );
|
||||||
* @brief Clear right (set the value at 0 ==> cant not be read/write/execute
|
/**
|
||||||
*/
|
* @brief Clear right (set the value at 0 ==> cant not be read/write/execute
|
||||||
void clear();
|
*/
|
||||||
/**
|
void clear();
|
||||||
* @brief Get the "Read status" for the "User"
|
/**
|
||||||
* @return true The file/folder/... is readable
|
* @brief Get the "Read status" for the "User"
|
||||||
* @return false The file/folder/... is NOT readable
|
* @return true The file/folder/... is readable
|
||||||
*/
|
* @return false The file/folder/... is NOT readable
|
||||||
bool isUserReadable() const;
|
*/
|
||||||
/**
|
bool isUserReadable() const;
|
||||||
* @brief Get the "Write status" for the "User"
|
/**
|
||||||
* @return true The file/folder/... is writable
|
* @brief Get the "Write status" for the "User"
|
||||||
* @return false The file/folder/... is NOT writable
|
* @return true The file/folder/... is writable
|
||||||
*/
|
* @return false The file/folder/... is NOT writable
|
||||||
bool isUserWritable() const;
|
*/
|
||||||
/**
|
bool isUserWritable() const;
|
||||||
* @brief Get the "execute status" for the "User"
|
/**
|
||||||
* @return true The file/folder/... is executable
|
* @brief Get the "execute status" for the "User"
|
||||||
* @return false The file/folder/... is NOT executable
|
* @return true The file/folder/... is executable
|
||||||
*/
|
* @return false The file/folder/... is NOT executable
|
||||||
bool isUserRunable() const;
|
*/
|
||||||
/**
|
bool isUserRunable() const;
|
||||||
* @brief Set the "Read status" for the "User"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Read status" for the "User"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setUserReadable(bool _newStatus);
|
*/
|
||||||
/**
|
void setUserReadable(bool _newStatus);
|
||||||
* @brief Set the "Write status" for the "User"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Write status" for the "User"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setUserWritable(bool _newStatus);
|
*/
|
||||||
/**
|
void setUserWritable(bool _newStatus);
|
||||||
* @brief Set the "execute status" for the "User"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "execute status" for the "User"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setUserRunable(bool _newStatus);
|
*/
|
||||||
/**
|
void setUserRunable(bool _newStatus);
|
||||||
* @brief Get the "Read status" for the "Group"
|
/**
|
||||||
* @return true The file/folder/... is readable
|
* @brief Get the "Read status" for the "Group"
|
||||||
* @return false The file/folder/... is NOT readable
|
* @return true The file/folder/... is readable
|
||||||
*/
|
* @return false The file/folder/... is NOT readable
|
||||||
bool isGroupReadable() const;
|
*/
|
||||||
/**
|
bool isGroupReadable() const;
|
||||||
* @brief Get the "Write status" for the "Group"
|
/**
|
||||||
* @return true The file/folder/... is writable
|
* @brief Get the "Write status" for the "Group"
|
||||||
* @return false The file/folder/... is NOT writable
|
* @return true The file/folder/... is writable
|
||||||
*/
|
* @return false The file/folder/... is NOT writable
|
||||||
bool isGroupWritable() const;
|
*/
|
||||||
/**
|
bool isGroupWritable() const;
|
||||||
* @brief Get the "execute status" for the "Group"
|
/**
|
||||||
* @return true The file/folder/... is executable
|
* @brief Get the "execute status" for the "Group"
|
||||||
* @return false The file/folder/... is NOT executable
|
* @return true The file/folder/... is executable
|
||||||
*/
|
* @return false The file/folder/... is NOT executable
|
||||||
bool isGroupRunable() const;
|
*/
|
||||||
/**
|
bool isGroupRunable() const;
|
||||||
* @brief Set the "Read status" for the "Group"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Read status" for the "Group"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setGroupReadable(bool _newStatus);
|
*/
|
||||||
/**
|
void setGroupReadable(bool _newStatus);
|
||||||
* @brief Set the "Write status" for the "Group"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Write status" for the "Group"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setGroupWritable(bool _newStatus);
|
*/
|
||||||
/**
|
void setGroupWritable(bool _newStatus);
|
||||||
* @brief Set the "Execute status" for the "Group"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Execute status" for the "Group"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setGroupRunable(bool _newStatus);
|
*/
|
||||||
/**
|
void setGroupRunable(bool _newStatus);
|
||||||
* @brief Get the "Read status" for the "Other"
|
/**
|
||||||
* @return true The file/folder/... is readable
|
* @brief Get the "Read status" for the "Other"
|
||||||
* @return false The file/folder/... is NOT readable
|
* @return true The file/folder/... is readable
|
||||||
*/
|
* @return false The file/folder/... is NOT readable
|
||||||
bool isOtherReadable() const;
|
*/
|
||||||
/**
|
bool isOtherReadable() const;
|
||||||
* @brief Get the "Write status" for the "Other"
|
/**
|
||||||
* @return true The file/folder/... is writable
|
* @brief Get the "Write status" for the "Other"
|
||||||
* @return false The file/folder/... is NOT writable
|
* @return true The file/folder/... is writable
|
||||||
*/
|
* @return false The file/folder/... is NOT writable
|
||||||
bool isOtherWritable() const;
|
*/
|
||||||
/**
|
bool isOtherWritable() const;
|
||||||
* @brief Get the "execute status" for the "Other"
|
/**
|
||||||
* @return true The file/folder/... is executable
|
* @brief Get the "execute status" for the "Other"
|
||||||
* @return false The file/folder/... is NOT executable
|
* @return true The file/folder/... is executable
|
||||||
*/
|
* @return false The file/folder/... is NOT executable
|
||||||
bool isOtherRunable() const;
|
*/
|
||||||
/**
|
bool isOtherRunable() const;
|
||||||
* @brief Set the "Read status" for the "Other"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Read status" for the "Other"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setOtherReadable(bool _newStatus);
|
*/
|
||||||
/**
|
void setOtherReadable(bool _newStatus);
|
||||||
* @brief Set the "Write status" for the "Other"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Write status" for the "Other"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setOtherWritable(bool _newStatus);
|
*/
|
||||||
/**
|
void setOtherWritable(bool _newStatus);
|
||||||
* @brief Set the "Execute status" for the "Other"
|
/**
|
||||||
* @param[in] _newStatus New value to set on the file/folder/...
|
* @brief Set the "Execute status" for the "Other"
|
||||||
*/
|
* @param[in] _newStatus New value to set on the file/folder/...
|
||||||
void setOtherRunable(bool _newStatus);
|
*/
|
||||||
/**
|
void setOtherRunable(bool _newStatus);
|
||||||
* @brief Get the write written in a string mode (like in linux rw-r-----)
|
/**
|
||||||
* @return String with the right in string
|
* @brief Get the write written in a string mode (like in linux rw-r-----)
|
||||||
*/
|
* @return String with the right in string
|
||||||
etk::String getRight() const;
|
*/
|
||||||
};
|
etk::String getRight() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
//! @not_in_doc
|
//! @not_in_doc
|
||||||
etk::Stream& operator <<(etk::Stream &_os, const etk::filesystem::Permissions &_obj);
|
etk::Stream& operator <<(etk::Stream &_os, const etk::fileSystem::Permissions &_obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
#include <etk/types.hpp>
|
#include <etk/types.hpp>
|
||||||
#include <etk/filesystem/Type.hpp>
|
#include <etk/fileSystem/Type.hpp>
|
||||||
|
|
||||||
etk::Stream& etk::operator <<(etk::Stream &_os, const enum etk::fileSystem::Type &_obj) {
|
etk::Stream& etk::operator <<(etk::Stream &_os, const enum etk::fileSystem::Type &_obj) {
|
||||||
switch (_obj) {
|
switch (_obj) {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <etk/types.hpp>
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/Stream.hpp>
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
#include <etk/fileSystem/fileSystem.hpp>
|
#include <etk/fileSystem/fileSystem.hpp>
|
||||||
#include <etk/log.hpp>
|
#include <etk/debug.hpp>
|
||||||
|
|
||||||
#ifdef __TARGET_OS__Windows
|
#ifdef __TARGET_OS__Windows
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
@ -17,47 +17,127 @@ extern "C" {
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
}
|
}
|
||||||
|
namespace etk {
|
||||||
void etk::fileSystem::copy(const etk::Path& _path1, const etk::Path& _path2) {
|
static int32_t mkdir(const char* _path, mode_t _mode) {
|
||||||
|
struct stat st;
|
||||||
|
int32_t status = 0;
|
||||||
|
if (stat(_path, &st) != 0) {
|
||||||
|
/* Directory does not exist. EEXIST for race condition */
|
||||||
|
#ifdef __TARGET_OS__Windows
|
||||||
|
if(0!=::mkdir(_path)
|
||||||
|
#else
|
||||||
|
if(0!=::mkdir(_path, _mode)
|
||||||
|
#endif
|
||||||
|
&& errno != EEXIST) {
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
|
} else if (!S_ISDIR(st.st_mode)) {
|
||||||
|
errno = ENOTDIR;
|
||||||
|
status = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
static int32_t mkPath(const char* _path, mode_t _mode) {
|
||||||
|
char *pp;
|
||||||
|
char *sp;
|
||||||
|
int status;
|
||||||
|
char *copypath = strdup(_path);
|
||||||
|
if (copypath == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
status = 0;
|
||||||
|
pp = copypath;
|
||||||
|
while (status == 0 && (sp = strchr(pp, '/')) != 0) {
|
||||||
|
if (sp != pp) {
|
||||||
|
/* Neither root nor double slash in path */
|
||||||
|
*sp = '\0';
|
||||||
|
status = etk::mkdir(copypath, _mode);
|
||||||
|
*sp = '/';
|
||||||
|
}
|
||||||
|
pp = sp + 1;
|
||||||
|
}
|
||||||
|
if (status == 0) {
|
||||||
|
status = etk::mkdir(_path, _mode);
|
||||||
|
}
|
||||||
|
free(copypath);
|
||||||
|
return (status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::fileSystem::copyDirectory(const etk::Path& _path1, const etk::Path& _path2, bool _recursive) {
|
bool etk::fileSystem::copy(const etk::Path& _path1, const etk::Path& _path2) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::fileSystem::copyFile(const etk::Path& _path1, const etk::Path& _path2) {
|
bool etk::fileSystem::copyDirectory(const etk::Path& _path1, const etk::Path& _path2, bool _recursive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::fileSystem::copyFile(const etk::Path& _path1, const etk::Path& _path2) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void etk::fileSystem::move(const etk::Path& _path1, const etk::Path& _path2) {
|
bool etk::fileSystem::move(const etk::Path& _path1, const etk::Path& _path2) {
|
||||||
|
if (etk::fileSystem::exist(_path2) == true) {
|
||||||
|
remove(_path2);
|
||||||
|
}
|
||||||
|
TK_DEBUG("Move : \"" << _path1 << "\" ==> \"" << _path2 << "\"");
|
||||||
|
// create path to be sure it exist ...
|
||||||
|
TK_VERBOSE("create path: '" << _path2.getParent() << "'");
|
||||||
|
etk::mkPath(_path2.getParent().getString().c_str() , 0755);
|
||||||
|
int32_t res = ::rename(_path1.getString().c_str(), _path2.getString().c_str());
|
||||||
|
if (res!=0) {
|
||||||
|
TK_ERROR("Can not move the file: '" << _path1 << "' ==> '" << _path2 << "'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::fileSystem::moveDirectory(const etk::Path& _path1, const etk::Path& _path2) {
|
bool etk::fileSystem::moveDirectory(const etk::Path& _path1, const etk::Path& _path2) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::fileSystem::moveFile(const etk::Path& _path1, const etk::Path& _path2) {
|
bool etk::fileSystem::moveFile(const etk::Path& _path1, const etk::Path& _path2) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void etk::fileSystem::remove(const etk::Path& _path) {
|
bool etk::fileSystem::remove(const etk::Path& _path) {
|
||||||
|
if (etk::fileSystem::isDirectory(_path) == true) {
|
||||||
|
return etk::fileSystem::removeDirectory(_path);
|
||||||
|
}
|
||||||
|
return etk::fileSystem::removeFile(_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::fileSystem::removeDirectory(const etk::Path& _path) {
|
bool etk::fileSystem::removeDirectory(const etk::Path& _path) {
|
||||||
|
if( 0 != ::rmdir(_path1.getString().c_str()) ) {
|
||||||
|
if (ENOTEMPTY == errno) {
|
||||||
|
TK_ERROR("The Directory is not empty...");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::fileSystem::removeFile(const etk::Path& _path) {
|
bool etk::fileSystem::removeFile(const etk::Path& _path) {
|
||||||
|
if (0 != unlink(_path1.getString().c_str()) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool etk::fileSystem::touch(const etk::Path& _path) {
|
||||||
|
TK_DEBUG("Touch FILE : " << _path);
|
||||||
|
//just open in write an close ==> this will update the time
|
||||||
|
etk::io::File file{_path};
|
||||||
|
if (file.open(etk::io::OpenMode::Append) == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return file.close();
|
||||||
|
}
|
||||||
|
|
||||||
bool etk::fileSystem::exit(const etk::Path& _path) {
|
bool etk::fileSystem::exist(const etk::Path& _path) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int32_t status = 0;
|
int32_t status = 0;
|
||||||
if (stat(_path.get().c_str(), &st) != 0) {
|
if (stat(_path.get().c_str(), &st) != 0) {
|
||||||
@ -116,8 +196,8 @@ bool etk::fileSystem::isSymLink(const etk::Path& _path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
etk::filesystem::Permissions etk::fileSystem::getPermission(const etk::Path& _path) {
|
etk::fileSystem::Permissions etk::fileSystem::getPermission(const etk::Path& _path) {
|
||||||
etk::filesystem::Permissions permissions;
|
etk::fileSystem::Permissions permissions;
|
||||||
// tmpStat Buffer :
|
// tmpStat Buffer :
|
||||||
struct stat statProperty;
|
struct stat statProperty;
|
||||||
if (-1 == stat(m_systemFileName.c_str(), &statProperty)) {
|
if (-1 == stat(m_systemFileName.c_str(), &statProperty)) {
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <etk/types.hpp>
|
#include <etk/types.hpp>
|
||||||
|
|
||||||
#pragma once
|
#include <etk/fileSystem/Path.hpp>
|
||||||
|
#include <etk/fileSystem/Permissions.hpp>
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
namespace fileSystem {
|
namespace fileSystem {
|
||||||
@ -14,61 +16,86 @@ namespace etk {
|
|||||||
* @brief Copy a path to an other (if possible...)
|
* @brief Copy a path to an other (if possible...)
|
||||||
* @param[in] _path1 Path source.
|
* @param[in] _path1 Path source.
|
||||||
* @param[in] _path2 Path destination.
|
* @param[in] _path2 Path destination.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void copy(const etk::Path& _path1, const etk::Path& _path2);
|
bool copy(const etk::Path& _path1, const etk::Path& _path2);
|
||||||
/**
|
/**
|
||||||
* @brief Copy a FOLDER path to an other (if possible...)
|
* @brief Copy a FOLDER path to an other (if possible...)
|
||||||
* @param[in] _path1 Path source.
|
* @param[in] _path1 Path source.
|
||||||
* @param[in] _path2 Path destination.
|
* @param[in] _path2 Path destination.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void copyDirectory(const etk::Path& _path1, const etk::Path& _path2, bool _recursive = true);
|
bool copyDirectory(const etk::Path& _path1, const etk::Path& _path2, bool _recursive = true);
|
||||||
/**
|
/**
|
||||||
* @brief Copy a FILE path to an other (if possible...)
|
* @brief Copy a FILE path to an other (if possible...)
|
||||||
* @param[in] _path1 Path source.
|
* @param[in] _path1 Path source.
|
||||||
* @param[in] _path2 Path destination.
|
* @param[in] _path2 Path destination.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void copyFile(const etk::Path& _path1, const etk::Path& _path2);
|
bool copyFile(const etk::Path& _path1, const etk::Path& _path2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Move a path to an other (if possible...)
|
* @brief Move a path to an other (if possible...)
|
||||||
* @param[in] _path1 Path source.
|
* @param[in] _path1 Path source.
|
||||||
* @param[in] _path2 Path destination.
|
* @param[in] _path2 Path destination.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void move(const etk::Path& _path1, const etk::Path& _path2);
|
bool move(const etk::Path& _path1, const etk::Path& _path2);
|
||||||
/**
|
/**
|
||||||
* @brief Move a FOLDER path to an other (if possible...)
|
* @brief Move a FOLDER path to an other (if possible...)
|
||||||
* @param[in] _path1 Path source.
|
* @param[in] _path1 Path source.
|
||||||
* @param[in] _path2 Path destination.
|
* @param[in] _path2 Path destination.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void moveDirectory(const etk::Path& _path1, const etk::Path& _path2);
|
bool moveDirectory(const etk::Path& _path1, const etk::Path& _path2);
|
||||||
/**
|
/**
|
||||||
* @brief Move a FILE path to an other (if possible...)
|
* @brief Move a FILE path to an other (if possible...)
|
||||||
* @param[in] _path1 Path source.
|
* @param[in] _path1 Path source.
|
||||||
* @param[in] _path2 Path destination.
|
* @param[in] _path2 Path destination.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void moveFile(const etk::Path& _path1, const etk::Path& _path2);
|
bool moveFile(const etk::Path& _path1, const etk::Path& _path2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove a path (if possible...)
|
* @brief Remove a path (if possible...)
|
||||||
* @param[in] _path Path to remove.
|
* @param[in] _path Path to remove.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void remove(const etk::Path& _path);
|
bool remove(const etk::Path& _path);
|
||||||
/**
|
/**
|
||||||
* @brief Remove a FOLDER path (if possible...)
|
* @brief Remove a FOLDER path (if possible...)
|
||||||
* @param[in] _path Path to remove.
|
* @param[in] _path Path to remove.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void removeDirectory(const etk::Path& _path);
|
bool removeDirectory(const etk::Path& _path);
|
||||||
/**
|
/**
|
||||||
* @brief Remove a FILE path (if possible...)
|
* @brief Remove a FILE path (if possible...)
|
||||||
* @param[in] _path Path to remove.
|
* @param[in] _path Path to remove.
|
||||||
|
* @return true Operation succeed.
|
||||||
|
* @return false Operation Failed.
|
||||||
*/
|
*/
|
||||||
void removeFile(const etk::Path& _path);
|
bool removeFile(const etk::Path& _path);
|
||||||
|
/**
|
||||||
|
* @brief update the Time of the file with the current time
|
||||||
|
* @param[in] _path Path to touch.
|
||||||
|
* @return true : action done
|
||||||
|
* @return false : action not done
|
||||||
|
*/
|
||||||
|
bool touch(const etk::Path& _path);
|
||||||
/**
|
/**
|
||||||
* @brief Check if the path exist
|
* @brief Check if the path exist
|
||||||
* @param[in] _path1 Path source.
|
* @param[in] _path1 Path source.
|
||||||
* @param[in] _path2 Path destination.
|
* @param[in] _path2 Path destination.
|
||||||
*/
|
*/
|
||||||
bool exit(const etk::Path& _path);
|
bool exist(const etk::Path& _path);
|
||||||
/**
|
/**
|
||||||
* @brief Get the File size
|
* @brief Get the File size
|
||||||
* @return the requested size
|
* @return the requested size
|
||||||
@ -79,7 +106,7 @@ namespace etk {
|
|||||||
bool isFile(const etk::Path& _path);
|
bool isFile(const etk::Path& _path);
|
||||||
bool isSymLink(const etk::Path& _path);
|
bool isSymLink(const etk::Path& _path);
|
||||||
|
|
||||||
etk::filesystem::Permissions getPermission(const etk::Path& _path);
|
etk::fileSystem::Permissions getPermission(const etk::Path& _path);
|
||||||
|
|
||||||
etk::String getRelativeString(const etk::Path& _path);
|
etk::String getRelativeString(const etk::Path& _path);
|
||||||
etk::String getDecoratedString(const etk::Path& _path);
|
etk::String getDecoratedString(const etk::Path& _path);
|
||||||
|
@ -11,10 +11,19 @@
|
|||||||
etk::io::File::File() {
|
etk::io::File::File() {
|
||||||
// nothing to do.
|
// nothing to do.
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::io::File::File(const etk::Path& _path):
|
etk::io::File::File(const etk::Path& _path):
|
||||||
m_path(_path) {
|
m_path(_path) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etk::io::File::File() {
|
||||||
|
if (m_pointer != null) {
|
||||||
|
TK_ERROR("Missing to close the file : \"" << *this << "\"");
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool etk::io::File::open(etk::io::OpenMode _mode) {
|
bool etk::io::File::open(etk::io::OpenMode _mode) {
|
||||||
if (m_pointer != null) {
|
if (m_pointer != null) {
|
||||||
TK_CRITICAL("File Already open : " << *this);
|
TK_CRITICAL("File Already open : " << *this);
|
||||||
@ -57,46 +66,6 @@ uint64_t etk::io::File::size() {
|
|||||||
return etk::fileSystem::fileSize(m_path);
|
return etk::fileSystem::fileSize(m_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* etk::io::File::gets(char* _elementLine, int64_t _maxData) {
|
|
||||||
return fgets(_elementLine, _maxData, m_pointer);
|
|
||||||
}
|
|
||||||
|
|
||||||
char etk::io::File::get() {
|
|
||||||
char data='\0';
|
|
||||||
if (read(&data, 1, 1)!=1) {
|
|
||||||
return '\0';
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool etk::io::File::gets(etk::String& _output) {
|
|
||||||
_output.clear();
|
|
||||||
char tmp = get();
|
|
||||||
while ( tmp != '\0'
|
|
||||||
&& tmp != '\n') {
|
|
||||||
_output += tmp;
|
|
||||||
tmp = get();
|
|
||||||
}
|
|
||||||
if (tmp == '\0') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool etk::io::File::put(char _input) {
|
|
||||||
if (fileWrite(&_input, 1, 1) == 1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool etk::io::File::puts(const etk::String& _input) {
|
|
||||||
if (fileWrite((void*)_input.c_str(), 1, _input.size()) == (int64_t)_input.size()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool etk::io::File::seek(uint64_t _offset, enum etk::io::SeekMode _origin) {
|
bool etk::io::File::seek(uint64_t _offset, enum etk::io::SeekMode _origin) {
|
||||||
int originFS = 0;
|
int originFS = 0;
|
||||||
switch(_origin) {
|
switch(_origin) {
|
||||||
@ -123,10 +92,11 @@ void etk::io::File::flush() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void etk::io::File::tell() {
|
int64_t etk::io::File::tell() {
|
||||||
if (m_pointer != null) {
|
if (m_pointer != null) {
|
||||||
ftell(m_pointer);
|
return ftell(m_pointer);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t etk::io::File::read(void* _data, int64_t _blockSize, int64_t _nbBlock) {
|
int64_t etk::io::File::read(void* _data, int64_t _blockSize, int64_t _nbBlock) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <etk/types.hpp>
|
#include <etk/types.hpp>
|
||||||
#include <etk/io/Interface.hpp>
|
#include <etk/io/Interface.hpp>
|
||||||
|
#include <etk/io/File.hpp>
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
namespace io {
|
namespace io {
|
||||||
@ -20,19 +21,16 @@ namespace etk {
|
|||||||
public:
|
public:
|
||||||
File();
|
File();
|
||||||
File(const etk::Path& _path);
|
File(const etk::Path& _path);
|
||||||
|
~File();
|
||||||
ETK_CONSTRUCTOR_COPY_DELETE(File);
|
ETK_CONSTRUCTOR_COPY_DELETE(File);
|
||||||
ETK_CONSTRUCTOR_MOVE_DEFAULT(File);
|
ETK_CONSTRUCTOR_MOVE_DEFAULT(File);
|
||||||
public:
|
public:
|
||||||
bool open() override;
|
bool open(etk::io::OpenMode _mode) override;
|
||||||
bool isOpen() override;
|
bool isOpen() override;
|
||||||
bool close() override;
|
bool close() override;
|
||||||
uint64_t size() override;
|
uint64_t size() override;
|
||||||
char* gets(char* _elementLine, int64_t _maxData) override;
|
|
||||||
char get() override;
|
|
||||||
bool gets(etk::String& _output) override;
|
|
||||||
bool put(char _input) override;
|
|
||||||
bool puts(const etk::String& _input) override;
|
|
||||||
bool seek(uint64_t _offset, enum etk::io::SeekMode _origin) override;
|
bool seek(uint64_t _offset, enum etk::io::SeekMode _origin) override;
|
||||||
|
int64_t tell() override;
|
||||||
void flush() override;
|
void flush() override;
|
||||||
int64_t read(void* _data, int64_t _blockSize, int64_t _nbBlock) override;
|
int64_t read(void* _data, int64_t _blockSize, int64_t _nbBlock) override;
|
||||||
int64_t write(const void* _data, int64_t _blockSize, int64_t _nbBlock) override;
|
int64_t write(const void* _data, int64_t _blockSize, int64_t _nbBlock) override;
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL-2 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/io/Interface.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
char etk::io::Interface::get() {
|
||||||
|
char data='\0';
|
||||||
|
if (read(&data, 1, 1)!=1) {
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::io::Interface::gets(etk::String& _output) {
|
||||||
|
_output.clear();
|
||||||
|
char tmp = get();
|
||||||
|
while ( tmp != '\0'
|
||||||
|
&& tmp != '\n') {
|
||||||
|
_output += tmp;
|
||||||
|
tmp = get();
|
||||||
|
}
|
||||||
|
if (tmp == '\0') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::io::Interface::put(char _input) {
|
||||||
|
if (fileWrite(&_input, 1, 1) == 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::io::Interface::puts(const etk::String& _input) {
|
||||||
|
if (fileWrite((void*)_input.c_str(), 1, _input.size()) == (int64_t)_input.size()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
@ -16,6 +16,7 @@ namespace etk {
|
|||||||
*/
|
*/
|
||||||
class Interface {
|
class Interface {
|
||||||
public:
|
public:
|
||||||
|
virtual ~Interface();
|
||||||
/**
|
/**
|
||||||
* @brief Open the file in Read mode
|
* @brief Open the file in Read mode
|
||||||
* @param[in] _mode Mode to open the IO
|
* @param[in] _mode Mode to open the IO
|
||||||
@ -40,39 +41,32 @@ namespace etk {
|
|||||||
* @return the requested size
|
* @return the requested size
|
||||||
*/
|
*/
|
||||||
virtual uint64_t size() = 0;
|
virtual uint64_t size() = 0;
|
||||||
/**
|
|
||||||
* @brief Get the pointer on the start line and the next line (or null)
|
|
||||||
* @param[in,out] _elementLine Pointer to an array of chars where the string read is copied.
|
|
||||||
* @param[in] _maxData Maximum number of characters to be copied into str (including the terminating null-character).
|
|
||||||
* @return the pointer on the end of the cuurent line.
|
|
||||||
*/
|
|
||||||
virtual char* gets(char* _elementLine, int64_t _maxData) = 0;
|
|
||||||
/**
|
/**
|
||||||
* @brief Get a unique data in the file
|
* @brief Get a unique data in the file
|
||||||
* @return the next element in the file.
|
* @return the next element in the file.
|
||||||
*/
|
*/
|
||||||
virtual char get() = 0;
|
virtual char get();
|
||||||
/**
|
/**
|
||||||
* @brief Get a compleate line in a text file
|
* @brief Get a compleate line in a text file
|
||||||
* @param[out] _output the next element in the file.
|
* @param[out] _output the next element in the file.
|
||||||
* @return true The file is not ended.
|
* @return true The file is not ended.
|
||||||
* @return false The file is ended.
|
* @return false The file is ended.
|
||||||
*/
|
*/
|
||||||
virtual bool gets(etk::String& _output) = 0;
|
virtual bool gets(etk::String& _output);
|
||||||
/**
|
/**
|
||||||
* @brief Write data on the file
|
* @brief Write data on the file
|
||||||
* @param[in] _input data to write.
|
* @param[in] _input data to write.
|
||||||
* @return true Write done corectly.
|
* @return true Write done corectly.
|
||||||
* @return false ErrorOn write.
|
* @return false ErrorOn write.
|
||||||
*/
|
*/
|
||||||
virtual bool put(char _input) = 0;
|
virtual bool put(char _input);
|
||||||
/**
|
/**
|
||||||
* @brief Write data on the file
|
* @brief Write data on the file
|
||||||
* @param[in] _input data to write.
|
* @param[in] _input data to write.
|
||||||
* @return true Write done corectly.
|
* @return true Write done corectly.
|
||||||
* @return false ErrorOn write.
|
* @return false ErrorOn write.
|
||||||
*/
|
*/
|
||||||
virtual bool puts(const etk::String& _input) = 0;
|
virtual bool puts(const etk::String& _input);
|
||||||
/**
|
/**
|
||||||
* @brief Move in the file Position
|
* @brief Move in the file Position
|
||||||
* @param[in] _offset Offset to apply at the file
|
* @param[in] _offset Offset to apply at the file
|
||||||
|
@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL-2 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/io/Interface.hpp>
|
||||||
|
#include <etk/io/ZipFile.hpp>
|
||||||
|
|
||||||
|
etk::io::ZipFile::ZipFile(ememory::SharedPtr<etk::Archive> _archive):
|
||||||
|
m_archive(_archive) {
|
||||||
|
// nothing to do.
|
||||||
|
}
|
||||||
|
etk::io::ZipFile::ZipFile(const etk::Path& _path, ememory::SharedPtr<etk::Archive> _archive):
|
||||||
|
m_path(_path),
|
||||||
|
m_archive(_archive) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::io::ZipFile::open(etk::io::OpenMode _mode) {
|
||||||
|
if (m_content != null) {
|
||||||
|
TK_CRITICAL("File Already open : " << *this);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (m_archive == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TK_VERBOSE(" Read file : " << m_path);
|
||||||
|
switch (_mode) {
|
||||||
|
case etk::io::OpenMode::Read:
|
||||||
|
if (m_archive->exist(m_path) == false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_content = m_archive->getContent(m_path);
|
||||||
|
if (m_content != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
m_archive->open(m_path);
|
||||||
|
return false;
|
||||||
|
case etk::io::OpenMode::Write:
|
||||||
|
return false;
|
||||||
|
case etk::io::OpenMode::Append:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::io::ZipFile::isOpen() {
|
||||||
|
if (m_content != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::io::ZipFile::close() {
|
||||||
|
if (m_content == null) {
|
||||||
|
TK_CRITICAL("File Already closed : " << *this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_archive->close(m_path);
|
||||||
|
m_content = null;
|
||||||
|
m_offset = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t etk::io::ZipFile::size() {
|
||||||
|
if (m_content == null) {
|
||||||
|
TK_CRITICAL("Can not access to the size: " << *this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return m_content->getTheoricSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool etk::io::ZipFile::seek(uint64_t _offset, enum etk::io::SeekMode _origin) {
|
||||||
|
if (null == m_content) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int32_t positionEnd = 0;
|
||||||
|
switch(_origin) {
|
||||||
|
case etk::seekNode_end:
|
||||||
|
positionEnd = m_content->size();
|
||||||
|
break;
|
||||||
|
case etk::seekNode_current:
|
||||||
|
positionEnd = m_offset;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
positionEnd = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
positionEnd += _offset;
|
||||||
|
if (positionEnd < 0) {
|
||||||
|
positionEnd = 0;
|
||||||
|
} else if (positionEnd > m_content->size()) {
|
||||||
|
positionEnd = m_content->size();
|
||||||
|
}
|
||||||
|
m_offset = positionEnd;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void etk::io::ZipFile::flush() {
|
||||||
|
// nothing to do.
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t etk::io::ZipFile::tell() {
|
||||||
|
if (null == m_content) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t etk::io::ZipFile::read(void* _data, int64_t _blockSize, int64_t _nbBlock) {
|
||||||
|
if (m_content == null) {
|
||||||
|
((char*)_data)[0] = '\0';
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int32_t dataToRead = _blockSize * _nbBlock;
|
||||||
|
if (dataToRead + m_offset > m_content->size()) {
|
||||||
|
_nbBlock = ((m_content->size() - m_offset) / _blockSize);
|
||||||
|
dataToRead = _blockSize * _nbBlock;
|
||||||
|
}
|
||||||
|
memcpy(_data, &((char*)m_content->data())[m_offset], dataToRead);
|
||||||
|
m_offset += dataToRead;
|
||||||
|
return _nbBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t etk::io::ZipFile::write(const void* _data, int64_t _blockSize, int64_t _nbBlock) {
|
||||||
|
TK_CRITICAL("Can not write on data inside APK : " << *this);
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL-2 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/io/Interface.hpp>
|
||||||
|
|
||||||
|
namespace etk {
|
||||||
|
namespace io {
|
||||||
|
/**
|
||||||
|
* @brief System file interface.
|
||||||
|
*/
|
||||||
|
class ZipFile: public etk::io::Interface {
|
||||||
|
private:
|
||||||
|
etk::Path m_path; //!< Path to access in this interface
|
||||||
|
ememory::SharedPtr<etk::Archive> m_archive; //!< Archive interface
|
||||||
|
ememory::SharedPtr<etk::ArchiveContent> m_content; //!< Data in the archive file
|
||||||
|
int32_t m_offset;
|
||||||
|
public:
|
||||||
|
ZipFile(ememory::SharedPtr<etk::Archive> _archive);
|
||||||
|
ZipFile(const etk::Path& _path, ememory::SharedPtr<etk::Archive> _archive);
|
||||||
|
ETK_CONSTRUCTOR_COPY_DELETE(File);
|
||||||
|
ETK_CONSTRUCTOR_MOVE_DEFAULT(File);
|
||||||
|
public:
|
||||||
|
bool open(etk::io::OpenMode _mode) override;
|
||||||
|
bool isOpen() override;
|
||||||
|
bool close() override;
|
||||||
|
uint64_t size() override;
|
||||||
|
char* gets(char* _elementLine, int64_t _maxData) override;
|
||||||
|
bool seek(uint64_t _offset, enum etk::io::SeekMode _origin) override;
|
||||||
|
int64_t tell() override;
|
||||||
|
void flush() override;
|
||||||
|
int64_t read(void* _data, int64_t _blockSize, int64_t _nbBlock) override;
|
||||||
|
int64_t write(const void* _data, int64_t _blockSize, int64_t _nbBlock) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,60 @@
|
|||||||
|
|
||||||
TEST(TestPath, defaultContructor) {
|
TEST(TestPath, defaultContructor) {
|
||||||
etk::Path path;
|
etk::Path path;
|
||||||
EXPECT_EQ(path.getType(), etk::fileSystem::Type::Unknow);
|
EXPECT_EQ(path.getString(), "");
|
||||||
EXPECT_EQ(path.get(), "");
|
EXPECT_EQ(path.isRelative(), true);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestPath, basic_relatif) {
|
||||||
|
etk::Path path("hello");
|
||||||
|
EXPECT_EQ(path.getSring(), "hello");
|
||||||
|
EXPECT_EQ(path.isRelative(), true);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestPath, basic_relatif_2) {
|
||||||
|
etk::Path path("hello/plouf");
|
||||||
|
EXPECT_EQ(path.getSring(), "hello/plouf");
|
||||||
|
EXPECT_EQ(path.isRelative(), true);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestPath, basic_relatif_2_windows) {
|
||||||
|
etk::Path path("hello\\plouf");
|
||||||
|
EXPECT_EQ(path.getSring(), "hello/plouf");
|
||||||
|
EXPECT_EQ(path.isRelative(), true);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestPath, basic_absolute) {
|
||||||
|
etk::Path path("/");
|
||||||
|
EXPECT_EQ(path.getSring(), "/");
|
||||||
|
EXPECT_EQ(path.getSringWindows(), "\\");
|
||||||
|
EXPECT_EQ(path.isRelative(), false);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestPath, basic_absolute_windows) {
|
||||||
|
etk::Path path("k:\\");
|
||||||
|
EXPECT_EQ(path.getSring(), "/k/");
|
||||||
|
EXPECT_EQ(path.getSringWindows(), "k:\\");
|
||||||
|
EXPECT_EQ(path.isRelative(), false);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestPath, basic_absolute_2) {
|
||||||
|
etk::Path path("/home/heero/hello/plouf");
|
||||||
|
EXPECT_EQ(path.getSring(), "/home/heero/hello/plouf");
|
||||||
|
EXPECT_EQ(path.getSringWindows(), "\\home\\heero\\hello\\plouf");
|
||||||
|
EXPECT_EQ(path.isRelative(), false);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestPath, basic_absolute_2_windows) {
|
||||||
|
etk::Path path("G:\\hello\\plouf");
|
||||||
|
EXPECT_EQ(path.getSring(), "/g/hello/plouf");
|
||||||
|
EXPECT_EQ(path.getSringWindows(), "g:\\hello\\plouf");
|
||||||
|
EXPECT_EQ(path.isRelative(), false);
|
||||||
|
EXPECT_EQ(path.isAbsolute(), true);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user