[DEV] continue rework IO interface with abstract provider
This commit is contained in:
parent
26d5d87fd7
commit
68a391e7ad
1
data/data/.file_hidden.txt
Normal file
1
data/data/.file_hidden.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_hidden.txt
|
1
data/data/dir_A/file_A_1.txt
Normal file
1
data/data/dir_A/file_A_1.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_A_1.txt
|
1
data/data/dir_B/dir_C/file_C_1.txt
Normal file
1
data/data/dir_B/dir_C/file_C_1.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_C_1.txt
|
1
data/data/dir_B/file_B_1.txt
Normal file
1
data/data/dir_B/file_B_1.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_B_1.txt
|
1
data/data/dir_B/file_B_2.txt
Normal file
1
data/data/dir_B/file_B_2.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_B_2.txt
|
1
data/data/file_1.txt
Normal file
1
data/data/file_1.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_1.txt
|
1
data/data/file_2.txt
Normal file
1
data/data/file_2.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_2.txt
|
1
data/data/file_3.txt
Normal file
1
data/data/file_3.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
file_3.txt
|
BIN
data/data_sample.zip
Normal file
BIN
data/data_sample.zip
Normal file
Binary file not shown.
@ -97,7 +97,7 @@ void etest::init(int32_t _argc, const char** _argv) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nbTimeInit++;
|
nbTimeInit++;
|
||||||
elog::init(_argc, _argv);
|
elog::init(_argc, _argv, "etest");
|
||||||
//etk::initDefaultFolder("ewolApplNoName");
|
//etk::initDefaultFolder("ewolApplNoName");
|
||||||
ETEST_INFO("ETEST system init (BEGIN) ");
|
ETEST_INFO("ETEST system init (BEGIN) ");
|
||||||
for (int32_t iii=0; iii<_argc ; ++iii) {
|
for (int32_t iii=0; iii<_argc ; ++iii) {
|
||||||
|
@ -318,6 +318,10 @@ namespace etk {
|
|||||||
bool empty() const {
|
bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
|
/// @previous
|
||||||
|
bool isEmpty() const {
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Get a current element in the string
|
* @brief Get a current element in the string
|
||||||
* @param[in] _pos Desired position read
|
* @param[in] _pos Desired position read
|
||||||
|
@ -308,6 +308,10 @@ namespace etk {
|
|||||||
bool empty() const {
|
bool empty() const {
|
||||||
return size() == 0;
|
return size() == 0;
|
||||||
}
|
}
|
||||||
|
/// @previous
|
||||||
|
bool isEmpty() const {
|
||||||
|
return empty();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief Get a current element in the string
|
* @brief Get a current element in the string
|
||||||
* @param[in] _pos Desired position read
|
* @param[in] _pos Desired position read
|
||||||
|
@ -999,7 +999,7 @@ namespace etk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (swapped == false) {
|
if (swapped == false) {
|
||||||
break;
|
//break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,22 @@ ememory::SharedPtr<etk::Archive> etk::Archive::load(const etk::Path& _fileName)
|
|||||||
TK_ERROR("An error occured when load archive : " << _fileName);
|
TK_ERROR("An error occured when load archive : " << _fileName);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TK_ERROR("Extention not managed " << _fileName << " Sopported extention : .zip");
|
TK_ERROR("Extention not managed '" << _fileName << "' Supported extention : .zip");
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
ememory::SharedPtr<etk::Archive> etk::Archive::load(const etk::Uri& _uri) {
|
||||||
|
ememory::SharedPtr<etk::Archive> output;
|
||||||
|
etk::String extention = _uri.getPath().getExtention().toLower();
|
||||||
|
// select the corect Loader :
|
||||||
|
if( extention == "zip"
|
||||||
|
|| extention == ".apk") {
|
||||||
|
output = ememory::makeShared<etk::archive::Zip>(_uri);
|
||||||
|
if (output == null) {
|
||||||
|
TK_ERROR("An error occured when load archive : " << _uri);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
TK_ERROR("Extention not managed '" << _uri << "' Supported extention : .zip");
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
@ -138,4 +153,38 @@ void etk::Archive::close(const etk::Path& _key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
etk::Vector<etk::Path> etk::Archive::list(const etk::Path& _path) {
|
||||||
|
etk::Vector<etk::Path> out;
|
||||||
|
etk::String base = _path.getString();
|
||||||
|
for (auto& it: m_content) {
|
||||||
|
etk::String name = it.first.getString();
|
||||||
|
if (name.size() < base.size()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (etk::start_with(name, base) == true) {
|
||||||
|
// element or subElement...
|
||||||
|
if (it.first.getParent() == _path) {
|
||||||
|
out.pushBack(it.first);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
etk::String back = name.extract(base.size());
|
||||||
|
if ( back.size() == 0
|
||||||
|
|| back[0] != '/') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
back.erase(back.begin());
|
||||||
|
size_t pos = back.find('/');
|
||||||
|
if (pos == etk::String::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
etk::String value = back.extract(0, pos);
|
||||||
|
etk::Path tmpppp = etk::Path(base) / value;
|
||||||
|
if (etk::isIn(tmpppp, out) == false) {
|
||||||
|
out.pushBack(tmpppp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <ethread/Mutex.hpp>
|
#include <ethread/Mutex.hpp>
|
||||||
#include <ememory/memory.hpp>
|
#include <ememory/memory.hpp>
|
||||||
#include <etk/fs/Path.hpp>
|
#include <etk/fs/Path.hpp>
|
||||||
|
#include <etk/uri/Uri.hpp>
|
||||||
|
|
||||||
namespace etk {
|
namespace etk {
|
||||||
/**
|
/**
|
||||||
@ -174,12 +175,24 @@ namespace etk {
|
|||||||
* @return A pointer an the specified archive, the user might delete it.
|
* @return A pointer an the specified archive, the user might delete it.
|
||||||
*/
|
*/
|
||||||
static ememory::SharedPtr<Archive> load(const etk::Path& _fileName);
|
static ememory::SharedPtr<Archive> load(const etk::Path& _fileName);
|
||||||
|
/**
|
||||||
|
* @brief Load an Achive with a specific name.
|
||||||
|
* @param[in] _uri Localisation of the file.
|
||||||
|
* @return A pointer an the specified archive, the user might delete it.
|
||||||
|
*/
|
||||||
|
static ememory::SharedPtr<Archive> load(const etk::Uri& _uri);
|
||||||
/**
|
/**
|
||||||
* @brief Load an Achive with a specific name in package mode ==> this mean the data is associated with the basic binary.
|
* @brief Load an Achive with a specific name in package mode ==> this mean the data is associated with the basic binary.
|
||||||
* @param[in] _fileName File name of the specific archive.
|
* @param[in] _fileName File name of the specific archive.
|
||||||
* @return A pointer an the specified archive, the user might delete it.
|
* @return A pointer an the specified archive, the user might delete it.
|
||||||
*/
|
*/
|
||||||
static ememory::SharedPtr<Archive> loadPackage(const etk::Path& _fileName);
|
static ememory::SharedPtr<Archive> loadPackage(const etk::Path& _fileName);
|
||||||
|
/**
|
||||||
|
* @brief List the content of a specific path.
|
||||||
|
* @param[in] Path to parse.
|
||||||
|
* @return the full list of path in the _path.
|
||||||
|
*/
|
||||||
|
etk::Vector<etk::Path> list(const etk::Path& _path);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -52,6 +52,50 @@ etk::archive::Zip::Zip(const etk::Path& _fileName, uint64_t _offset) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: Support the correct URI... ==> do a structure in unzip to manage the read and write of data with a callback...
|
||||||
|
etk::archive::Zip::Zip(const etk::Uri& _uri) :
|
||||||
|
etk::Archive(_uri.getPath()),
|
||||||
|
m_ctx(null) {
|
||||||
|
if (_uri.getScheme() != "") {
|
||||||
|
TK_ERROR("Can not read and uri that is not with a scheme != of RAW, we have " << _uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Open the zip file */
|
||||||
|
m_ctx = unzOpenOffset(m_fileName.getNative().c_str(), 0);
|
||||||
|
if(!m_ctx) {
|
||||||
|
TK_ERROR("Unable to open the zip file '" << m_fileName << "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Get info about the zip file */
|
||||||
|
if(unzGetGlobalInfo(m_ctx, &m_info) != UNZ_OK) {
|
||||||
|
TK_ERROR("Unable to read the global info related to the '" << m_fileName << "' zip file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store all the file in the standard structure
|
||||||
|
for(uint32_t iii=0; iii<m_info.number_entry; iii++) {
|
||||||
|
char tmpFileName[FILENAME_MAX];
|
||||||
|
unz_file_info tmpFileInfo;
|
||||||
|
/* Get info about current file. */
|
||||||
|
if(unzGetCurrentFileInfo(m_ctx, &tmpFileInfo, tmpFileName, FILENAME_MAX, null, 0, null, 0) != UNZ_OK) {
|
||||||
|
TK_ERROR("Could not read file info from the zip file '" << m_fileName << "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(tmpFileName[strlen(tmpFileName) - 1] == '/' ) {
|
||||||
|
// find directory ...
|
||||||
|
} else {
|
||||||
|
TK_INFO("find file : " << tmpFileName);
|
||||||
|
m_content.set(etk::Path(tmpFileName), ememory::makeShared<etk::ArchiveContent>(tmpFileInfo.uncompressed_size));
|
||||||
|
}
|
||||||
|
/* Go the the next entry listed in the zip file. */
|
||||||
|
if((iii+1) < m_info.number_entry) {
|
||||||
|
if (unzGoToNextFile(m_ctx) != UNZ_OK) {
|
||||||
|
TK_ERROR("Could not read next file from the zip file '" << m_fileName << "'");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
etk::archive::Zip::~Zip() {
|
etk::archive::Zip::~Zip() {
|
||||||
if (m_ctx!= null) {
|
if (m_ctx!= null) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <etk/archive/Archive.hpp>
|
#include <etk/archive/Archive.hpp>
|
||||||
|
#include <etk/uri/Uri.hpp>
|
||||||
#ifdef ETK_BUILD_MINIZIP
|
#ifdef ETK_BUILD_MINIZIP
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <minizip/unzip.h>
|
#include <minizip/unzip.h>
|
||||||
@ -29,6 +30,11 @@
|
|||||||
* @param[in] _offset Offset in the file where to start the parsing of the "zip"
|
* @param[in] _offset Offset in the file where to start the parsing of the "zip"
|
||||||
*/
|
*/
|
||||||
Zip(const etk::Path& _fileName, uint64_t _offset = 0LL);
|
Zip(const etk::Path& _fileName, uint64_t _offset = 0LL);
|
||||||
|
/**
|
||||||
|
* @brief constructor of a zip file access
|
||||||
|
* @param[in] _uri URI of the file to parse (.zip / .apk)
|
||||||
|
*/
|
||||||
|
Zip(const etk::Uri& _uri);
|
||||||
/**
|
/**
|
||||||
* @brief basic destructor
|
* @brief basic destructor
|
||||||
*/
|
*/
|
||||||
|
14
etk/etk.cpp
14
etk/etk.cpp
@ -13,6 +13,8 @@
|
|||||||
#include <etk/typeInfo.hpp>
|
#include <etk/typeInfo.hpp>
|
||||||
#include <etk/Allocator.hpp>
|
#include <etk/Allocator.hpp>
|
||||||
#include <etk/theme/theme.hpp>
|
#include <etk/theme/theme.hpp>
|
||||||
|
#include <etk/fs/fileSystem.hpp>
|
||||||
|
#include <etk/uri/provider/provider.hpp>
|
||||||
|
|
||||||
static int32_t nbTimeInit = 0;
|
static int32_t nbTimeInit = 0;
|
||||||
|
|
||||||
@ -28,8 +30,9 @@ void etk::unInit() {
|
|||||||
nbTimeInit = 0;
|
nbTimeInit = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
etk::theme::unInit();
|
|
||||||
TK_INFO("ETK system un-init (BEGIN)");
|
TK_INFO("ETK system un-init (BEGIN)");
|
||||||
|
etk::theme::unInit();
|
||||||
|
etk::uri::provider::unInit();
|
||||||
ETK_MEM_SHOW_LOG();
|
ETK_MEM_SHOW_LOG();
|
||||||
TK_INFO("ETK system un-init (END)");
|
TK_INFO("ETK system un-init (END)");
|
||||||
}
|
}
|
||||||
@ -46,13 +49,8 @@ void etk::init(int _argc, const char** _argv) {
|
|||||||
} else {
|
} else {
|
||||||
TK_INFO("ETK system init (BEGIN) ");
|
TK_INFO("ETK system init (BEGIN) ");
|
||||||
}
|
}
|
||||||
elog::init(_argc, _argv);
|
elog::init(_argc, _argv, etk::fs::getBinaryName());
|
||||||
#if !defined(__TARGET_OS__Android) and !defined(__TARGET_OS__IOs)
|
etk::uri::provider::init();
|
||||||
// This action is done by the main wrapper...
|
|
||||||
if (_argc >= 1) {
|
|
||||||
etk::setArgZero(_argv[0]);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
etk::theme::init();
|
etk::theme::init();
|
||||||
for (int32_t iii=0; iii<_argc ; ++iii) {
|
for (int32_t iii=0; iii<_argc ; ++iii) {
|
||||||
etk::String data = _argv[iii];
|
etk::String data = _argv[iii];
|
||||||
|
@ -125,6 +125,14 @@ namespace etk {
|
|||||||
* @brief Clear data.
|
* @brief Clear data.
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
/**
|
||||||
|
* @brief Check if the path ahave data
|
||||||
|
* @return true The path is empty
|
||||||
|
* @return famse The path have some element
|
||||||
|
*/
|
||||||
|
bool isEmpty() const {
|
||||||
|
return m_data.isEmpty();
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
|
@ -407,14 +407,33 @@ etk::Path etk::fs::getBinaryPath() {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::Path etk::fs::getBinaryName() {
|
etk::String etk::fs::getBinaryName() {
|
||||||
return getBinaryPath().getFileName();
|
return getBinaryPath().getFileName();
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
etk::Path etk::fs::getDataPath() {
|
etk::Path etk::fs::getDataPath() {
|
||||||
|
#if defined(__TARGET_OS__Web)
|
||||||
|
return "zz_generic_zz";
|
||||||
|
#elif defined(__TARGET_OS__Android)
|
||||||
|
return "assets";
|
||||||
|
#elif defined(__TARGET_OS__Linux)
|
||||||
|
etk::Path dataPath = etk::Path("/usr/share") / getBinaryName();
|
||||||
|
etk::Path theoricInstalledName = etk::Path("/usr/bin") / getBinaryName();
|
||||||
|
TK_DEBUG(" position : '" << getBinaryPath() << "' installed position : '" << theoricInstalledName << "'");
|
||||||
|
if (getBinaryPath() != theoricInstalledName) {
|
||||||
|
dataPath = getBinaryPath().getParent() / ".." / "share" / getBinaryName();
|
||||||
|
}
|
||||||
|
return dataPath;
|
||||||
|
#elif defined(__TARGET_OS__Windows)
|
||||||
|
return getBinaryPath().getParent() / "data";
|
||||||
|
#elif defined(__TARGET_OS__MacOs)
|
||||||
|
return getBinaryPath().getParent() / ".." / "Resources" / getBinaryName();
|
||||||
|
#elif defined(__TARGET_OS__IOs)
|
||||||
|
return getBinaryPath().getParent() / "share" / getBinaryName();
|
||||||
|
#endif
|
||||||
|
return "NO_DATA_PATH";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
uint64_t etk::fs::getCreateTime(const etk::Path& _path) {
|
uint64_t etk::fs::getCreateTime(const etk::Path& _path) {
|
||||||
struct stat statProperty;
|
struct stat statProperty;
|
||||||
if (-1 == stat(_path.getNative().c_str(), &statProperty)) {
|
if (-1 == stat(_path.getNative().c_str(), &statProperty)) {
|
||||||
|
@ -212,19 +212,17 @@ namespace etk {
|
|||||||
* @brief Current binary name.
|
* @brief Current binary name.
|
||||||
* @return executable name.
|
* @return executable name.
|
||||||
*/
|
*/
|
||||||
etk::Path getBinaryName();
|
etk::String getBinaryName();
|
||||||
/**
|
/**
|
||||||
* @brief Full banary name (with root path).
|
* @brief Full banary name (with root path).
|
||||||
* @return the binary absolute path.
|
* @return the binary absolute path.
|
||||||
*/
|
*/
|
||||||
etk::Path getBinaryPath();
|
etk::Path getBinaryPath();
|
||||||
#if 0
|
/**
|
||||||
/**
|
* @brief Get the data path of the application.
|
||||||
* @brief Get the data path of the application.
|
* @return the root path of the data for this application.
|
||||||
* @return the root path of the data for this application.
|
*/
|
||||||
*/
|
etk::Path getDataPath();
|
||||||
etk::Path getDataPath();
|
|
||||||
#endif
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the creation time of the path.
|
* @brief Get the creation time of the path.
|
||||||
* @param[in] _path Path of the requested information.
|
* @param[in] _path Path of the requested information.
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
/** @file
|
|
||||||
* @author Edouard DUPIN
|
|
||||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
|
||||||
* @license MPL v2.0 (see license file)
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <etk/types.hpp>
|
|
||||||
#include <etk/fs/Type.hpp>
|
|
||||||
#include <etk/String.hpp>
|
|
||||||
#include <etk/Map.hpp>
|
|
||||||
#include <etk/uri/Query.hpp>
|
|
||||||
#include <etk/fs/Path.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace etk {
|
|
||||||
namespace uri {
|
|
||||||
class IoProviderInterface : public ememory::EnableSharedFromThis<IoProvider> {
|
|
||||||
public:
|
|
||||||
|
|
||||||
};
|
|
||||||
void addProvider(const etk::String& _scheme, ememory::SharedPtr<IoProviderInterface> _interface);
|
|
||||||
void removeProvider(const etk::String& _scheme);
|
|
||||||
ememory::SharedPtr<etk::io::Interface> provideIO(const etk::uri::Uri& _uri);
|
|
||||||
}
|
|
||||||
}
|
|
@ -147,4 +147,20 @@ etk::Stream& etk::operator <<(etk::Stream& _os, const etk::uri::Query& _obj) {
|
|||||||
|
|
||||||
bool etk::uri::Query::isEmpty() const {
|
bool etk::uri::Query::isEmpty() const {
|
||||||
return m_data.size() == 0;
|
return m_data.size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool etk::uri::Query::operator== (const etk::uri::Query& _obj) const {
|
||||||
|
return getEncoded() == _obj.getEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::uri::Query::operator!= (const etk::uri::Query& _obj) const {
|
||||||
|
return getEncoded() != _obj.getEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::uri::Query::operator< (const etk::uri::Query& _obj) const {
|
||||||
|
return getEncoded() < _obj.getEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::uri::Query::operator> (const etk::uri::Query& _obj) const {
|
||||||
|
return getEncoded() > _obj.getEncoded();
|
||||||
|
}
|
||||||
|
@ -78,6 +78,30 @@ namespace etk {
|
|||||||
* @return true The querry have no data. false Otherwise
|
* @return true The querry have no data. false Otherwise
|
||||||
*/
|
*/
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
|
/**
|
||||||
|
* @brief Check if the 2 Query are identical.
|
||||||
|
* @param[in] _obj Query to compare.
|
||||||
|
* @return true : same Query, false otherwise.
|
||||||
|
*/
|
||||||
|
bool operator== (const etk::uri::Query& _obj) const;
|
||||||
|
/**
|
||||||
|
* @brief Check if the 2 Query are different.
|
||||||
|
* @param[in] _obj Query to compare.
|
||||||
|
* @return false : same query, true otherwise.
|
||||||
|
*/
|
||||||
|
bool operator!= (const etk::uri::Query& _obj) const;
|
||||||
|
/**
|
||||||
|
* @brief check if this elemnt is greater than the other.
|
||||||
|
* @param[in] _obj Query to compare.
|
||||||
|
* @return true : less Query, false otherwise.
|
||||||
|
*/
|
||||||
|
bool operator< (const etk::uri::Query& _obj) const;
|
||||||
|
/**
|
||||||
|
* @brief Check if this elemnt is greater than the other.
|
||||||
|
* @param[in] _obj Query to compare.
|
||||||
|
* @return false : Greater Query, true otherwise.
|
||||||
|
*/
|
||||||
|
bool operator> (const etk::uri::Query& _obj) const;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
//! @not_in_doc
|
//! @not_in_doc
|
||||||
|
@ -15,10 +15,19 @@ etk::Uri::Uri(const etk::String& _value) {
|
|||||||
set(_value);
|
set(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etk::Uri::Uri(const etk::Path& _value) {
|
||||||
|
m_path = _value;
|
||||||
|
}
|
||||||
|
|
||||||
etk::Uri::Uri(const char * _value) {
|
etk::Uri::Uri(const char * _value) {
|
||||||
set(_value);
|
set(_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
etk::Stream& etk::operator <<(etk::Stream& _os, const etk::Uri& _obj) {
|
||||||
|
_os << _obj.get();
|
||||||
|
return _os;
|
||||||
|
}
|
||||||
|
|
||||||
void etk::Uri::set(const char * _value) {
|
void etk::Uri::set(const char * _value) {
|
||||||
set(etk::String(_value));
|
set(etk::String(_value));
|
||||||
}
|
}
|
||||||
@ -34,6 +43,58 @@ void etk::Uri::clear() {
|
|||||||
m_fragment.clear();
|
m_fragment.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool etk::Uri::isEmpty() const {
|
||||||
|
return m_scheme.isEmpty() == true
|
||||||
|
&& m_user.isEmpty() == true
|
||||||
|
&& m_password.isEmpty() == true
|
||||||
|
&& m_server.isEmpty() == true
|
||||||
|
&& m_port == 0
|
||||||
|
&& m_path.isEmpty() == true
|
||||||
|
&& m_query.isEmpty() == true
|
||||||
|
&& m_fragment.isEmpty() == true;
|
||||||
|
}
|
||||||
|
bool etk::Uri::operator== (const etk::Uri& _obj) const {
|
||||||
|
return m_scheme == _obj.m_scheme
|
||||||
|
&& m_user == _obj.m_user
|
||||||
|
&& m_password == _obj.m_password
|
||||||
|
&& m_server == _obj.m_server
|
||||||
|
&& m_port == _obj.m_port
|
||||||
|
&& m_path == _obj.m_path
|
||||||
|
&& m_query == _obj.m_query
|
||||||
|
&& m_fragment == _obj.m_fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::Uri::operator!= (const etk::Uri& _obj) const {
|
||||||
|
return m_scheme != _obj.m_scheme
|
||||||
|
|| m_user != _obj.m_user
|
||||||
|
|| m_password != _obj.m_password
|
||||||
|
|| m_server != _obj.m_server
|
||||||
|
|| m_port != _obj.m_port
|
||||||
|
|| m_path != _obj.m_path
|
||||||
|
|| m_query != _obj.m_query
|
||||||
|
|| m_fragment != _obj.m_fragment;
|
||||||
|
}
|
||||||
|
bool etk::Uri::operator< (const etk::Uri& _obj) const {
|
||||||
|
return m_scheme < _obj.m_scheme
|
||||||
|
&& m_user < _obj.m_user
|
||||||
|
&& m_password < _obj.m_password
|
||||||
|
&& m_server < _obj.m_server
|
||||||
|
&& m_port < _obj.m_port
|
||||||
|
&& m_path < _obj.m_path
|
||||||
|
&& m_query < _obj.m_query
|
||||||
|
&& m_fragment < _obj.m_fragment;
|
||||||
|
}
|
||||||
|
bool etk::Uri::operator> (const etk::Uri& _obj) const {
|
||||||
|
return m_scheme > _obj.m_scheme
|
||||||
|
&& m_user > _obj.m_user
|
||||||
|
&& m_password > _obj.m_password
|
||||||
|
&& m_server > _obj.m_server
|
||||||
|
&& m_port > _obj.m_port
|
||||||
|
&& m_path > _obj.m_path
|
||||||
|
&& m_query > _obj.m_query
|
||||||
|
&& m_fragment > _obj.m_fragment;
|
||||||
|
}
|
||||||
|
|
||||||
void etk::Uri::set(etk::String _value) {
|
void etk::Uri::set(etk::String _value) {
|
||||||
TK_VERBOSE("parse: '" << _value << "'");
|
TK_VERBOSE("parse: '" << _value << "'");
|
||||||
size_t pos = _value.find("://");
|
size_t pos = _value.find("://");
|
||||||
@ -92,7 +153,7 @@ void etk::Uri::set(etk::String _value) {
|
|||||||
TK_VERBOSE("find server / port : '" << m_server << "' / '" << m_port << "'");
|
TK_VERBOSE("find server / port : '" << m_server << "' / '" << m_port << "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
etk::String etk::Uri::get() {
|
etk::String etk::Uri::get() const {
|
||||||
etk::String out;
|
etk::String out;
|
||||||
if (m_scheme != "") {
|
if (m_scheme != "") {
|
||||||
out += m_scheme;
|
out += m_scheme;
|
||||||
|
@ -39,6 +39,11 @@ namespace etk {
|
|||||||
* @param[in] _value Element basic URI
|
* @param[in] _value Element basic URI
|
||||||
*/
|
*/
|
||||||
Uri(const etk::String& _value);
|
Uri(const etk::String& _value);
|
||||||
|
/**
|
||||||
|
* @brief Contructor with basic URI with a generic path.
|
||||||
|
* @param[in] _value generic path
|
||||||
|
*/
|
||||||
|
Uri(const etk::Path& _value);
|
||||||
/**
|
/**
|
||||||
* @brief Contructor with basic URI.
|
* @brief Contructor with basic URI.
|
||||||
* @param[in] _value Element basic URI
|
* @param[in] _value Element basic URI
|
||||||
@ -58,7 +63,7 @@ namespace etk {
|
|||||||
* @brief generate the URI string.
|
* @brief generate the URI string.
|
||||||
* @return the uri correctly encoded
|
* @return the uri correctly encoded
|
||||||
*/
|
*/
|
||||||
etk::String get();
|
etk::String get() const;
|
||||||
/**
|
/**
|
||||||
* @brief Get the scheme of the URI.
|
* @brief Get the scheme of the URI.
|
||||||
* @return Scheme value.
|
* @return Scheme value.
|
||||||
@ -143,6 +148,38 @@ namespace etk {
|
|||||||
* @brief Clear the structure.
|
* @brief Clear the structure.
|
||||||
*/
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
/**
|
||||||
|
* @brief Check if the uri ahave data
|
||||||
|
* @return true The uri is empty
|
||||||
|
* @return famse The uri have some element
|
||||||
|
*/
|
||||||
|
bool isEmpty() const;
|
||||||
|
/**
|
||||||
|
* @brief Check if the 2 Uri are identical.
|
||||||
|
* @param[in] _obj Uri to compare.
|
||||||
|
* @return true : same Uri, false otherwise.
|
||||||
|
*/
|
||||||
|
bool operator== (const etk::Uri& _obj) const;
|
||||||
|
/**
|
||||||
|
* @brief Check if the 2 Uri are different.
|
||||||
|
* @param[in] _obj Uri to compare.
|
||||||
|
* @return false : same Uri, true otherwise.
|
||||||
|
*/
|
||||||
|
bool operator!= (const etk::Uri& _obj) const;
|
||||||
|
/**
|
||||||
|
* @brief check if this elemnt is greater than the other.
|
||||||
|
* @param[in] _obj Uri to compare.
|
||||||
|
* @return true : less Uri, false otherwise.
|
||||||
|
*/
|
||||||
|
bool operator< (const etk::Uri& _obj) const;
|
||||||
|
/**
|
||||||
|
* @brief Check if this elemnt is greater than the other.
|
||||||
|
* @param[in] _obj Uri to compare.
|
||||||
|
* @return false : Greater Uri, true otherwise.
|
||||||
|
*/
|
||||||
|
bool operator> (const etk::Uri& _obj) const;
|
||||||
};
|
};
|
||||||
|
//! @not_in_doc
|
||||||
|
etk::Stream& operator <<(etk::Stream& _os, const etk::Uri& _obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
etk/uri/provider/Interface.hpp
Normal file
31
etk/uri/provider/Interface.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/uri/Uri.hpp>
|
||||||
|
#include <etk/io/Interface.hpp>
|
||||||
|
#include <ememory/SharedPtr.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace etk {
|
||||||
|
namespace uri {
|
||||||
|
namespace provider {
|
||||||
|
class Interface : public ememory::EnableSharedFromThis<Interface> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Virtualize detructor:
|
||||||
|
*/
|
||||||
|
virtual ~Interface() = default;
|
||||||
|
public:
|
||||||
|
virtual ememory::SharedPtr<etk::io::Interface> create(const etk::Uri& _uri) = 0;
|
||||||
|
virtual bool exist(const etk::Uri& _uri) = 0;
|
||||||
|
virtual etk::Vector<etk::Uri> list(const etk::Uri& _uri) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
55
etk/uri/provider/ProviderFile.cpp
Normal file
55
etk/uri/provider/ProviderFile.cpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#include <etk/uri/provider/ProviderFile.hpp>
|
||||||
|
#include <etk/io/File.hpp>
|
||||||
|
#include <etk/fs/fileSystem.hpp>
|
||||||
|
#include <etk/debug.hpp>
|
||||||
|
|
||||||
|
etk::uri::provider::ProviderFile::ProviderFile() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::uri::provider::ProviderFile::ProviderFile(const etk::Path& _offset) :
|
||||||
|
m_offset(_offset) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ememory::SharedPtr<etk::io::Interface> etk::uri::provider::ProviderFile::create(const etk::Uri& _uri) {
|
||||||
|
if (m_offset.isEmpty() == true) {
|
||||||
|
return ememory::makeShared<etk::io::File>(_uri.getPath());
|
||||||
|
}
|
||||||
|
return ememory::makeShared<etk::io::File>(m_offset / _uri.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::uri::provider::ProviderFile::exist(const etk::Uri& _uri) {
|
||||||
|
if (m_offset.isEmpty() == true) {
|
||||||
|
return etk::fs::exist(_uri.getPath());
|
||||||
|
}
|
||||||
|
return etk::fs::exist(m_offset / _uri.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Vector<etk::Uri> etk::uri::provider::ProviderFile::list(const etk::Uri& _uri) {
|
||||||
|
etk::Vector<etk::Path> tmp;
|
||||||
|
etk::Vector<etk::Uri> out;
|
||||||
|
if (m_offset.isEmpty() == true) {
|
||||||
|
tmp = etk::fs::list(_uri.getPath());
|
||||||
|
for (auto& elem: tmp) {
|
||||||
|
etk::Uri newUri = _uri;
|
||||||
|
newUri.setPath(elem);
|
||||||
|
out.pushBack(newUri);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
TK_ERROR("list path: " << m_offset / _uri.getPath());
|
||||||
|
tmp = etk::fs::list(m_offset / _uri.getPath());
|
||||||
|
int32_t offset = m_offset.getString().size()+1;
|
||||||
|
for (auto& elem: tmp) {
|
||||||
|
etk::Uri newUri = _uri;
|
||||||
|
newUri.setPath(elem.getString().extract(offset));
|
||||||
|
out.pushBack(newUri);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
27
etk/uri/provider/ProviderFile.hpp
Normal file
27
etk/uri/provider/ProviderFile.hpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/uri/provider/provider.hpp>
|
||||||
|
|
||||||
|
namespace etk {
|
||||||
|
namespace uri {
|
||||||
|
namespace provider {
|
||||||
|
class ProviderFile : public etk::uri::provider::Interface {
|
||||||
|
protected:
|
||||||
|
etk::Path m_offset;
|
||||||
|
public:
|
||||||
|
ProviderFile();
|
||||||
|
ProviderFile(const etk::Path& _offset);
|
||||||
|
public:
|
||||||
|
ememory::SharedPtr<etk::io::Interface> create(const etk::Uri& _uri) override;
|
||||||
|
bool exist(const etk::Uri& _uri) override;
|
||||||
|
etk::Vector<etk::Uri> list(const etk::Uri& _uri) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
62
etk/uri/provider/ProviderFileZip.cpp
Normal file
62
etk/uri/provider/ProviderFileZip.cpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#include <etk/uri/provider/ProviderFileZip.hpp>
|
||||||
|
#include <etk/debug.hpp>
|
||||||
|
#include <etk/io/ZipFile.hpp>
|
||||||
|
|
||||||
|
void etk::uri::provider::ProviderFileZip::loadZipFile(const etk::Uri& _zipFile) {
|
||||||
|
m_archive = etk::Archive::load(_zipFile);
|
||||||
|
TK_ASSERT(m_archive != null, "Error loading APK ... '" << _zipFile << "'");
|
||||||
|
#ifdef DEBUG
|
||||||
|
//Just for debug, print APK contents
|
||||||
|
m_archive->display();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::uri::provider::ProviderFileZip::ProviderFileZip(const etk::Uri& _zipFile) {
|
||||||
|
loadZipFile(_zipFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::uri::provider::ProviderFileZip::ProviderFileZip(const etk::Uri& _zipFile, const etk::Path& _offset) :
|
||||||
|
m_offset(_offset) {
|
||||||
|
loadZipFile(_zipFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
ememory::SharedPtr<etk::io::Interface> etk::uri::provider::ProviderFileZip::create(const etk::Uri& _uri) {
|
||||||
|
if (m_offset.isEmpty() == true) {
|
||||||
|
return ememory::makeShared<etk::io::ZipFile>(_uri.getPath(), m_archive);
|
||||||
|
}
|
||||||
|
return ememory::makeShared<etk::io::ZipFile>(m_offset / _uri.getPath(), m_archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::uri::provider::ProviderFileZip::exist(const etk::Uri& _uri) {
|
||||||
|
if (m_offset.isEmpty() == true) {
|
||||||
|
return m_archive->exist(_uri.getPath());
|
||||||
|
}
|
||||||
|
return m_archive->exist(m_offset / _uri.getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Vector<etk::Uri> etk::uri::provider::ProviderFileZip::list(const etk::Uri& _uri) {
|
||||||
|
etk::Vector<etk::Path> tmp;
|
||||||
|
etk::Vector<etk::Uri> out;
|
||||||
|
if (m_offset.isEmpty() == true) {
|
||||||
|
tmp = m_archive->list(_uri.getPath());
|
||||||
|
for (auto& elem: tmp) {
|
||||||
|
etk::Uri newUri = _uri;
|
||||||
|
newUri.setPath(elem);
|
||||||
|
out.pushBack(newUri);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
tmp = m_archive->list(m_offset / _uri.getPath());
|
||||||
|
int32_t offset = m_offset.getString().size()+1;
|
||||||
|
for (auto& elem: tmp) {
|
||||||
|
etk::Uri newUri = _uri;
|
||||||
|
newUri.setPath(elem.getString().extract(offset));
|
||||||
|
out.pushBack(newUri);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
32
etk/uri/provider/ProviderFileZip.hpp
Normal file
32
etk/uri/provider/ProviderFileZip.hpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/uri/provider/provider.hpp>
|
||||||
|
#include <etk/archive/Archive.hpp>
|
||||||
|
#include <ememory/SharedPtr.hpp>
|
||||||
|
|
||||||
|
namespace etk {
|
||||||
|
namespace uri {
|
||||||
|
namespace provider {
|
||||||
|
class ProviderFileZip : public etk::uri::provider::Interface {
|
||||||
|
protected:
|
||||||
|
ememory::SharedPtr<etk::Archive> m_archive;
|
||||||
|
etk::Path m_offset;
|
||||||
|
void loadZipFile(const etk::Uri& _zipFile);
|
||||||
|
public:
|
||||||
|
ProviderFileZip(const etk::Uri& _zipFile);
|
||||||
|
ProviderFileZip(const etk::Uri& _zipFile, const etk::Path& _offset);
|
||||||
|
public:
|
||||||
|
ememory::SharedPtr<etk::io::Interface> create(const etk::Uri& _uri) override;
|
||||||
|
bool exist(const etk::Uri& _uri) override;
|
||||||
|
etk::Vector<etk::Uri> list(const etk::Uri& _uri) override;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
etk/uri/provider/provider.cpp
Normal file
68
etk/uri/provider/provider.cpp
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#include <etk/uri/provider/provider.hpp>
|
||||||
|
#include <etk/uri/provider/ProviderFile.hpp>
|
||||||
|
#include <etk/Map.hpp>
|
||||||
|
#include <etk/io/File.hpp>
|
||||||
|
|
||||||
|
static etk::Map<etk::String, ememory::SharedPtr<etk::uri::provider::Interface>>& getProviders() {
|
||||||
|
static etk::Map<etk::String, ememory::SharedPtr<etk::uri::provider::Interface>> g_data;
|
||||||
|
return g_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void etk::uri::provider::add(const etk::String& _scheme, ememory::SharedPtr<etk::uri::provider::Interface> _interface) {
|
||||||
|
etk::String scheme = _scheme;
|
||||||
|
if (scheme.empty() == true) {
|
||||||
|
scheme = "RAW";
|
||||||
|
}
|
||||||
|
getProviders().set(scheme, _interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void etk::uri::provider::clear() {
|
||||||
|
getProviders().clear();
|
||||||
|
etk::uri::provider::add("", ememory::makeShared<etk::uri::provider::ProviderFile>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void etk::uri::provider::remove(const etk::String& _scheme) {
|
||||||
|
getProviders().erase(_scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool etk::uri::provider::exist(const etk::String& _scheme) {
|
||||||
|
etk::String scheme = _scheme;
|
||||||
|
if (scheme.empty() == true) {
|
||||||
|
scheme = "RAW";
|
||||||
|
}
|
||||||
|
return getProviders().exist(scheme);
|
||||||
|
}
|
||||||
|
|
||||||
|
ememory::SharedPtr<etk::io::Interface> etk::uri::provider::get(const etk::Uri& _uri) {
|
||||||
|
etk::String scheme = _uri.getScheme();
|
||||||
|
if (scheme.empty() == true) {
|
||||||
|
scheme = "RAW";
|
||||||
|
}
|
||||||
|
if (getProviders().exist(scheme) == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getProviders()[scheme]->create(_uri);
|
||||||
|
}
|
||||||
|
ememory::SharedPtr<etk::uri::provider::Interface> etk::uri::provider::getProvider(const etk::String& _scheme) {
|
||||||
|
etk::String scheme = _scheme;
|
||||||
|
if (scheme.empty() == true) {
|
||||||
|
scheme = "RAW";
|
||||||
|
}
|
||||||
|
if (getProviders().exist(scheme) == false) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getProviders()[scheme];
|
||||||
|
}
|
||||||
|
|
||||||
|
void etk::uri::provider::init() {
|
||||||
|
etk::uri::provider::clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void etk::uri::provider::unInit() {
|
||||||
|
getProviders().clear();
|
||||||
|
}
|
65
etk/uri/provider/provider.hpp
Normal file
65
etk/uri/provider/provider.hpp
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <etk/fs/Type.hpp>
|
||||||
|
#include <etk/String.hpp>
|
||||||
|
#include <etk/Map.hpp>
|
||||||
|
#include <etk/uri/Query.hpp>
|
||||||
|
#include <etk/fs/Path.hpp>
|
||||||
|
#include <etk/io/Interface.hpp>
|
||||||
|
#include <etk/uri/provider/Interface.hpp>
|
||||||
|
#include <ememory/SharedPtr.hpp>
|
||||||
|
#include <ememory/memory.hpp>
|
||||||
|
|
||||||
|
namespace etk {
|
||||||
|
namespace uri {
|
||||||
|
namespace provider {
|
||||||
|
/**
|
||||||
|
* @brief Add a IO interface provider ==> permit to have simple whangable backend interface.
|
||||||
|
* @param[in] _scheme URI scheme specific interface (like 'http' for 'http://' or 'RAW' for no scheme or "data" for 'data://')
|
||||||
|
* @param[in] _interface Provider interface
|
||||||
|
*/
|
||||||
|
void add(const etk::String& _scheme, ememory::SharedPtr<etk::uri::provider::Interface> _interface);
|
||||||
|
/**
|
||||||
|
* @brief Add a IO interface provider ==> permit to have simple whangable backend interface.
|
||||||
|
* @param[in] _scheme URI scheme specific interface
|
||||||
|
*/
|
||||||
|
void remove(const etk::String& _scheme);
|
||||||
|
/**
|
||||||
|
* @brief Check if a provider exist.
|
||||||
|
* @param[in] _scheme URI scheme specific interface
|
||||||
|
* @return true The provider is availlable
|
||||||
|
*/
|
||||||
|
bool exist(const etk::String& _scheme);
|
||||||
|
/**
|
||||||
|
* @brief Clear all providers
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
/**
|
||||||
|
* @brief Get an IO interface with a specific URI
|
||||||
|
* @param[in] _uri Data interface requested
|
||||||
|
* @return The interface requested.
|
||||||
|
*/
|
||||||
|
ememory::SharedPtr<etk::io::Interface> get(const etk::Uri& _uri);
|
||||||
|
/**
|
||||||
|
* @brief Get an URI provider
|
||||||
|
* @param[in] _scheme type of provider
|
||||||
|
* @return The interface requested.
|
||||||
|
*/
|
||||||
|
ememory::SharedPtr<etk::uri::provider::Interface> getProvider(const etk::String& _scheme);
|
||||||
|
/**
|
||||||
|
* @brief Initialize uri provider
|
||||||
|
*/
|
||||||
|
void init();
|
||||||
|
/**
|
||||||
|
* @brief Un-Initialize uri provider
|
||||||
|
*/
|
||||||
|
void unInit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -33,6 +33,7 @@ def configure(target, my_module):
|
|||||||
'test/testTheme.cpp',
|
'test/testTheme.cpp',
|
||||||
'test/testUri.cpp',
|
'test/testUri.cpp',
|
||||||
'test/testQuery.cpp',
|
'test/testQuery.cpp',
|
||||||
|
'test/testUriProvider.cpp',
|
||||||
])
|
])
|
||||||
"""
|
"""
|
||||||
'test/ConstructDestruct.cpp',
|
'test/ConstructDestruct.cpp',
|
||||||
@ -63,5 +64,9 @@ def configure(target, my_module):
|
|||||||
'test-debug'
|
'test-debug'
|
||||||
])
|
])
|
||||||
my_module.copy_path('data/*')
|
my_module.copy_path('data/*')
|
||||||
|
my_module.copy_path('data/data/*', 'data')
|
||||||
|
my_module.copy_path('data/data/dir_A/*', 'data/dir_A')
|
||||||
|
my_module.copy_path('data/data/dir_B/*', 'data/dir_B')
|
||||||
|
my_module.copy_path('data/data/dir_B/dir_C/*', 'data/dir_B/dir_C')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -59,6 +59,9 @@ def configure(target, my_module):
|
|||||||
'etk/archive/Zip.cpp',
|
'etk/archive/Zip.cpp',
|
||||||
'etk/uri/Uri.cpp',
|
'etk/uri/Uri.cpp',
|
||||||
'etk/uri/Query.cpp',
|
'etk/uri/Query.cpp',
|
||||||
|
'etk/uri/provider/provider.cpp',
|
||||||
|
'etk/uri/provider/ProviderFile.cpp',
|
||||||
|
'etk/uri/provider/ProviderFileZip.cpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
my_module.add_header_file([
|
my_module.add_header_file([
|
||||||
@ -96,6 +99,10 @@ def configure(target, my_module):
|
|||||||
'etk/FlatTree.hpp',
|
'etk/FlatTree.hpp',
|
||||||
'etk/uri/Uri.hpp',
|
'etk/uri/Uri.hpp',
|
||||||
'etk/uri/Query.hpp',
|
'etk/uri/Query.hpp',
|
||||||
|
'etk/uri/provider/provider.hpp',
|
||||||
|
'etk/uri/provider/Interface.hpp',
|
||||||
|
'etk/uri/provider/ProviderFile.hpp',
|
||||||
|
'etk/uri/provider/ProviderFileZip.hpp',
|
||||||
])
|
])
|
||||||
|
|
||||||
# build in C++ mode
|
# build in C++ mode
|
||||||
@ -112,7 +119,7 @@ def configure(target, my_module):
|
|||||||
my_module.add_depend(['cxx'])
|
my_module.add_depend(['cxx'])
|
||||||
|
|
||||||
# add some optionnal libraries
|
# add some optionnal libraries
|
||||||
my_module.add_optionnal_depend('minizip', ["c++", "-DETK_BUILD_MINIZIP"])
|
my_module.add_optionnal_depend('minizip', ["c++", "-DETK_BUILD_MINIZIP"], export=True)
|
||||||
my_module.add_optionnal_depend('linearmath', ["c", "-DETK_BUILD_LINEARMATH"], export=True)
|
my_module.add_optionnal_depend('linearmath', ["c", "-DETK_BUILD_LINEARMATH"], export=True)
|
||||||
|
|
||||||
if "Android" in target.get_type():
|
if "Android" in target.get_type():
|
||||||
|
@ -17,7 +17,11 @@
|
|||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
// init test engine:
|
// init test engine:
|
||||||
|
etk::init(argc, argv);
|
||||||
etest::init(argc, argv);
|
etest::init(argc, argv);
|
||||||
TEST_INFO("TEST ETK");
|
TEST_INFO("TEST ETK");
|
||||||
return RUN_ALL_TESTS();
|
int out = RUN_ALL_TESTS();
|
||||||
|
etest::unInit();
|
||||||
|
etk::unInit();
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,20 @@ TEST(TestUri, base_9) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(TestUri, base_10) {
|
TEST(TestUri, base_10) {
|
||||||
|
etk::String value = "__SCHEME__:////__PATH__?__QUERY__";
|
||||||
|
etk::Uri uri(value);
|
||||||
|
EXPECT_EQ(uri.get(), value);
|
||||||
|
EXPECT_EQ(uri.getScheme(), "__SCHEME__");
|
||||||
|
EXPECT_EQ(uri.getUser(), "");
|
||||||
|
EXPECT_EQ(uri.getPassword(), "");
|
||||||
|
EXPECT_EQ(uri.getServer(), "");
|
||||||
|
EXPECT_EQ(uri.getPort(), 0);
|
||||||
|
EXPECT_EQ(uri.getPath(), etk::Path("/__PATH__"));
|
||||||
|
EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__");
|
||||||
|
EXPECT_EQ(uri.getFragment(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestUri, base_10_2) {
|
||||||
etk::String value = "__SCHEME__:///__PATH__?__QUERY__";
|
etk::String value = "__SCHEME__:///__PATH__?__QUERY__";
|
||||||
etk::Uri uri(value);
|
etk::Uri uri(value);
|
||||||
EXPECT_EQ(uri.get(), value);
|
EXPECT_EQ(uri.get(), value);
|
||||||
@ -163,3 +177,35 @@ TEST(TestUri, base_10) {
|
|||||||
EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__");
|
EXPECT_EQ(uri.getQuery().getEncoded(), "__QUERY__");
|
||||||
EXPECT_EQ(uri.getFragment(), "");
|
EXPECT_EQ(uri.getFragment(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(TestUri, base_11_1) {
|
||||||
|
etk::String value = "//hello/txt";
|
||||||
|
etk::Path valuePath = "/hello/txt";
|
||||||
|
etk::Uri uri(valuePath);
|
||||||
|
EXPECT_EQ(uri.get(), value);
|
||||||
|
EXPECT_EQ(uri.getScheme(), "");
|
||||||
|
EXPECT_EQ(uri.getUser(), "");
|
||||||
|
EXPECT_EQ(uri.getPassword(), "");
|
||||||
|
EXPECT_EQ(uri.getServer(), "");
|
||||||
|
EXPECT_EQ(uri.getPort(), 0);
|
||||||
|
EXPECT_EQ(uri.getPath(), valuePath);
|
||||||
|
EXPECT_EQ(uri.getQuery().getEncoded(), "");
|
||||||
|
EXPECT_EQ(uri.getFragment(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestUri, base_11_2) {
|
||||||
|
etk::String value = "/hello/txt";
|
||||||
|
etk::Path valuePath = "hello/txt";
|
||||||
|
etk::Uri uri(valuePath);
|
||||||
|
EXPECT_EQ(uri.get(), value);
|
||||||
|
EXPECT_EQ(uri.getScheme(), "");
|
||||||
|
EXPECT_EQ(uri.getUser(), "");
|
||||||
|
EXPECT_EQ(uri.getPassword(), "");
|
||||||
|
EXPECT_EQ(uri.getServer(), "");
|
||||||
|
EXPECT_EQ(uri.getPort(), 0);
|
||||||
|
EXPECT_EQ(uri.getPath(), valuePath);
|
||||||
|
EXPECT_EQ(uri.getQuery().getEncoded(), "");
|
||||||
|
EXPECT_EQ(uri.getFragment(), "");
|
||||||
|
}
|
||||||
|
// "audio://alsa/front?mode=I16"
|
||||||
|
|
||||||
|
238
test/testUriProvider.cpp
Normal file
238
test/testUriProvider.cpp
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/**
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
*
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
*
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <etest/etest.hpp>
|
||||||
|
#include <test-debug/debug.hpp>
|
||||||
|
#include <etk/uri/Uri.hpp>
|
||||||
|
#include <etk/uri/provider/provider.hpp>
|
||||||
|
#include <etk/uri/provider/ProviderFile.hpp>
|
||||||
|
#include <etk/uri/provider/ProviderFileZip.hpp>
|
||||||
|
#include <etk/fs/fileSystem.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST(TestUriProvider, defaultContructor) {
|
||||||
|
etk::uri::provider::clear();
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist(""), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t s_plouf = 0;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class ProviderTest1 : public etk::uri::provider::Interface {
|
||||||
|
public:
|
||||||
|
ememory::SharedPtr<etk::io::Interface> create(const etk::Uri& _uri) override {
|
||||||
|
s_plouf = 5555;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
bool exist(const etk::Uri& _uri) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
etk::Vector<etk::Uri> list(const etk::Uri& _uri) override {
|
||||||
|
etk::Vector<etk::Uri> out;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class ProviderTest2 : public etk::uri::provider::Interface {
|
||||||
|
public:
|
||||||
|
ememory::SharedPtr<etk::io::Interface> create(const etk::Uri& _uri) override {
|
||||||
|
s_plouf = 9999;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
bool exist(const etk::Uri& _uri) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
etk::Vector<etk::Uri> list(const etk::Uri& _uri) override {
|
||||||
|
etk::Vector<etk::Uri> out;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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("PLOUF_1"), false);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_2"), false);
|
||||||
|
etk::uri::provider::add("PLOUF_1", ememory::makeShared<::ProviderTest1>());
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist(""), true);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_1"), true);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_2"), false);
|
||||||
|
etk::uri::provider::add("PLOUF_2", ememory::makeShared<::ProviderTest2>());
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist(""), true);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_1"), true);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_2"), true);
|
||||||
|
EXPECT_EQ(s_plouf, 0);
|
||||||
|
etk::uri::provider::get("PLOUF_1:///qsdfqsdfqsdfqsdf.txt");
|
||||||
|
EXPECT_EQ(s_plouf, 5555);
|
||||||
|
etk::uri::provider::get("PLOUF_2:///qsdfqsdfqsdfqsdf.txt");
|
||||||
|
EXPECT_EQ(s_plouf, 9999);
|
||||||
|
etk::uri::provider::remove("PLOUF_1");
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist(""), true);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_1"), false);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_2"), true);
|
||||||
|
etk::uri::provider::remove("PLOUF_2");
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist(""), true);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_1"), false);
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("PLOUF_2"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Vector<etk::Uri> listDirect = {
|
||||||
|
"DATA:///filePresent.txt",
|
||||||
|
"DATA:///fileEmpty.txt",
|
||||||
|
"DATA:///data",
|
||||||
|
"DATA:///data_sample.zip",
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This function takes last element as pivot, places
|
||||||
|
the pivot element at its correct position in sorted
|
||||||
|
array, and places all smaller (smaller than pivot)
|
||||||
|
to left of pivot and all greater elements to right
|
||||||
|
of pivot */
|
||||||
|
int_t partition (etk::Vector<etk::Uri>& _data, int _low, int _high) {
|
||||||
|
int_t iii = (_low - 1); // Index of smaller element
|
||||||
|
for (int_t jjj = _low; jjj < _high; ++jjj) {
|
||||||
|
// If current element is smaller than or equal to pivot
|
||||||
|
if (_data[jjj] < _data[_high]) {
|
||||||
|
iii++; // increment index of smaller element
|
||||||
|
etk::swap(_data[iii], _data[jjj]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
etk::swap(_data[iii + 1], _data[_high]);
|
||||||
|
return (iii + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The main function that implements QuickSort
|
||||||
|
arr[] --> Array to be sorted,
|
||||||
|
low --> Starting index,
|
||||||
|
high --> Ending index */
|
||||||
|
void quickSort(etk::Vector<etk::Uri>& _data, int _low, int _high) {
|
||||||
|
if (_low >= _high) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// pi is partitioning index, arr[p] is now at right place
|
||||||
|
int_t pi = partition(_data, _low, _high);
|
||||||
|
// Separately sort elements before partition and after partition
|
||||||
|
quickSort(_data, _low, pi - 1);
|
||||||
|
quickSort(_data, pi + 1, _high);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestUriProvider, checkDirectAccess) {
|
||||||
|
etk::uri::provider::clear();
|
||||||
|
TEST_VERBOSE("data path: " << etk::fs::getDataPath());
|
||||||
|
etk::uri::provider::add("DATA", ememory::makeShared<etk::uri::provider::ProviderFile>(etk::fs::getDataPath()));
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("DATA"), true);
|
||||||
|
ememory::SharedPtr<etk::uri::provider::Interface> provider = etk::uri::provider::getProvider("DATA");
|
||||||
|
EXPECT_NE(provider, null);
|
||||||
|
etk::Uri searchBase("DATA:///");
|
||||||
|
auto elems = provider->list(searchBase);
|
||||||
|
TEST_WARNING("List DATA path: (A)");
|
||||||
|
for (auto& it: elems) {
|
||||||
|
TEST_WARNING(" " << it);
|
||||||
|
}
|
||||||
|
elems.sort(0, elems.size(), [] (const etk::Uri& _left, const etk::Uri& _right) {
|
||||||
|
TEST_WARNING("compare " << _left << " " << (_left < _right?"<":">=") << " " << _right);
|
||||||
|
|
||||||
|
return _left < _right;
|
||||||
|
});
|
||||||
|
TEST_WARNING("List DATA path: (B)");
|
||||||
|
for (auto& it: elems) {
|
||||||
|
TEST_WARNING(" " << it);
|
||||||
|
}
|
||||||
|
quickSort(elems, 0, elems.size()-1);
|
||||||
|
TEST_WARNING("List DATA path: (C)");
|
||||||
|
for (auto& it: elems) {
|
||||||
|
TEST_WARNING(" " << it);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(elems, listDirect);
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Vector<etk::Uri> listDirect2 = {
|
||||||
|
"DATA:///data/.file_hidden.txt",
|
||||||
|
"DATA:///data/dir_A",
|
||||||
|
"DATA:///data/dir_B",
|
||||||
|
"DATA:///data/file_1.txt",
|
||||||
|
"DATA:///data/file_2.txt",
|
||||||
|
"DATA:///data/file_3.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(TestUriProvider, checkDirectAccess2) {
|
||||||
|
etk::uri::provider::clear();
|
||||||
|
TEST_VERBOSE("data path: " << etk::fs::getDataPath());
|
||||||
|
etk::uri::provider::add("DATA", ememory::makeShared<etk::uri::provider::ProviderFile>(etk::fs::getDataPath()));
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("DATA"), true);
|
||||||
|
ememory::SharedPtr<etk::uri::provider::Interface> provider = etk::uri::provider::getProvider("DATA");
|
||||||
|
EXPECT_NE(provider, null);
|
||||||
|
etk::Uri searchBase("DATA:///data");
|
||||||
|
|
||||||
|
auto elems = provider->list(searchBase);
|
||||||
|
TEST_WARNING("List DATA path: (A)");
|
||||||
|
for (auto& it: elems) {
|
||||||
|
TEST_WARNING(" " << it);
|
||||||
|
}
|
||||||
|
elems.sort(0, elems.size(), [] (const etk::Uri& _left, const etk::Uri& _right) {
|
||||||
|
return _left < _right;
|
||||||
|
});
|
||||||
|
TEST_WARNING("List DATA path: (B)");
|
||||||
|
for (auto& it: elems) {
|
||||||
|
TEST_WARNING(" " << it);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(elems, listDirect2);
|
||||||
|
}
|
||||||
|
|
||||||
|
etk::Vector<etk::Uri> listZip = {
|
||||||
|
"DATA:///.file_hidden.txt",
|
||||||
|
"DATA:///dir_A",
|
||||||
|
"DATA:///dir_B",
|
||||||
|
"DATA:///file_1.txt",
|
||||||
|
"DATA:///file_2.txt",
|
||||||
|
"DATA:///file_3.txt"
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(TestUriProvider, checkZipAccess) {
|
||||||
|
etk::uri::provider::clear();
|
||||||
|
TEST_VERBOSE("data path: " << etk::fs::getDataPath());
|
||||||
|
etk::uri::provider::add("DATA", ememory::makeShared<etk::uri::provider::ProviderFileZip>(etk::fs::getDataPath() / "data_sample.zip", "data"));
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("DATA"), true);
|
||||||
|
ememory::SharedPtr<etk::uri::provider::Interface> provider = etk::uri::provider::getProvider("DATA");
|
||||||
|
EXPECT_NE(provider, null);
|
||||||
|
TEST_WARNING("List DATA path:");
|
||||||
|
etk::Uri searchBase("DATA://");
|
||||||
|
auto elems = provider->list(searchBase);
|
||||||
|
for (auto& it: elems) {
|
||||||
|
TEST_WARNING(" " << it);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(elems, listZip);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
etk::Vector<etk::Uri> listZip2 = {
|
||||||
|
"DATA:///dir_B/dir_C",
|
||||||
|
"DATA:///dir_B/file_B_1.txt",
|
||||||
|
"DATA:///dir_B/file_B_2.txt",
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST(TestUriProvider, checkZipAccess2) {
|
||||||
|
etk::uri::provider::clear();
|
||||||
|
TEST_VERBOSE("data path: " << etk::fs::getDataPath());
|
||||||
|
etk::uri::provider::add("DATA", ememory::makeShared<etk::uri::provider::ProviderFileZip>(etk::fs::getDataPath() / "data_sample.zip", "data"));
|
||||||
|
EXPECT_EQ(etk::uri::provider::exist("DATA"), true);
|
||||||
|
ememory::SharedPtr<etk::uri::provider::Interface> provider = etk::uri::provider::getProvider("DATA");
|
||||||
|
EXPECT_NE(provider, null);
|
||||||
|
TEST_WARNING("List DATA path:");
|
||||||
|
etk::Uri searchBase("DATA:///dir_B");
|
||||||
|
auto elems = provider->list(searchBase);
|
||||||
|
for (auto& it: elems) {
|
||||||
|
TEST_WARNING(" " << it);
|
||||||
|
}
|
||||||
|
EXPECT_EQ(elems, listZip2);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user