From 6a7d45b5b0bc56f3826e19614ab8d9a542e876a2 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Thu, 30 Aug 2018 23:18:55 +0200 Subject: [PATCH] [DEV] add base of generic usage of a path --- etk/fileSystem/Path.cpp | 226 +++++++++++++++++++++++++++++++++ etk/fileSystem/Path.hpp | 64 ++++++++++ etk/fileSystem/Permissions.cpp | 209 ++++++++++++++++++++++++++++++ etk/fileSystem/Permissions.hpp | 151 ++++++++++++++++++++++ etk/fileSystem/Type.cpp | 42 ++++++ etk/fileSystem/Type.hpp | 54 ++++++++ etk/fileSystem/fileSystem.cpp | 0 etk/fileSystem/fileSystem.hpp | 53 ++++++++ etk/theme/theme.cpp | 56 ++++++++ etk/theme/theme.hpp | 45 +++++++ etk/types.hpp | 1 + 11 files changed, 901 insertions(+) create mode 100644 etk/fileSystem/Path.cpp create mode 100644 etk/fileSystem/Path.hpp create mode 100644 etk/fileSystem/Permissions.cpp create mode 100644 etk/fileSystem/Permissions.hpp create mode 100644 etk/fileSystem/Type.cpp create mode 100644 etk/fileSystem/Type.hpp create mode 100644 etk/fileSystem/fileSystem.cpp create mode 100644 etk/fileSystem/fileSystem.hpp create mode 100644 etk/theme/theme.cpp create mode 100644 etk/theme/theme.hpp diff --git a/etk/fileSystem/Path.cpp b/etk/fileSystem/Path.cpp new file mode 100644 index 0000000..9ab4982 --- /dev/null +++ b/etk/fileSystem/Path.cpp @@ -0,0 +1,226 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +#include + + +static etk::Pair parsePath(etk::String _path) { + m_libSearch = ""; + if ( _path.size() > 0 + && _path[0] == '{') { + // special case: Reference of searching in subLib folder ==> library use-case + size_t firstPos = _path.find('}'); + if (firstPos != etk::String::npos) { + // we find a theme name : We extracted it : + m_libSearch = etk::String(_path, 1, firstPos-1); + _path = etk::String(_path, firstPos+1); + } else { + TK_ERROR("start a path name with '{' without '}' : " << _path); + // remove in case the { + _path = etk::String(_path, 1); + } + } + + #ifdef HAVE_ZIP_DATA + m_zipContent = null; + m_zipReadingOffset = 0; + #endif + // Reset ALL DATA : + m_userFileName = ""; + m_type = etk::FSNType_unknow; + TK_DBG_MODE("1 : Set Name : \"" << _path << "\""); + + // generate destination name in case of the input error + etk::String destFilename; + if (_path.size() == 0) { + // if no name ==> go to the root Folder + destFilename = "ROOT:"; + } else { + destFilename = _path; + } + + bool isRootFolder = false; + #ifdef __TARGET_OS__Windows + for (char iii='a' ; iii<='z' ; iii++) { + char tmpVal[10]; + char tmpValMaj[10]; + sprintf(tmpVal, "%c:/", iii); + sprintf(tmpValMaj, "%c:/", iii+'A'-'a'); + if( etk::start_with(destFilename, tmpVal) == true + || etk::start_with(destFilename, tmpValMaj) == true) { + isRootFolder = true; + break; + } + } + #else + isRootFolder = destFilename[0] == '/'; + #endif + if( start_with(destFilename, "ROOT:") == true + || start_with(destFilename, "root:") == true ) { + TK_DBG_MODE(" ==> detect root 2 "); + destFilename.erase(0, 5); + m_type = etk::FSNType_direct; + if(start_with(destFilename, "~") == true) { + destFilename.erase(0, 1); + m_type = etk::FSNType_home; + } + } else if( start_with(destFilename, "DIRECT:") == true + || start_with(destFilename, "direct:") == true ) { + TK_DBG_MODE(" ==> detect direct"); + destFilename.erase(0, 7); + m_type = etk::FSNType_direct; + if(start_with(destFilename, "~") == true) { + destFilename.erase(0, 1); + m_type = etk::FSNType_home; + } + } else if( start_with(destFilename, "DATA:") == true + || start_with(destFilename, "data:") == true ) { + TK_DBG_MODE(" ==> detect data"); + destFilename.erase(0, 5); + m_type = etk::FSNType_data; + } else if( start_with(destFilename, "USERDATA:") == true + || start_with(destFilename, "userdata:") == true ) { + TK_DBG_MODE(" ==> detect User-data"); + destFilename.erase(0, 9); + m_type = etk::FSNType_userData; + } else if( start_with(destFilename, "CACHE:") == true + || start_with(destFilename, "cache:") == true ) { + TK_DBG_MODE(" ==> detect Cache"); + destFilename.erase(0, 6); + m_type = etk::FSNType_cache; + } else if( start_with(destFilename, "THEME:") == true + || start_with(destFilename, "theme:") == true ) { + TK_DBG_MODE(" ==> detect theme"); + destFilename.erase(0, 6); + m_type = etk::FSNType_theme; + } else if(start_with(destFilename, "./") == true) { + TK_DBG_MODE(" ==> detect relatif 1"); + destFilename.erase(0, 2); + while (destFilename.size()>0 && destFilename[0] == '/') { + destFilename.erase(0, 1); + } + m_type = etk::FSNType_relatif; + } else if( start_with(destFilename, "REL:") == true + || start_with(destFilename, "rel:") == true ) { + TK_DBG_MODE(" ==> detect relatif 2"); + destFilename.erase(0, 4); + while (destFilename.size()>0 && destFilename[0] == '/') { + destFilename.erase(0, 1); + } + m_type = etk::FSNType_relatif; + } else if(start_with(destFilename, baseRunPath) == true) { + TK_DBG_MODE(" ==> detect relatif 3 (run path=" << baseRunPath << ")"); + destFilename.erase(0, baseRunPath.size()); + while (destFilename.size()>0 && destFilename[0] == '/') { + destFilename.erase(0, 1); + } + m_type = etk::FSNType_relatif; + } else if (( baseRunPath != baseRunPathInHome + && ( start_with(destFilename, "~" + baseRunPathInHome) == true + || start_with(destFilename, "HOME:" + baseRunPathInHome) == true + || start_with(destFilename, "home:" + baseRunPathInHome) == true ) ) ) { + TK_DBG_MODE(" ==> detect relatif 4"); + if (start_with(destFilename, "~" + baseRunPathInHome) == true) { + destFilename.erase(0, 1); + } else { + destFilename.erase(0, 5); + } + destFilename.erase(0, baseRunPathInHome.size()); + while (destFilename.size()>0 && destFilename[0] == '/') { + destFilename.erase(0, 1); + } + m_type = etk::FSNType_relatif; + } else if(start_with(destFilename, "~")) { + TK_DBG_MODE(" ==> detect home 2"); + destFilename.erase(0, 1); + m_type = etk::FSNType_home; + } else if( start_with(destFilename, "HOME:") == true + || start_with(destFilename, "home:") == true ) { + TK_DBG_MODE(" ==> detect home 3"); + destFilename.erase(0, 5); + m_type = etk::FSNType_home; + if(start_with(destFilename, "~") == true) { + destFilename.erase(0, 1); + } + } else if (start_with(destFilename, baseFolderHome) == true) { + TK_DBG_MODE(" ==> detect home"); + destFilename.erase(0, baseFolderHome.size()); + m_type = etk::FSNType_home; + } else if(isRootFolder == true) { + TK_DBG_MODE(" ==> detect root"); + #ifdef __TARGET_OS__Windows + destFilename.erase(0, 3); + #else + destFilename.erase(0, 1); + #endif + m_type = etk::FSNType_direct; + } else { + TK_DBG_MODE(" ==> detect other"); + // nothing to remove + //Other type is Relative : + m_type = etk::FSNType_relatif; + } + m_userFileName = destFilename; + TK_DBG_MODE("3 : parse done : [" << m_type << "]->\"" << m_userFileName << "\""); + + // 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); +} + + + +etk::Path::Path(const etk::String& _value) { + m_type = + m_data = +} + +bool etk::Path::operator== (const etk::Path &_obj) const { + return m_type == _obj.m_type + && m_data == _obj.m_data; +} + +bool etk::Path::operator!= (const etk::Path &_obj) const { + return m_type != _obj.m_type + || m_data != _obj.m_data; +} + +etk::Path etk::Path::operator/ (const etk::String & _element) const { + etk::Path tmp = *this; + tmp /= _element; + return tmp; +} + +etk::Path& etk::Path::operator/= (const etk::String & _element) { + if (_element.size() == 0) { + return *this; + } + m_data += "/" + _element; + return *this; +} + +etk::Path etk::Path::operator+ (const etk::String & _element) const { + etk::Path tmp = *this; + tmp += _element; + return tmp; +} + +etk::Path& etk::Path::operator+= (const etk::String & _element) { + if (_element.size() == 0) { + return *this; + } + m_data += _element; + return *this; +} + diff --git a/etk/fileSystem/Path.hpp b/etk/fileSystem/Path.hpp new file mode 100644 index 0000000..5a3ce1f --- /dev/null +++ b/etk/fileSystem/Path.hpp @@ -0,0 +1,64 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace etk { + /** + * @brief representation of a path in the filesystem (the generic store data with / separators, for windows we store the Drive with a /c/ or /x/. + * You can get the OS specific filename with the function: @ref getOsPath(); + */ + class Path { + private: + fileSystem::Type m_type; //!< the Type of data requested by the User. + etk::String m_data; //!< Raw data of the path. + public: + ETK_CONSTRUCTOR_MOVE_DEFAULT(Path); + ETK_CONSTRUCTOR_COPY_DEFAULT(Path); + /** + * @brief Default contructor. + */ + Path(); + /** + * @brief Contructor with basic path. + * @param[in] _value Element basic path + */ + Path(const etk::String& _value); + /** + * @brief Check if the 2 Path are identical. + * @param[in] _obj Path to compare. + * @return true : same path, false otherwise. + */ + bool operator== (const etk::Path &_obj) const; + /** + * @brief Check if the 2 Path are different. + * @param[in] _obj Path to compare. + * @return false : same path, true otherwise. + */ + bool operator!= (const etk::Path &_obj) const; + /** + * @brief Add a subfolder on the current path. + * @param[in] _element sub folder or file to add. + * @return false : same path, true otherwise. + */ + Path operator/ (const etk::String & _element) const; + //! @preivious + Path& operator=/ (const etk::String & _element); + /** + * @brief Add a subfolder on the current path. + * @param[in] _element sub folder or file to add. + * @return false : same path, true otherwise. + */ + Path operator+ (const etk::String & _element) const; + //! @preivious + Path& operator+= (const etk::String & _element); + + + }; +} + diff --git a/etk/fileSystem/Permissions.cpp b/etk/fileSystem/Permissions.cpp new file mode 100644 index 0000000..ba19a17 --- /dev/null +++ b/etk/fileSystem/Permissions.cpp @@ -0,0 +1,209 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ + + +#include +#include +#include + +// Right Flags : +enum { + right_other_execute = 1 << 0, + right_other_write = 1 << 1, + right_other_read = 1 << 2, + right_group_execute = 1 << 3, + right_group_write = 1 << 4, + right_group_read = 1 << 5, + right_user_execute = 1 << 6, + right_user_write = 1 << 7, + right_user_read = 1 << 8, +}; + +ETK_DECLARE_TYPE(etk::filesystem::Permissions); + +etk::filesystem::Permissions::FSNodeRight(int16_t _newRight) : + m_rights(_newRight&0x01FF) { + +} + +etk::filesystem::Permissions& etk::filesystem::Permissions::operator= (const etk::filesystem::Permissions &_obj ) { + m_rights = _obj.m_rights; + return *this; +} + +etk::filesystem::Permissions& etk::filesystem::Permissions::operator= (const int32_t _newVal) { + m_rights = _newVal&0x01FF; + return *this; +} + +void etk::filesystem::Permissions::clear() { + m_rights = 0; +} + +bool etk::filesystem::Permissions::isUserReadable() const { + return ((m_rights&right_user_read)!=0)?true:false; +} + +bool etk::filesystem::Permissions::isUserWritable() const { + return ((m_rights&right_user_write)!=0)?true:false; +} + +bool etk::filesystem::Permissions::isUserRunable() const { + return ((m_rights&right_user_execute)!=0)?true:false; +} + +void etk::filesystem::Permissions::setUserReadable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_user_read); + if (_newStatus == true) { + m_rights |= right_user_read; + } +} + +void etk::filesystem::Permissions::setUserWritable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_user_write); + if (_newStatus == true) { + m_rights |= right_user_write; + } +} + +void etk::filesystem::Permissions::setUserRunable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_user_execute); + if (_newStatus == true) { + m_rights |= right_user_execute; + } +} + +bool etk::filesystem::Permissions::isGroupReadable() const { + return ((m_rights&right_group_read)!=0)?true:false; +} + +bool etk::filesystem::Permissions::isGroupWritable() const { + return ((m_rights&right_group_write)!=0)?true:false; +} + +bool etk::filesystem::Permissions::isGroupRunable() const { + return ((m_rights&right_group_execute)!=0)?true:false; +} + +void etk::filesystem::Permissions::setGroupReadable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_group_read); + if (true == _newStatus) { + m_rights |= right_group_read; + } +} + +void etk::filesystem::Permissions::setGroupWritable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_group_write); + if (true == _newStatus) { + m_rights |= right_group_write; + } +} + +void etk::filesystem::Permissions::setGroupRunable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_group_execute); + if (true == _newStatus) { + m_rights |= right_group_execute; + } +} + +bool etk::filesystem::Permissions::isOtherReadable() const { + return ((m_rights&right_other_read) != 0)?true:false; +} + +bool etk::filesystem::Permissions::isOtherWritable() const { + return ((m_rights&right_other_write) != 0)?true:false; +} + +bool etk::filesystem::Permissions::isOtherRunable() const { + return ((m_rights&right_other_execute) != 0)?true:false; +} + +void etk::filesystem::Permissions::setOtherReadable(bool _newStatus) { + // reset the flag: + m_rights &= (0xFFFFFFFF - right_other_read); + if (_newStatus == true) { + m_rights |= right_other_read; + } +} + +void etk::filesystem::Permissions::setOtherWritable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_other_write); + if (_newStatus == true) { + m_rights |= right_other_write; + } +} + +void etk::filesystem::Permissions::setOtherRunable(bool _newStatus) { + // reset the flag : + m_rights &= (0xFFFFFFFF - right_other_execute); + if (_newStatus == true) { + m_rights |= right_other_execute; + } +} + +etk::String etk::filesystem::Permissions::getRight() const { + etk::String tmp; + if (isUserReadable() == true) { + tmp += "r"; + } else { + tmp += "-"; + } + if (isUserWritable() == true) { + tmp += "w"; + } else { + tmp += "-"; + } + if (isUserRunable() == true) { + tmp += "x"; + } else { + tmp += "-"; + } + if (isGroupReadable() == true) { + tmp += "r"; + } else { + tmp += "-"; + } + if (isGroupWritable() == true) { + tmp += "w"; + } else { + tmp += "-"; + } + if (isGroupRunable() == true) { + tmp += "x"; + } else { + tmp += "-"; + } + if (isOtherReadable() == true) { + tmp += "r"; + } else { + tmp += "-"; + } + if (isOtherWritable() == true) { + tmp += "w"; + } else { + tmp += "-"; + } + if (isOtherRunable() == true) { + tmp += "x"; + } else { + tmp += "-"; + } + return tmp; +} + + +etk::Stream& etk::operator <<(etk::Stream &_os, const etk::filesystem::Permissions &_obj) { + _os << _obj.getRight(); + return _os; +}; + diff --git a/etk/fileSystem/Permissions.hpp b/etk/fileSystem/Permissions.hpp new file mode 100644 index 0000000..5ac28f5 --- /dev/null +++ b/etk/fileSystem/Permissions.hpp @@ -0,0 +1,151 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2011, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ + +#include + +#pragma once + +#include + +namespace etk { + /** + * @brief File System Right management + */ + class Permissions { + private: + uint16_t m_rights; //!< right manage in a bit field + public: + /** + * @brief Right contructor. + * @param[in] _newRight Right to set by default + */ + Permissions(int16_t _newRight = 0); + /** + * @brief Copy asignement operator (operator=) + * @param[in] _obj Object to copy + * @return Local reference on the object + */ + etk::filesystem::Permissions& operator= (const etk::filesystem::Permissions &_obj); + /** + * @brief Asignement operator (operator=) + * @param[in] _newVal Value to set on the right + * @return Local reference on the object + */ + etk::filesystem::Permissions& operator= (const int32_t _newVal ); + /** + * @brief Clear right (set the value at 0 ==> cant not be read/write/execute + */ + void clear(); + /** + * @brief Get the "Read status" for the "User" + * @return true The file/folder/... is readable + * @return false The file/folder/... is NOT readable + */ + bool isUserReadable() const; + /** + * @brief Get the "Write status" for the "User" + * @return true The file/folder/... is writable + * @return false The file/folder/... is NOT writable + */ + bool isUserWritable() const; + /** + * @brief Get the "execute status" for the "User" + * @return true The file/folder/... is executable + * @return false The file/folder/... is NOT executable + */ + bool isUserRunable() const; + /** + * @brief Set the "Read status" for the "User" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setUserReadable(bool _newStatus); + /** + * @brief Set the "Write status" for the "User" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setUserWritable(bool _newStatus); + /** + * @brief Set the "execute status" for the "User" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setUserRunable(bool _newStatus); + /** + * @brief Get the "Read status" for the "Group" + * @return true The file/folder/... is readable + * @return false The file/folder/... is NOT readable + */ + bool isGroupReadable() const; + /** + * @brief Get the "Write status" for the "Group" + * @return true The file/folder/... is writable + * @return false The file/folder/... is NOT writable + */ + bool isGroupWritable() const; + /** + * @brief Get the "execute status" for the "Group" + * @return true The file/folder/... is executable + * @return false The file/folder/... is NOT executable + */ + bool isGroupRunable() const; + /** + * @brief Set the "Read status" for the "Group" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setGroupReadable(bool _newStatus); + /** + * @brief Set the "Write status" for the "Group" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setGroupWritable(bool _newStatus); + /** + * @brief Set the "Execute status" for the "Group" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setGroupRunable(bool _newStatus); + /** + * @brief Get the "Read status" for the "Other" + * @return true The file/folder/... is readable + * @return false The file/folder/... is NOT readable + */ + bool isOtherReadable() const; + /** + * @brief Get the "Write status" for the "Other" + * @return true The file/folder/... is writable + * @return false The file/folder/... is NOT writable + */ + bool isOtherWritable() const; + /** + * @brief Get the "execute status" for the "Other" + * @return true The file/folder/... is executable + * @return false The file/folder/... is NOT executable + */ + bool isOtherRunable() const; + /** + * @brief Set the "Read status" for the "Other" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setOtherReadable(bool _newStatus); + /** + * @brief Set the "Write status" for the "Other" + * @param[in] _newStatus New value to set on the file/folder/... + */ + void setOtherWritable(bool _newStatus); + /** + * @brief Set the "Execute status" for the "Other" + * @param[in] _newStatus New value to set on the file/folder/... + */ + 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 + */ + etk::String getRight() const; + }; + //! @not_in_doc + etk::Stream& operator <<(etk::Stream &_os, const etk::filesystem::Permissions &_obj); +} + + diff --git a/etk/fileSystem/Type.cpp b/etk/fileSystem/Type.cpp new file mode 100644 index 0000000..4fe74ce --- /dev/null +++ b/etk/fileSystem/Type.cpp @@ -0,0 +1,42 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +#include +#include + +etk::Stream& etk::operator <<(etk::Stream &_os, const enum etk::fileSystem::Type &_obj) { + switch (_obj) { + case etk::fileSystem::Type::Unknow: + _os << "etk::fileSystem::Type::Unknow"; + break; + case etk::fileSystem::Type::Direct: + _os << "etk::fileSystem::Type::Direct"; + break; + case etk::fileSystem::Type::Home: + _os << "etk::fileSystem::Type::Home"; + break; + case etk::fileSystem::Type::Data: + _os << "etk::fileSystem::Type::Data"; + break; + case etk::fileSystem::Type::UserData: + _os << "etk::fileSystem::Type::UserData"; + break; + case etk::fileSystem::Type::Cache: + _os << "etk::fileSystem::Type::Cache"; + break; + case etk::fileSystem::Type::Theme: + _os << "etk::fileSystem::Type::Theme"; + break; + case etk::fileSystem::Type::ThemeData: + _os << "etk::fileSystem::Type::Theme(DATA)"; + break; + default: + _os << "etk::fileSystem::Type::????"; + break; + } + return _os; +} + + diff --git a/etk/fileSystem/Type.hpp b/etk/fileSystem/Type.hpp new file mode 100644 index 0000000..d84fbd2 --- /dev/null +++ b/etk/fileSystem/Type.hpp @@ -0,0 +1,54 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ + +#include + +#pragma once + +namespace etk { + namespace fileSystem { + /** + * @brief Type of the file/folder/... accessible in the Node + */ + enum class Type { + Unknow, //!< Unknow type of the node (many time no file name seted) + // user might done abstraction ==> acces of the sdcard when possible ... + Direct, //!< Access at the file System with a direct naming like "/home/plop/xxx.txt" + // depend on case + // - PC : ~/ + // - Android : /sdcard/ + // - Apple : ???? + Home, //!< acces at the home path of the system (with name of the current user) + // depend of the case + // - PC : /usr/shared/programName/ + // - Android : Internal at the executable file (pointer on static area) + // - Apple : Internal at the executable file + Data, //!< Access on the application data (internal application data are the one provided with the binary) + // depend on case + // - PC : ~/.local/programName/ + // - Android : /data/data/programName/files/ + // - Apple : ???? + UserData, //!< Access on the user application data (where the data are stored when the application stop) + // depend on case + // - PC : ~/.programName/cache/ + // - Android : /data/data/programName/cache/ + // - Apple : ???? + Cache, //!< Access on the application temporary path (remove when user want and whe the compter restart or have not enought memory) + // depend on case + // - try on USER_DATA:/theme/themeName/xxx + // - try on DATA:/theme/themeName/xxx + // and jump to the default theme file + // - try on USER_DATA:/theme/default/xxx + // - try on DATA:/theme/default/xxx + Theme, //!< Theme area + ThemeData //!< Theme data area + }; + } + + //! @not_in_doc + etk::Stream& operator <<(etk::Stream &_os, const etk::fileSystem::Type &_obj); +} + diff --git a/etk/fileSystem/fileSystem.cpp b/etk/fileSystem/fileSystem.cpp new file mode 100644 index 0000000..e69de29 diff --git a/etk/fileSystem/fileSystem.hpp b/etk/fileSystem/fileSystem.hpp new file mode 100644 index 0000000..6f83d8f --- /dev/null +++ b/etk/fileSystem/fileSystem.hpp @@ -0,0 +1,53 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ + +#include + +#pragma once + +namespace etk { + namespace fileSystem { + void copy(const etk::Path& _path1, const etk::Path& _path2); + void copyDirectory(const etk::Path& _path1, const etk::Path& _path2, bool _recursive = true); + void copyFile(const etk::Path& _path1, const etk::Path& _path2); + + void move(const etk::Path& _path1, const etk::Path& _path2); + void moveDirectory(const etk::Path& _path1, const etk::Path& _path2); + void moveFile(const etk::Path& _path1, const etk::Path& _path2); + + void remove(const etk::Path& _path1, const etk::Path& _path2); + void removeDirectory(const etk::Path& _path1, const etk::Path& _path2); + void removeFile(const etk::Path& _path1, const etk::Path& _path2); + + bool exit(const etk::Path& _path); + uint_t fileSize(const etk::Path& _path); + + bool isDirectory(const etk::Path& _path); + bool isFile(const etk::Path& _path); + bool isSymLink(const etk::Path& _path); + + etk::filesystem::Permissions getPermission(const etk::Path& _path); + + etk::String getRelativeString(const etk::Path& _path); + etk::String getDecoratedString(const etk::Path& _path); + etk::String getAbsoluteString(const etk::Path& _path); + + etk::String getMimeType(const etk::Path& _path); + + etk::Path getTemporaryPath(); + etk::Path getHomePath(); + etk::Path getExecutionPath(); + etk::Path getBinaryPath(); + etk::Path getDataPath(); + + uint64_t getCreateTime(const etk::Path& _path); + uint64_t getModifyTime(const etk::Path& _path); + uint64_t getAccessTime(const etk::Path& _path); + uint32_t getIdOwner(const etk::Path& _path); + uint32_t getIdGroup(const etk::Path& _path); + } +} + diff --git a/etk/theme/theme.cpp b/etk/theme/theme.cpp new file mode 100644 index 0000000..c88f07f --- /dev/null +++ b/etk/theme/theme.cpp @@ -0,0 +1,56 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +#include +#include + +static etk::Map& getTheme() { + static etk::Map g_listTheme; + return g_listTheme; +} + +static etk::Map& getThemeDefault() { + static etk::Map g_listThemeDefault; + return g_listThemeDefault; +} + +void etk::theme::setName(const etk::String& _refName, const etk::String& _folderName) { + TK_WARNING("Change theme : '" << _refName << "' : '" << _folderName << "'"); + getTheme().set(_refName, _folderName); +} + +etk::String etk::theme::getName(const etk::String& _refName) { + auto it = getTheme().find(_refName); + if (it != getTheme().end()) { + return it->second; + } + return _refName; +} + +// get the list of all the theme folder availlable in the user Home/appl +etk::Vector etk::theme::list() { + etk::Vector keys; + for (auto &it : getTheme()) { + keys.pushBack(it.first); + } + return keys; +} + +void etk::theme::setNameDefault(const etk::String& _refName, const etk::String& _folderName) { + auto it = getThemeDefault().find(_refName); + if (it != getThemeDefault().end()) { + it->second = _folderName; + return; + } + getThemeDefault().set(_refName, _folderName); +} + +etk::String etk::theme::getNameDefault(const etk::String& _refName) { + auto it = getThemeDefault().find(_refName); + if (it != getThemeDefault().end()) { + return it->second; + } + return "default"; +} diff --git a/etk/theme/theme.hpp b/etk/theme/theme.hpp new file mode 100644 index 0000000..96f7719 --- /dev/null +++ b/etk/theme/theme.hpp @@ -0,0 +1,45 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ + +#include + +#pragma once + +namespace etk { + namespace theme { + // TODO : Add an INIT ... + /** + * @brief Set the Folder of a subset of a theme ... + * @param[in] _refName Theme cathegorie ex : "GUI" "SHADER" "DEFAULT" + * @param[in] _folderName The associated folder of the Theme (like "myTheme/folder/folder2/") + */ + void setName(const etk::String& _refName, const etk::String& _folderName); + /** + * @brief get the folder from a Reference theme + * @param[in] _refName Theme cathegorie ex : "GUI" "SHADER" "DEFAULT" + * @return the path of the theme + */ + etk::String getName(const etk::String& _refName); + /** + * @brief Set the default folder of a subset of a theme ... + * @param[in] _refName Theme cathegorie ex : "GUI" "SHADER" "DEFAULT" + * @param[in] _folderName The associated default folder of the Theme (like "myTheme/color/default/") + */ + void setNameDefault(const etk::String& _refName, const etk::String& _folderName); + /** + * @brief get the default folder from a Reference theme + * @param[in] _refName Theme cathegorie ex : "GUI" "SHADER" "DEFAULT" + * @return the path of the theme + */ + etk::String getNameDefault(const etk::String& _refName); + /** + * @brief Get the list of all the theme folder availlable in the user Home/appl + * @return The list of elements + */ + etk::Vector list(); + } +} + diff --git a/etk/types.hpp b/etk/types.hpp index 91afc28..1133330 100644 --- a/etk/types.hpp +++ b/etk/types.hpp @@ -38,6 +38,7 @@ extern "C" { ETK_TYPE_CLASS(ETK_TYPE_CLASS&& ) = delete; \ ETK_TYPE_CLASS& operator= (ETK_TYPE_CLASS&& ) = delete + // DEfine 2 basic type that depend on the machine word size. uint_t is better than size_t because whe have the usigned dual. using int_t = int; using uint_t = unsigned int;