From 247ada05cbccc7a904dd4c186dca3e348f96d0e7 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Tue, 9 Oct 2018 23:06:37 +0200 Subject: [PATCH] [DEV] update URI interface and Path --- etk-core/Allocator.cpp | 2 +- etk-core/Allocator.hpp | 2 +- etk-core/Vector.hpp | 7 ++ etk-core/utf8.cpp | 6 +- etk-core/utf8.hpp | 1 + etk/archive/Archive.cpp | 18 +++ etk/archive/Archive.hpp | 18 ++- etk/etk.cpp | 8 +- etk/io/Interface.cpp | 3 +- etk/io/ZipFile.cpp | 1 + etk/io/ZipFile.hpp | 2 +- etk/path/Path.cpp | 7 +- etk/path/fileSystem.cpp | 18 ++- etk/path/fileSystem.hpp | 7 ++ etk/theme/ProviderTheme.cpp | 172 +++++++++++++++++++++++++++ etk/theme/ProviderTheme.hpp | 30 +++++ etk/theme/theme.cpp | 37 +++--- etk/theme/theme.hpp | 9 +- etk/uri/provider/Interface.hpp | 26 ++++ etk/uri/provider/ProviderFile.cpp | 21 ++++ etk/uri/provider/ProviderFile.hpp | 3 + etk/uri/provider/ProviderFileZip.cpp | 19 +++ etk/uri/provider/ProviderFileZip.hpp | 3 + etk/uri/provider/provider.cpp | 16 ++- etk/uri/uri.cpp | 48 ++++++-- etk/uri/uri.hpp | 21 ++++ lutin_etk-core.py | 6 +- lutin_etk.py | 2 + test/testPath.cpp | 18 +++ test/testTheme.cpp | 26 ++-- test/testUriProvider.cpp | 12 +- 31 files changed, 515 insertions(+), 54 deletions(-) create mode 100644 etk/theme/ProviderTheme.cpp create mode 100644 etk/theme/ProviderTheme.hpp diff --git a/etk-core/Allocator.cpp b/etk-core/Allocator.cpp index 8b5885b..1cef2ff 100644 --- a/etk-core/Allocator.cpp +++ b/etk-core/Allocator.cpp @@ -33,7 +33,7 @@ void operator delete[] (void* ptr) { -#define ETK_MEM_DEBUG_LEVEL 4 +#define ETK_MEM_DEBUG_LEVEL 5 #define ETK_MEMORY_PRINT(...) \ do { \ diff --git a/etk-core/Allocator.hpp b/etk-core/Allocator.hpp index 5152cd2..250dd98 100644 --- a/etk-core/Allocator.hpp +++ b/etk-core/Allocator.hpp @@ -17,7 +17,7 @@ } #endif -//#define ETK_MEMORY_CHECKER 0 +//#define ETK_MEMORY_CHECKER 2 #ifndef ETK_MEMORY_CHECKER #define ETK_MEMORY_CHECKER 0 diff --git a/etk-core/Vector.hpp b/etk-core/Vector.hpp index 104d847..85bd8c9 100644 --- a/etk-core/Vector.hpp +++ b/etk-core/Vector.hpp @@ -850,6 +850,7 @@ namespace etk { // check if something is allocated : if (m_data == null) { // no data allocated ==> request an allocation (might be the first) + //printf("Allocate : %d\n", int(sizeof(ETK_VECTOR_TYPE)*requestSize)); m_data = (ETK_VECTOR_TYPE*)ETK_MALLOC(char, sizeof(ETK_VECTOR_TYPE)*requestSize); if (m_data == null) { //TK_CRITICAL("Vector : Error in data allocation request allocation:" << requestSize << "*" << (int32_t)(sizeof(ETK_VECTOR_TYPE)) << "bytes" ); @@ -865,6 +866,12 @@ namespace etk { #endif } else { // allocate a new pool of data: + /* + printf("Allocate : %d\n", int(sizeof(ETK_VECTOR_TYPE)*requestSize)); + if ( int(sizeof(ETK_VECTOR_TYPE)*requestSize) > 33554432) { + throw "hello"; + } + */ ETK_VECTOR_TYPE* dataTmp = (ETK_VECTOR_TYPE*)ETK_MALLOC(char, sizeof(ETK_VECTOR_TYPE)*requestSize);; if (dataTmp == null) { //TK_CRITICAL("Vector : Error in data allocation request allocation:" << requestSize << "*" << (int32_t)(sizeof(ETK_VECTOR_TYPE)) << "bytes" ); diff --git a/etk-core/utf8.cpp b/etk-core/utf8.cpp index 4b62dc9..ff1f182 100644 --- a/etk-core/utf8.cpp +++ b/etk-core/utf8.cpp @@ -129,6 +129,10 @@ etk::String u32char::convertToUtf8(const etk::UString& _input) { return etk::toString(_input); } +etk::String u32char::convertToUtf8(char32_t _input) { + return etk::toString(etk::UString(_input)); +} + size_t u32char::strlen(const char32_t* _input) { uint32_t out = 0; while (*_input != 0) { @@ -193,7 +197,7 @@ char32_t u32char::toLower(char32_t _input) { static uint8_t sizeElement(const char* _data, int32_t _lenMax) { - uint8_t size = 0; + uint8_t size = 1; //TK_ASSERT(0 <= _lenMax, "size can not be < 0 ..."); if (0 > _lenMax) { return 0; diff --git a/etk-core/utf8.hpp b/etk-core/utf8.hpp index 61142c5..d01baea 100644 --- a/etk-core/utf8.hpp +++ b/etk-core/utf8.hpp @@ -67,6 +67,7 @@ namespace u32char { */ int8_t convertUtf8(char32_t _val, char _output[7]); etk::String convertToUtf8(const etk::UString& _input); + etk::String convertToUtf8(char32_t _input); char32_t toUpper(char32_t _input); char32_t toLower(char32_t _input); size_t strlen(const char32_t* _input); diff --git a/etk/archive/Archive.cpp b/etk/archive/Archive.cpp index 544e109..fdf924b 100644 --- a/etk/archive/Archive.cpp +++ b/etk/archive/Archive.cpp @@ -47,6 +47,24 @@ ememory::SharedPtr etk::Archive::getContent(const etk::Path bool etk::Archive::exist(const etk::Path& _key) const { + ethread::UniqueLock lock(m_mutex); + if (m_content.find(_key) != m_content.end()) { + return true; + } + return isDirectory(_key); +} + +bool etk::Archive::isDirectory(const etk::Path& _key) const { + etk::String base = _key.getString() + "/"; + for (auto &it: m_content) { + if (it.first.getString().startWith(base) == true) { + return true; + } + } + return false; +} + +bool etk::Archive::isFile(const etk::Path& _key) const { ethread::UniqueLock lock(m_mutex); return m_content.find(_key) != m_content.end(); } diff --git a/etk/archive/Archive.hpp b/etk/archive/Archive.hpp index 39be297..f2a99c7 100644 --- a/etk/archive/Archive.hpp +++ b/etk/archive/Archive.hpp @@ -20,7 +20,7 @@ namespace etk { */ class ArchiveContent { private: - int32_t m_link; //!< number of element open on this file + int32_t m_link = 0; //!< number of element open on this file public: /** * @brief Increment the number of user of this resource (permit to keep data alive) @@ -42,7 +42,7 @@ namespace etk { return m_link; } private: - int32_t m_theoricSize; //!< Size set by the zip file (theoric ==> the data has not been read) + int32_t m_theoricSize = -1; //!< Size set by the zip file (theoric ==> the data has not been read) public: /** * @brief Get the size of the element (size set by Zip file (not read)) @@ -148,6 +148,20 @@ namespace etk { * @return true if the file is present */ bool exist(const etk::Path& _key) const; + /** + * @brief Check if the path is a directory. + * @param[in] _key Name of the file + * @return true This is a directory. + * @return false This is something else... + */ + bool isDirectory(const etk::Path& _key) const; + /** + * @brief Check if the path is a file (regular). + * @param[in] _key Name of the file + * @return true This is a file. + * @return false This is something else... + */ + bool isFile(const etk::Path& _key) const; /** * @brief Load the specific file in the memory * @param[in] _key Name of the file diff --git a/etk/etk.cpp b/etk/etk.cpp index f50c5da..c1bfa28 100644 --- a/etk/etk.cpp +++ b/etk/etk.cpp @@ -14,7 +14,7 @@ #include #include #include - +#include static int32_t nbTimeInit = 0; void etk::unInit() { @@ -50,6 +50,12 @@ void etk::init(int _argc, const char** _argv) { } elog::init(_argc, _argv, etk::path::getBinaryName()); etk::uri::provider::init(); + // Add default elements for the DATA:/// USER_DATA:// TMP:// HOME:// + etk::uri::provider::add("DATA", ememory::makeShared(etk::path::getDataPath())); + etk::uri::provider::add("USER_DATA", ememory::makeShared(etk::path::getHomePath() / ".local" / "share" / etk::path::getBinaryName())); + etk::uri::provider::add("CONFIG", ememory::makeShared(etk::path::getHomePath() / ".config" / "share" / etk::path::getBinaryName())); + etk::uri::provider::add("CACHE", ememory::makeShared(etk::path::getHomePath() / ".cache" / etk::path::getBinaryName())); + etk::uri::provider::add("TMP", ememory::makeShared(etk::path::getTemporaryProcessPath())); etk::theme::init(); for (int32_t iii=0; iii<_argc ; ++iii) { etk::String data = _argv[iii]; diff --git a/etk/io/Interface.cpp b/etk/io/Interface.cpp index 7a1836e..bfbb6f8 100644 --- a/etk/io/Interface.cpp +++ b/etk/io/Interface.cpp @@ -23,7 +23,8 @@ bool etk::io::Interface::gets(etk::String& _output) { _output += tmp; tmp = get(); } - if (tmp == '\0') { + if ( tmp == '\0' + && _output.isEmpty() == true) { return false; } return true; diff --git a/etk/io/ZipFile.cpp b/etk/io/ZipFile.cpp index e3079f3..4a63bf2 100644 --- a/etk/io/ZipFile.cpp +++ b/etk/io/ZipFile.cpp @@ -25,6 +25,7 @@ bool etk::io::ZipFile::open(etk::io::OpenMode _mode) { if (m_archive == null) { return false; } + m_offset = 0; TK_VERBOSE(" Read file : " << m_path); switch (_mode) { case etk::io::OpenMode::Read: diff --git a/etk/io/ZipFile.hpp b/etk/io/ZipFile.hpp index e347a8f..591880c 100644 --- a/etk/io/ZipFile.hpp +++ b/etk/io/ZipFile.hpp @@ -21,7 +21,7 @@ namespace etk { etk::Path m_path; //!< Path to access in this interface ememory::SharedPtr m_archive; //!< Archive interface ememory::SharedPtr m_content; //!< Data in the archive file - int32_t m_offset; + int32_t m_offset = 0; public: ZipFile(ememory::SharedPtr _archive); ZipFile(const etk::Path& _path, ememory::SharedPtr _archive); diff --git a/etk/path/Path.cpp b/etk/path/Path.cpp index d355ad6..a1ae335 100644 --- a/etk/path/Path.cpp +++ b/etk/path/Path.cpp @@ -327,10 +327,11 @@ etk::Path etk::Path::getExtentionRemoved() const { void etk::Path::parent() { size_t pos = m_data.rfind('/'); if (pos == etk::String::npos) { + m_data = ""; return; } if (pos == 0) { - // Last root element ==> do nothing. + m_data = "/"; return; } m_data = m_data.extract(0, pos); @@ -389,6 +390,10 @@ etk::Path& etk::Path::operator/= (const etk::Path& _path) { if (_path.m_data[0] == '/') { ETK_THROW_EXCEPTION(etk::exception::InvalidArgument("add path that is absolute")); } + if (m_data.isEmpty() == true){ + m_data = _path.m_data; + return *this; + } m_data += '/' + _path.m_data; m_data = simplifyPath(m_data); return *this; diff --git a/etk/path/fileSystem.cpp b/etk/path/fileSystem.cpp index f915d34..6211fe9 100644 --- a/etk/path/fileSystem.cpp +++ b/etk/path/fileSystem.cpp @@ -232,6 +232,14 @@ bool etk::path::isSymLink(const etk::Path& _path) { return true; } +bool etk::path::haveChild(const etk::Path& _path) { + if (isDirectory(_path) == false) { + return false; + } + // TODO: do it better. it work, but is slow ... + return list(_path).size() != 0; +} + etk::path::Permissions etk::path::getPermission(const etk::Path& _path) { etk::path::Permissions permissions; @@ -481,6 +489,8 @@ etk::Vector etk::path::list(const etk::Path& _path, uint32_t _flags) } DIR *dir = null; struct dirent *ent = null; + TK_VERBOSE("List path: " << _path << " with flags: " << _flags); + TK_VERBOSE(" native=" << _path.getNative()); dir = opendir(_path.getNative().c_str()); if (dir != null) { // for each element in the drectory... @@ -491,6 +501,7 @@ etk::Vector etk::path::list(const etk::Path& _path, uint32_t _flags) // do nothing ... continue; } + TK_VERBOSE(" find=" << ent->d_name); etk::Path tmpPath = _path / ent->d_name; if (_flags == etk::path::LIST_ALL) { out.pushBack(tmpPath); @@ -498,18 +509,23 @@ etk::Vector etk::path::list(const etk::Path& _path, uint32_t _flags) } // Hidden file if ( ent->d_name[0] == '.' - || (_flags & etk::path::LIST_HIDDEN) == 0) { + && (_flags & etk::path::LIST_HIDDEN) == 0) { + TK_VERBOSE(" ==> hidden"); continue; } // FOLDER if (etk::path::isDirectory(tmpPath) == true) { if ((_flags & etk::path::LIST_FOLDER) != 0) { + TK_VERBOSE(" ==> directory (add)"); out.pushBack(tmpPath); + } else { + TK_VERBOSE(" ==> directory"); } continue; } // OTHER ==> clasify as file ==> 99.9999% of usage if ((_flags & etk::path::LIST_FILE) != 0) { + TK_VERBOSE(" ==> file (add)"); out.pushBack(tmpPath); } } diff --git a/etk/path/fileSystem.hpp b/etk/path/fileSystem.hpp index 78663f7..bb23c23 100644 --- a/etk/path/fileSystem.hpp +++ b/etk/path/fileSystem.hpp @@ -150,6 +150,13 @@ namespace etk { * @return false This is something else... */ bool isSymLink(const etk::Path& _path); + /** + * @brief check if the path have under file inside. + * @param[in] _path Path of the requested information. + * @return true This contain sub elements. + * @return false This is empty. + */ + bool haveChild(const etk::Path& _path); /** * @brief Get the relative string of the path. * @param[in] _path Path to transform. diff --git a/etk/theme/ProviderTheme.cpp b/etk/theme/ProviderTheme.cpp new file mode 100644 index 0000000..556717f --- /dev/null +++ b/etk/theme/ProviderTheme.cpp @@ -0,0 +1,172 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +#include +#include +#include +#include +#include + +etk::theme::ProviderTheme::ProviderTheme() { + +} + +etk::theme::ProviderTheme::ProviderTheme(const etk::Path& _offset, const etk::Path& _offsetDefault) : + m_offset(_offset), + m_offsetDefault(_offsetDefault) { + +} + +ememory::SharedPtr etk::theme::ProviderTheme::create(const etk::Uri& _uri) { + etk::Uri uri = _uri; + uri.setScheme("DATA"); + TK_WARNING("Create URI file IO " << _uri); + if (m_offset.isEmpty() == true) { + TK_WARNING(" check " << uri); + if (etk::uri::exist(uri) == true) { + TK_WARNING(" ==> find"); + return etk::uri::get(uri); + } + } else { + uri.setPath(m_offset / _uri.getPath()); + TK_WARNING(" check " << uri); + if (etk::uri::exist(uri) == true) { + TK_WARNING(" ==> find"); + return etk::uri::get(uri); + } + } + if ( m_offsetDefault.isEmpty() == false + && m_offsetDefault != "theme") { + etk::Uri uri2 = uri; + uri2.setPath(m_offsetDefault / _uri.getPath()); + TK_WARNING(" check " << uri2); + if (etk::uri::exist(uri2) == true) { + TK_WARNING(" ==> find"); + return etk::uri::get(uri2); + } + } + TK_WARNING(" ** Find nothing ..."); + return etk::uri::get(uri); +} + +bool etk::theme::ProviderTheme::exist(const etk::Uri& _uri) { + etk::Uri uri = _uri; + uri.setScheme("DATA"); + TK_WARNING("Exist URI file IO " << _uri); + if (m_offset.isEmpty() == true) { + TK_WARNING(" check " << uri); + if (etk::uri::exist(uri) == true) { + TK_WARNING(" ==> true"); + return true; + } + } else { + uri.setPath(m_offset / _uri.getPath()); + TK_WARNING(" check " << uri); + if (etk::uri::exist(uri) == true) { + TK_WARNING(" ==> true"); + return true; + } + } + if ( m_offsetDefault.isEmpty() == false + && m_offsetDefault != "theme") { + etk::Uri uri2 = uri; + uri2.setPath(m_offsetDefault / _uri.getPath()); + TK_WARNING(" check " << uri2); + if (etk::uri::exist(uri2) == true) { + TK_WARNING(" ==> true"); + return true; + } + } + TK_WARNING(" ** Find nothing ..."); + return false; +} + +bool etk::theme::ProviderTheme::isDirectory(const etk::Uri& _uri) { + // TODO: + throw "kjkjkj"; +} + +bool etk::theme::ProviderTheme::isFile(const etk::Uri& _uri) { + // TODO: + throw "kjkjkj"; +} + +bool etk::theme::ProviderTheme::isSymLink(const etk::Uri& _uri) { + // TODO: + throw "kjkjkj"; +} + +etk::Vector etk::theme::ProviderTheme::list(const etk::Uri& _uri) { + etk::Uri uri = _uri; + uri.setScheme("DATA"); + etk::Vector directList; + if (m_offset.isEmpty() == true) { + directList = etk::uri::list(uri); + } else { + uri.setPath(m_offset / _uri.getPath()); + directList = etk::uri::list(uri); + } + etk::Vector defaultList; + if ( m_offsetDefault.isEmpty() == false + && m_offsetDefault != "theme") { + uri.setPath(m_offsetDefault / _uri.getPath()); + defaultList = etk::uri::list(uri); + } + for (auto& it: defaultList) { + it.setScheme(_uri.getScheme()); + } + for (auto& it: directList) { + it.setScheme(_uri.getScheme()); + } + if (defaultList.size() == 0) { + return directList; + } + if (directList.size() == 0) { + return defaultList; + } + for (auto& it: defaultList) { + if (etk::isIn(it, directList) == false) { + directList.pushBack(it); + } + } + return directList; +} + +etk::Vector etk::theme::ProviderTheme::listRecursive(const etk::Uri& _uri) { + etk::Uri uri = _uri; + uri.setScheme("DATA"); + etk::Vector directList; + if (m_offset.isEmpty() == true) { + directList = etk::uri::listRecursive(uri); + } else { + uri.setPath(m_offset / _uri.getPath()); + directList = etk::uri::listRecursive(uri); + } + etk::Vector defaultList; + if ( m_offsetDefault.isEmpty() == false + && m_offsetDefault != "theme") { + uri.setPath(m_offsetDefault / _uri.getPath()); + defaultList = etk::uri::listRecursive(uri); + } + for (auto& it: defaultList) { + it.setScheme(_uri.getScheme()); + } + for (auto& it: directList) { + it.setScheme(_uri.getScheme()); + } + if (defaultList.size() == 0) { + return directList; + } + if (directList.size() == 0) { + return defaultList; + } + for (auto& it: defaultList) { + if (etk::isIn(it, directList) == false) { + directList.pushBack(it); + } + } + return directList; +} + diff --git a/etk/theme/ProviderTheme.hpp b/etk/theme/ProviderTheme.hpp new file mode 100644 index 0000000..08b5bea --- /dev/null +++ b/etk/theme/ProviderTheme.hpp @@ -0,0 +1,30 @@ +/** @file + * @author Edouard DUPIN + * @copyright 2018, Edouard DUPIN, all right reserved + * @license MPL v2.0 (see license file) + */ +#pragma once + +#include +#include + +namespace etk { + namespace theme { + class ProviderTheme : public etk::uri::provider::Interface { + protected: + etk::Path m_offset; + etk::Path m_offsetDefault; + public: + ProviderTheme(); + ProviderTheme(const etk::Path& _offset, const etk::Path& _offsetDefault); + public: + ememory::SharedPtr create(const etk::Uri& _uri) override; + bool exist(const etk::Uri& _uri) override; + bool isDirectory(const etk::Uri& _uri) override; + bool isFile(const etk::Uri& _uri) override; + bool isSymLink(const etk::Uri& _uri) override; + etk::Vector list(const etk::Uri& _uri) override; + etk::Vector listRecursive(const etk::Uri& _uri) override; + }; + } +} diff --git a/etk/theme/theme.cpp b/etk/theme/theme.cpp index 0bb4837..3fe0d6f 100644 --- a/etk/theme/theme.cpp +++ b/etk/theme/theme.cpp @@ -5,20 +5,32 @@ */ #include #include +#include #include #include +#include -static etk::Map& getTheme() { - static etk::Map g_listTheme; +static etk::Map& getTheme() { + static etk::Map g_listTheme; return g_listTheme; } -static etk::Map& getThemeDefault() { - static etk::Map g_listThemeDefault; +static etk::Map& getThemeDefault() { + static etk::Map g_listThemeDefault; return g_listThemeDefault; } +static void updateProvider(const etk::String& _refName) { + etk::Path base = etk::theme::getName(_refName); + etk::Path baseDefault = etk::theme::getNameDefault(_refName); + if (base.isEmpty() == true) { + etk::uri::provider::add("THEME_" + _refName, ememory::makeShared(etk::Path("theme") / baseDefault, etk::Path("theme") / base)); + } else { + etk::uri::provider::add("THEME_" + _refName, ememory::makeShared(etk::Path("theme") / base, etk::Path("theme") / baseDefault)); + } +} + void etk::theme::init() { } @@ -28,17 +40,18 @@ void etk::theme::unInit() { getThemeDefault().clear(); } -void etk::theme::setName(const etk::String& _refName, const etk::String& _folderName) { +void etk::theme::setName(const etk::String& _refName, const etk::Path& _folderName) { TK_WARNING("Change theme : '" << _refName << "' : '" << _folderName << "'"); getTheme().set(_refName, _folderName); + updateProvider(_refName); } -etk::String etk::theme::getName(const etk::String& _refName) { +etk::Path etk::theme::getName(const etk::String& _refName) { auto it = getTheme().find(_refName); if (it != getTheme().end()) { return it->second; } - return _refName; + return ""; } // get the list of all the theme folder availlable in the user Home/appl @@ -50,16 +63,12 @@ etk::Vector etk::theme::list() { 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; - } +void etk::theme::setNameDefault(const etk::String& _refName, const etk::Path& _folderName) { getThemeDefault().set(_refName, _folderName); + updateProvider(_refName); } -etk::String etk::theme::getNameDefault(const etk::String& _refName) { +etk::Path etk::theme::getNameDefault(const etk::String& _refName) { auto it = getThemeDefault().find(_refName); if (it != getThemeDefault().end()) { return it->second; diff --git a/etk/theme/theme.hpp b/etk/theme/theme.hpp index 2537905..dd0b7cb 100644 --- a/etk/theme/theme.hpp +++ b/etk/theme/theme.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #pragma once @@ -25,25 +26,25 @@ namespace etk { * @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); + void setName(const etk::String& _refName, const etk::Path& _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); + etk::Path 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); + void setNameDefault(const etk::String& _refName, const etk::Path& _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); + etk::Path 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 diff --git a/etk/uri/provider/Interface.hpp b/etk/uri/provider/Interface.hpp index 5df6856..a77eb68 100644 --- a/etk/uri/provider/Interface.hpp +++ b/etk/uri/provider/Interface.hpp @@ -23,7 +23,33 @@ namespace etk { virtual ~Interface() = default; public: virtual ememory::SharedPtr create(const etk::Uri& _uri) = 0; + /** + * @brief Check if an URI really exist. + * @param[in] _uri Uri to check. + * @return true if exist, false ortherwise + */ virtual bool exist(const etk::Uri& _uri) = 0; + /** + * @brief Check if the path is a directory. + * @param[in] _uri Uri to check. + * @return true This is a directory. + * @return false This is something else... + */ + virtual bool isDirectory(const etk::Uri& _uri) = 0; + /** + * @brief Check if the path is a file (regular). + * @param[in] _uri Uri to check. + * @return true This is a file. + * @return false This is something else... + */ + virtual bool isFile(const etk::Uri& _uri) = 0; + /** + * @brief check if the path is a symbolink link. + * @param[in] _uri Uri to check. + * @return true This is a synbolic link. + * @return false This is something else... + */ + virtual bool isSymLink(const etk::Uri& _uri) = 0; virtual etk::Vector list(const etk::Uri& _uri) = 0; virtual etk::Vector listRecursive(const etk::Uri& _uri) = 0; virtual bool canMove() { return false; } diff --git a/etk/uri/provider/ProviderFile.cpp b/etk/uri/provider/ProviderFile.cpp index 7176ffa..d0cec86 100644 --- a/etk/uri/provider/ProviderFile.cpp +++ b/etk/uri/provider/ProviderFile.cpp @@ -31,6 +31,27 @@ bool etk::uri::provider::ProviderFile::exist(const etk::Uri& _uri) { return etk::path::exist(m_offset / _uri.getPath()); } +bool etk::uri::provider::ProviderFile::isDirectory(const etk::Uri& _uri) { + if (m_offset.isEmpty() == true) { + return etk::path::isDirectory(_uri.getPath()); + } + return etk::path::isDirectory(m_offset / _uri.getPath()); +} + +bool etk::uri::provider::ProviderFile::isFile(const etk::Uri& _uri) { + if (m_offset.isEmpty() == true) { + return etk::path::isFile(_uri.getPath()); + } + return etk::path::isFile(m_offset / _uri.getPath()); +} + +bool etk::uri::provider::ProviderFile::isSymLink(const etk::Uri& _uri) { + if (m_offset.isEmpty() == true) { + return etk::path::isSymLink(_uri.getPath()); + } + return etk::path::isSymLink(m_offset / _uri.getPath()); +} + etk::Vector etk::uri::provider::ProviderFile::list(const etk::Uri& _uri) { etk::Vector tmp; etk::Vector out; diff --git a/etk/uri/provider/ProviderFile.hpp b/etk/uri/provider/ProviderFile.hpp index d641c7e..225c003 100644 --- a/etk/uri/provider/ProviderFile.hpp +++ b/etk/uri/provider/ProviderFile.hpp @@ -20,6 +20,9 @@ namespace etk { public: ememory::SharedPtr create(const etk::Uri& _uri) override; bool exist(const etk::Uri& _uri) override; + bool isDirectory(const etk::Uri& _uri) override; + bool isFile(const etk::Uri& _uri) override; + bool isSymLink(const etk::Uri& _uri) override; etk::Vector list(const etk::Uri& _uri) override; etk::Vector listRecursive(const etk::Uri& _uri) override; virtual bool canMove() override; diff --git a/etk/uri/provider/ProviderFileZip.cpp b/etk/uri/provider/ProviderFileZip.cpp index 95af103..12fca6b 100644 --- a/etk/uri/provider/ProviderFileZip.cpp +++ b/etk/uri/provider/ProviderFileZip.cpp @@ -38,6 +38,25 @@ bool etk::uri::provider::ProviderFileZip::exist(const etk::Uri& _uri) { return m_archive->exist(m_offset / _uri.getPath()); } +bool etk::uri::provider::ProviderFileZip::isDirectory(const etk::Uri& _uri) { + if (m_offset.isEmpty() == true) { + return m_archive->isDirectory(_uri.getPath()); + } + return m_archive->isDirectory(m_offset / _uri.getPath()); +} + +bool etk::uri::provider::ProviderFileZip::isFile(const etk::Uri& _uri) { + if (m_offset.isEmpty() == true) { + return m_archive->isFile(_uri.getPath()); + } + return m_archive->isFile(m_offset / _uri.getPath()); +} + +bool etk::uri::provider::ProviderFileZip::isSymLink(const etk::Uri& _uri) { + // No symlink in ZIP ... + return false; +} + etk::Vector etk::uri::provider::ProviderFileZip::list(const etk::Uri& _uri) { etk::Vector tmp; etk::Vector out; diff --git a/etk/uri/provider/ProviderFileZip.hpp b/etk/uri/provider/ProviderFileZip.hpp index a147f75..c4d20b9 100644 --- a/etk/uri/provider/ProviderFileZip.hpp +++ b/etk/uri/provider/ProviderFileZip.hpp @@ -25,6 +25,9 @@ namespace etk { public: ememory::SharedPtr create(const etk::Uri& _uri) override; bool exist(const etk::Uri& _uri) override; + bool isDirectory(const etk::Uri& _uri) override; + bool isFile(const etk::Uri& _uri) override; + bool isSymLink(const etk::Uri& _uri) override; etk::Vector list(const etk::Uri& _uri) override; etk::Vector listRecursive(const etk::Uri& _uri) override; }; diff --git a/etk/uri/provider/provider.cpp b/etk/uri/provider/provider.cpp index 1607ce7..b979dd5 100644 --- a/etk/uri/provider/provider.cpp +++ b/etk/uri/provider/provider.cpp @@ -21,27 +21,37 @@ namespace etk { } } +static void displayProviders() { + TK_INFO("List all datat provider:"); + for (auto& it: etk::uri::provider::getProviders()) { + TK_INFO(" - " << it.first); + } +} + void etk::uri::provider::add(const etk::String& _scheme, ememory::SharedPtr _interface) { etk::String scheme = _scheme; if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } etk::uri::provider::getProviders().set(scheme, _interface); + displayProviders(); } void etk::uri::provider::clear() { etk::uri::provider::getProviders().clear(); etk::uri::provider::add("", ememory::makeShared()); + displayProviders(); } void etk::uri::provider::remove(const etk::String& _scheme) { etk::uri::provider::getProviders().erase(_scheme); + displayProviders(); } bool etk::uri::provider::exist(const etk::String& _scheme) { etk::String scheme = _scheme; if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } return etk::uri::provider::getProviders().exist(scheme); } @@ -49,7 +59,7 @@ bool etk::uri::provider::exist(const etk::String& _scheme) { ememory::SharedPtr etk::uri::provider::getProvider(const etk::String& _scheme) { etk::String scheme = _scheme; if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } if (etk::uri::provider::getProviders().exist(scheme) == false) { return null; diff --git a/etk/uri/uri.cpp b/etk/uri/uri.cpp index bd263bd..f74ab70 100644 --- a/etk/uri/uri.cpp +++ b/etk/uri/uri.cpp @@ -21,7 +21,7 @@ namespace etk { bool etk::uri::exist(const etk::Uri& _uri) { etk::String scheme = _uri.getScheme(); if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } if (etk::uri::provider::getProviders().exist(scheme) == false) { return false; @@ -29,10 +29,43 @@ bool etk::uri::exist(const etk::Uri& _uri) { return etk::uri::provider::getProviders()[scheme]->exist(_uri); } +bool etk::uri::isDirectory(const etk::Uri& _uri) { + etk::String scheme = _uri.getScheme(); + if (scheme.empty() == true) { + scheme = "FILE"; + } + if (etk::uri::provider::getProviders().exist(scheme) == false) { + return false; + } + return etk::uri::provider::getProviders()[scheme]->isDirectory(_uri); +} + +bool etk::uri::isFile(const etk::Uri& _uri) { + etk::String scheme = _uri.getScheme(); + if (scheme.empty() == true) { + scheme = "FILE"; + } + if (etk::uri::provider::getProviders().exist(scheme) == false) { + return false; + } + return etk::uri::provider::getProviders()[scheme]->isFile(_uri); +} + +bool etk::uri::isSymLink(const etk::Uri& _uri) { + etk::String scheme = _uri.getScheme(); + if (scheme.empty() == true) { + scheme = "FILE"; + } + if (etk::uri::provider::getProviders().exist(scheme) == false) { + return false; + } + return etk::uri::provider::getProviders()[scheme]->isSymLink(_uri); +} + etk::Vector etk::uri::list(const etk::Uri& _uri) { etk::String scheme = _uri.getScheme(); if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } if (etk::uri::provider::getProviders().exist(scheme) == false) { return etk::Vector(); @@ -43,7 +76,7 @@ etk::Vector etk::uri::list(const etk::Uri& _uri) { etk::Vector etk::uri::listRecursive(const etk::Uri& _uri) { etk::String scheme = _uri.getScheme(); if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } if (etk::uri::provider::getProviders().exist(scheme) == false) { return etk::Vector(); @@ -51,9 +84,10 @@ etk::Vector etk::uri::listRecursive(const etk::Uri& _uri) { return etk::uri::provider::getProviders()[scheme]->listRecursive(_uri); } ememory::SharedPtr etk::uri::get(const etk::Uri& _uri) { + TK_WARNING("uri get: " << _uri); etk::String scheme = _uri.getScheme(); if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } if (etk::uri::provider::getProviders().exist(scheme) == false) { TK_ERROR("lklklk " << scheme << " " << _uri << " " << etk::uri::provider::getProviders().getKeys()); @@ -68,7 +102,7 @@ ememory::SharedPtr etk::uri::get(const etk::Uri& _uri) { bool etk::uri::canMove(const etk::Uri& _uri) { etk::String scheme = _uri.getScheme(); if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } if (etk::uri::provider::getProviders().exist(scheme) == false) { return false; @@ -79,11 +113,11 @@ bool etk::uri::canMove(const etk::Uri& _uri) { bool etk::uri::move(const etk::Uri& _uriSource, const etk::Uri& _uriDestination) { etk::String scheme = _uriSource.getScheme(); if (scheme.empty() == true) { - scheme = "RAW"; + scheme = "FILE"; } etk::String scheme2 = _uriDestination.getScheme(); if (scheme2.empty() == true) { - scheme2 = "RAW"; + scheme2 = "FILE"; } if (scheme != scheme2) { TK_ERROR("Can not move 2 uri between 2 model of resource... " << _uriSource << " => " << _uriDestination); diff --git a/etk/uri/uri.hpp b/etk/uri/uri.hpp index 3c91e87..8eb37c6 100644 --- a/etk/uri/uri.hpp +++ b/etk/uri/uri.hpp @@ -22,6 +22,27 @@ namespace etk { * @return true if exist, false ortherwise */ bool exist(const etk::Uri& _uri); + /** + * @brief Check if the path is a directory. + * @param[in] _uri Uri to check. + * @return true This is a directory. + * @return false This is something else... + */ + bool isDirectory(const etk::Uri& _uri); + /** + * @brief Check if the path is a file (regular). + * @param[in] _uri Uri to check. + * @return true This is a file. + * @return false This is something else... + */ + bool isFile(const etk::Uri& _uri); + /** + * @brief check if the path is a symbolink link. + * @param[in] _uri Uri to check. + * @return true This is a synbolic link. + * @return false This is something else... + */ + bool isSymLink(const etk::Uri& _uri); /** * @brief Get the list of sub-element in the Uri * @param[in] _uri Uri requested as parent. diff --git a/lutin_etk-core.py b/lutin_etk-core.py index 4e5452e..3219657 100644 --- a/lutin_etk-core.py +++ b/lutin_etk-core.py @@ -69,7 +69,11 @@ def configure(target, my_module): 'm', "pthread", ]) - + """ + my_module.add_flag('c++', [ + "-DETK_MEMORY_CHECKER=2" + ], export=True) + """ if "Android" in target.get_type(): my_module.add_depend("SDK") if "MacOs" in target.get_type(): diff --git a/lutin_etk.py b/lutin_etk.py index 5b6f9d8..cacc9af 100644 --- a/lutin_etk.py +++ b/lutin_etk.py @@ -43,6 +43,7 @@ def configure(target, my_module): 'etk/io/File.cpp', 'etk/io/ZipFile.cpp', 'etk/theme/theme.cpp', + 'etk/theme/ProviderTheme.cpp', 'etk/math/Matrix2x2.cpp', 'etk/math/Matrix2x3.cpp', 'etk/math/Matrix3x3.cpp', @@ -79,6 +80,7 @@ def configure(target, my_module): 'etk/io/File.hpp', 'etk/io/ZipFile.hpp', 'etk/theme/theme.hpp', + 'etk/theme/ProviderTheme.hpp', 'etk/math/Matrix2x2.hpp', 'etk/math/Matrix2x3.hpp', 'etk/math/Matrix3x3.hpp', diff --git a/test/testPath.cpp b/test/testPath.cpp index 916d461..a679457 100644 --- a/test/testPath.cpp +++ b/test/testPath.cpp @@ -85,6 +85,20 @@ TEST(TestPath, assignation) { } +TEST(TestPath, operator_devide) { + etk::Path path; + EXPECT_EQ(path.getString(), ""); + path = "/home"; + EXPECT_EQ(path.getString(), "/home"); + path /= "rastapopoulos"; + EXPECT_EQ(path.getString(), "/home/rastapopoulos"); + path = ""; + path /= "plouf.txt"; + EXPECT_EQ(path.getString(), "plouf.txt"); + path = ""; + path = path / "plouf.txt"; + EXPECT_EQ(path.getString(), "plouf.txt");} + TEST(TestPath, simplification) { etk::Path path("/home/../plouf"); EXPECT_EQ(path.getString(), "/plouf"); @@ -135,6 +149,10 @@ TEST(TestPath, parent) { EXPECT_EQ(path.getString(), "/home/plouf/plaf"); path = "/"; EXPECT_EQ(path.getParent(), "/"); + path = "/wxdvsdf"; + EXPECT_EQ(path.getParent(), "/"); + path = "plouf.txt"; + EXPECT_EQ(path.getParent(), ""); } TEST(TestPath, getRelative) { diff --git a/test/testTheme.cpp b/test/testTheme.cpp index 4ecb8ce..c33358e 100644 --- a/test/testTheme.cpp +++ b/test/testTheme.cpp @@ -13,28 +13,28 @@ TEST(TestTheme, init_uninit) { etk::theme::init(); etk::theme::setName("AAA", "aaa"); - EXPECT_EQ(etk::theme::getNameDefault("AAA"), ""); - EXPECT_EQ(etk::theme::getName("AAA"), "aaa"); + EXPECT_EQ(etk::theme::getNameDefault("AAA"), etk::Path("default")); + EXPECT_EQ(etk::theme::getName("AAA"), etk::Path("aaa")); etk::theme::unInit(); - EXPECT_EQ(etk::theme::getNameDefault("AAA"), ""); - EXPECT_EQ(etk::theme::getName("AAA"), ""); + EXPECT_EQ(etk::theme::getNameDefault("AAA"), etk::Path("default")); + EXPECT_EQ(etk::theme::getName("AAA"), etk::Path()); } TEST(TestTheme, set) { etk::theme::init(); - etk::theme::setNameDefault("AAA", "aaa"); - EXPECT_EQ(etk::theme::getNameDefault("AAA"), "aaa"); - EXPECT_EQ(etk::theme::getName("AAA"), "aaa"); + etk::theme::setNameDefault("AAA", etk::Path("aaa")); + EXPECT_EQ(etk::theme::getNameDefault("AAA"), etk::Path("aaa")); + EXPECT_EQ(etk::theme::getName("AAA"), etk::Path()); etk::theme::unInit(); - EXPECT_EQ(etk::theme::getNameDefault("AAA"), ""); - EXPECT_EQ(etk::theme::getName("AAA"), ""); + EXPECT_EQ(etk::theme::getNameDefault("AAA"), etk::Path("default")); + EXPECT_EQ(etk::theme::getName("AAA"), etk::Path()); } TEST(TestTheme, set2) { etk::theme::init(); - etk::theme::setNameDefault("AAA", "aaa"); - etk::theme::setName("AAA", "bbb"); - EXPECT_EQ(etk::theme::getNameDefault("AAA"), "aaa"); - EXPECT_EQ(etk::theme::getName("AAA"), "bbb"); + etk::theme::setNameDefault("AAA", etk::Path("aaa")); + etk::theme::setName("AAA", etk::Path("bbb")); + EXPECT_EQ(etk::theme::getNameDefault("AAA"), etk::Path("aaa")); + EXPECT_EQ(etk::theme::getName("AAA"), etk::Path("bbb")); etk::theme::unInit(); } diff --git a/test/testUriProvider.cpp b/test/testUriProvider.cpp index 38c222a..7418f51 100644 --- a/test/testUriProvider.cpp +++ b/test/testUriProvider.cpp @@ -38,6 +38,10 @@ namespace { etk::Vector out; return out; } + etk::Vector listRecursive(const etk::Uri& _uri) override { + etk::Vector out; + return out; + } }; class ProviderTest2 : public etk::uri::provider::Interface { public: @@ -52,6 +56,10 @@ namespace { etk::Vector out; return out; } + etk::Vector listRecursive(const etk::Uri& _uri) override { + etk::Vector out; + return out; + } }; } @@ -60,7 +68,7 @@ TEST(TestUriProvider, checkPlouf) { etk::uri::provider::clear(); s_plouf = 0; EXPECT_EQ(etk::uri::provider::exist(""), true); - EXPECT_EQ(etk::uri::provider::exist("RAW"), true); + EXPECT_EQ(etk::uri::provider::exist("FILE"), true); EXPECT_EQ(etk::uri::provider::exist("PLOUF_1"), false); EXPECT_EQ(etk::uri::provider::exist("PLOUF_2"), false); etk::uri::provider::add("PLOUF_1", ememory::makeShared<::ProviderTest1>()); @@ -202,7 +210,7 @@ TEST(TestUriProvider, checkZipAccess) { ememory::SharedPtr provider = etk::uri::provider::getProvider("DATA"); EXPECT_NE(provider, null); TEST_VERBOSE("List DATA path:"); - etk::Uri searchBase("DATA://"); + etk::Uri searchBase("DATA:///"); auto elems = provider->list(searchBase); for (auto& it: elems) { TEST_VERBOSE(" " << it);