etk/etk/os/FSNode.hpp

855 lines
30 KiB
C++

/** @file
* @author Edouard DUPIN
* @copyright 2011, Edouard DUPIN, all right reserved
* @license MPL v2.0 (see license file)
*/
#include <etk/types.hpp>
#pragma once
#include <etk/os/FSNodeRight.hpp>
#include <etk/stdTools.hpp>
/**
* @brief Local maximum file name size
*/
#define MAX_FILE_NAME (10240)
//http://developer.android.com/guide/topics/data/data-storage.html
#ifdef __TARGET_OS__Android
#define HAVE_ZIP_DATA
#endif
#ifdef __TARGET_OS__Windows
#define HAVE_ZIP_DATA
#endif
#ifdef __TARGET_OS__Web
#define HAVE_ZIP_DATA
#endif
#ifdef HAVE_ZIP_DATA
namespace etk {
class ArchiveContent;
}
#endif
namespace etk {
/**
* @brief Set the firt argument of the application start (this permit to get the real position of the execution path and executable position
* @param[in] _val First parameter.
*/
void setArgZero(const etk::String& _val);
/**
* @brief Force the "USERDATA:" to an other path (not the default path).
* @note this is called internaly to change the path with the generic cmd line intruction ... It is dangerous to do it in runtime (after start).
* @param[in] _val user data basic path.
*/
void forcePathUserData(const etk::String& _val);
/**
* @brief Simplify a path with all the complication that mean ".." or "///\//"
* @param[in] _input Parth to simplify
* @return the simplified path.
*/
etk::String simplifyPath(etk::String _input);
/**
* @brief Get application name.
* @return The application name
*/
etk::String FSNodeGetApplicationName();
/**
* @brief Get application binary path.
* @return The application path
*/
etk::String FSNodeGetApplicationPath();
/**
* @brief Get the user Home path.
* @return The Home path: "~"
*/
etk::String FSNodeGetHomePath();
/**
* @brief List of Type that a node can have (this wrap some type that not exist on Windows)
*/
enum typeNode {
typeNode_unknow, //!< Type of the node is not known
typeNode_block, //!< The node is a block aceess device (Not availlable on Windows)
typeNode_character, //!< The node is a Char device type (Not availlable on Windows)
typeNode_folder, //!< The node is a folder
typeNode_fifo, //!< The node is a Fifo (Not availlable on Windows)
typeNode_link, //!< The node is a Link
typeNode_file, //!< The node is a File
typeNode_socket, //!< The node is a socket
};
//! @not_in_doc
etk::Stream& operator <<(etk::Stream &_os, const enum etk::typeNode &_obj);
/**
* @brief Seek mode availlable (just to wrap it ...)
*/
enum seekNode{
seekNode_start, //!< request seek position start at the START of the file
seekNode_end, //!< request seek position start at the END of the file
seekNode_current, //!< request seek position start at the CURRENT position in the file
};
/**
* @brief Type of the file/folder/... accessible in the Node
*/
enum FSNType {
FSNType_unknow, //!< Unknow type of the node (many time no file name seted)
// user might done abstraction ==> acces of the sdcard when possible ...
FSNType_direct, //!< Access at the file System with a direct naming like "/home/plop/xxx.txt"
FSNType_relatif, //!< Access at the file System with a relative naming like "../plop/xxx.txt"
// depend on case
// - PC : ~/
// - Android : /sdcard/
// - Apple : ????
FSNType_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
FSNType_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 : ????
FSNType_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 : ????
FSNType_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
FSNType_theme, //!< Theme area
FSNType_themeData //!< Theme data area
};
//! @not_in_doc
etk::Stream& operator <<(etk::Stream &_os, const enum etk::FSNType &_obj);
/*
note : The filename can be
Direct mode:
DIRECT:/sdfsdfsdf/
/XX ==> for Linux / Mac / Android
[a-zA-Z]:/xxx ==> for Windows
Data mode:
DATA:folder/File.ccc
{libName}DATA:folder/File.ccc ==> try to read in appl data and in next in "libName" lib data folder
{@libName}DATA:folder/File.ccc ==> try to read ONLY in "libName" lib data folder
User data mode:
USERDATA:folder/File.ccc
{libName}USERDATA:folder/File.ccc
{@libName}USERDATA:folder/File.ccc
Cache Data:
CACHE:folder/File.ccc
Theme data:
THEME:folder/file.xxx
THEME:GUI:folder/file.xxx
{libName}THEME:GUI:folder/file.xxx
{@libName}THEME:GUI:folder/file.xxx
Get the root folder:
ROOT:
/
[a-zA-Z]: ==> create more risk ...
Get the Home folder:
HOME:
~
Get the relative folder:
REL:
./
*/
/**
* @brief FS node is for File System IO access (named classicly "node in linux EXT)
* This class is independent of the OS, If you acces to a file in windows, it might
* generate the right like Linux (it is important to know that windows right is lighter than linux)
*/
class FSNode {
private:
etk::String m_libSearch; //!< the name Of the subLib that system must church subData
etk::String m_userFileName; //!< the name requested by the User
etk::String m_systemFileName; //!< the compleate filename for the system
enum FSNType m_type; //!< the Type of data requested by the User
enum typeNode m_typeNode; //!< type of the current file/Folder/Link
etk::FSNodeRight m_rights; //!< IO right of the current file
// specific when file Access :
FILE * m_PointerFile; //!< When reading file, this is the Real pointer access
uint64_t m_timeCreate; //!< Creating date of the file
uint64_t m_timeModify; //!< Last modify time of the file
uint64_t m_timeAccess; //!< Last acces time of the file
uint32_t m_idOwner; //!< Id of the owner of the Node
uint32_t m_idGroup; //!< Id of the group of the Node
public:
/**
* @brief Constructor
* @param[in] _path Path of the curent file /folder ...
*/
FSNode(const etk::String& _path = "~");
/**
* @brief Destructor
* @note you will have some warning if you did not close your files
*/
~FSNode();
private:
/**
* @brief Internal methode that create the internal Real system name (transform DATA: HOME: DATA:GUI: in the real name of the files)
*/
void generateFileSystemPath();
/**
* @brief Update the internal data of the right type, and times
*/
void updateFileSystemProperty();
/**
* @brief Common set name of the Node (if the user decide to change the node selection
* @param[in] _newName Name of the Node
*/
void privateSetName(etk::String _newName);
private:
#ifdef HAVE_ZIP_DATA
/**
* @brief Explocitly for Android that data are stored in the .apk that is a .zip not compressed
* @return true : Load is OK
* @return false : An error Occured
*/
bool loadDataZip();
const etk::ArchiveContent* m_zipContent;
int32_t m_zipReadingOffset;
#endif
public:
/**
* @brief Check if the node exist.
* @return true : The node existed.
* @return false : The node does not exist.
*/
bool exist() const {
return (m_typeNode!=etk::typeNode_unknow);
};
/**
* @brief Get the node type
* @return the requested type, typeNode_unknow if it does not existed
*/
enum typeNode getNodeType() const {
return m_typeNode;
};
/**
* @brief Get the node Right
* @return the requested right
*/
etk::FSNodeRight getRight() const {
return m_rights;
};
/**
* @brief Set the specific right of the node
* @param[in] _newRight new right to set
* @return true : action done
* @return false : action not done
*/
bool setRight(etk::FSNodeRight _newRight);
/**
* @brief Change the Node seeing (not rename the node, for this @ref etk::FSNodeMove)
* @param[in] _newName New node name to show
* @return true action done
* @return false action not done
*/
void setName(const etk::String& _newName);
/**
* @brief Get the Generate FileSystem name
* @return the requested filename
*/
etk::String getFileSystemName() const;
/**
* @brief Get the current folder of the Node. (file system name)
* @return the common name define (like /xxxxx/xxxxx/ or c:/xxxxx/xxxxx/)
* @note Auto remove of ../../../ and //
*/
etk::String getNameFolder() const;
/**
* @brief Get the current compleate node name (file system name)
* @return All the user name definition (like /xxxxx/xxxxx/myFile.kkk or c:/xxxxx/xxxxx/myFile.kkk)
* @note Auto remove of ../../../ and //
*/
etk::String getName() const;
/**
* @brief Get the file or current file name (if it was a file)
* @return the name of the node (like myFile.kkk)
*/
etk::String getNameFile() const;
/**
* @brief Get the current folder of the Node.
* @return the common name define (like DATA:xxxxx/xxxxx/)
* @note Auto remove of ../../../ and //
*/
etk::String getRelativeFolder() const;
/**
* @brief update the Time of the file with the current time
* @return true : action done
* @return false : action not done
*/
bool touch();
/**
* @brief Move the Node at a new path
* @param[in] _path The new path
* @return true : action done
* @return false : action not done
*/
bool move(const etk::String& _path);
/**
* @brief Get the node type (DATA/DIRECT...)
* @return the requested type
*/
enum FSNType getTypeAccess() const {
return m_type;
};
/**
* @brief Remove the current node ( if folder, this remove all subfolder but not the Link subfolder)
* @return true : action done
* @return false : action not done
*/
bool remove();
/**
* @brief Get the creating time of the File
* @return The time requested
*/
uint64_t timeCreated() const;
/**
* @brief Get the creating time of the File
* @return The time requested (in string)
*/
etk::String timeCreatedString() const;
/**
* @brief Get the modifying time of the File
* @return The time requested
*/
uint64_t timeModified() const;
/**
* @brief Get the modifying time of the File
* @return The time requested (in string)
*/
etk::String timeModifiedString() const;
/**
* @brief Get the Accessed time of the File
* @return The time requested
*/
uint64_t timeAccessed() const;
/**
* @brief Get the Accessed time of the File
* @return The time requested (in string)
*/
etk::String timeAccessedString() const;
/**
* @brief copy the other FSnode ==> for vector
* @param[in] _obj input node
* @return the current modify node
*/
const etk::FSNode& operator= (const etk::FSNode &_obj );
/**
* @brief Check if the 2 node are link with the same file
* @param[in] _obj input node
* @return true : same node, false otherwise
*/
bool operator== (const etk::FSNode &_obj ) const;
/**
* @brief Check if the 2 node are NOT link with the same file
* @param[in] _obj input node
* @return false : same node, true otherwise
*/
bool operator!= (const etk::FSNode &_obj ) const;
/**
* @brief Write in the statard debug IO the current node
* @param[in] _os std debug IO
* @param[in] _obj Node to display
* @return std debug IO
*/
friend etk::Stream& operator <<( etk::Stream &_os,const etk::FSNode &_obj);
/**
* @brief Count the number of subFolder in the curent Folder
* @return >=0 nb of subElement
* @return -1 an error occured ==> not a folder ???
*/
int64_t folderCount();
/**
* @brief Get the List of all node inside a node (folder only)
* @param[in] _showHidenFile Add hidden file/folder/...
* @param[in] _getFolderAndOther get folder
* @param[in] _getFile Get files
* @param[in] _temporaryFile add Tmp file like .bck or ~
* @return The requested list
*/
etk::Vector<etk::FSNode*> folderGetSubList(bool _showHidenFile = true,
bool _getFolderAndOther = true,
bool _getFile = true,
bool _temporaryFile = true);
/**
* @brief Get the List of all node inside a node (folder only)
* @param[in] _showHidenFile Add hidden file/folder/...
* @param[in] _getFolderAndOther get folder
* @param[in] _getFile Get files
* @param[in] _filter Generic regex string to filter file names
* @return The requested list
*/
etk::Vector<etk::FSNode*> folderGetSubList(bool _showHidenFile = true,
bool _getFolderAndOther = true,
bool _getFile = true,
const etk::String& _filter = ".*");
/**
* @brief Get the List of all node inside a node (folder only)
* @param[in] _getFolder get folder
* @param[in] _getFile Get files
* @param[in] _filter Generic regex string to filter file names
* @return The requested list
*/
etk::Vector<etk::String> folderGetSub(bool _getFolder, bool _getFile, const etk::String& _filter);
/**
* @brief Get the father node of this node
* @return The requested node
*/
etk::FSNode folderGetParent();
/**
* @brief Get all the File inside a Folder (done recursively)
* @param[out] _output List of all the File names (You must clear it before set it in)
* @param[in] _recursiveEnable Activate the recursive mode (enable by default)
*/
void folderGetRecursiveFiles(etk::Vector<etk::String>& _output, bool _recursiveEnable=true);
/**
* @brief Check if the file have an extention ( ***.ccc)
* @return true The file have an extention.
* @return false The file have NO extention.
*/
bool fileHasExtention();
/**
* @brief Get the extention of the Node
* @return the requested extention
*/
etk::String fileGetExtention();
/**
* @brief Get the File size
* @return the requested size
*/
uint64_t fileSize();
/**
* @brief Open the file in Read mode
* @return true : action done
* @return false : action not done
*/
bool fileOpenRead();
/**
* @brief Open the file in write Mode
* @note You can not do it with the DATA: file ==> this is not allowed in some Board like Android)
* @return true : action done
* @return false : action not done
*/
bool fileOpenWrite();
/**
* @brief Open the file in write Append Mode
* @note You can not do it with the DATA: file ==> this is not allowed in some Board like Android)
* @return true : action done
* @return false : action not done
*/
bool fileOpenAppend();
/**
* @brief Check if the current file is Open
* @return true : File is open in write or in read
* @return false : File is NOT open in write or in read
*/
bool fileIsOpen();
/**
* @brief Close the curent file
* @return true : action done
* @return false : action not done
*/
bool fileClose();
/**
* @brief Get the pointer on the start line and the next line (or null)
* @param[in,out] _elementLine Pointer to an array of chars where the string read is copied.
* @param[in] _maxData Maximum number of characters to be copied into str (including the terminating null-character).
* @return the pointer on the end of the cuurent line.
*/
char* fileGets(char* _elementLine, int64_t _maxData);
/**
* @brief Get a unique data in the file
* @return the next element in the file.
*/
char fileGet();
/**
* @brief Get a compleate line in a text file
* @param[out] _output the next element in the file.
* @return true The file is not ended.
* @return false The file is ended.
*/
bool fileGets(etk::String& _output);
/**
* @brief Write data on the file
* @param[in] _input data to write.
* @return true Write done corectly.
* @return false ErrorOn write.
*/
bool filePut(char _input);
/**
* @brief Write data on the file
* @param[in] _input data to write.
* @return true Write done corectly.
* @return false ErrorOn write.
*/
bool filePuts(const etk::String& _input);
/**
* @brief Read data from the file
* @param[in,out] _data Pointer on the buffer that might be set the data
* @param[in] _blockSize Size of one block of data
* @param[in] _nbBlock Number of block needed
* @return Number of element read (in block number)
*/
int64_t fileRead(void* _data, int64_t _blockSize, int64_t _nbBlock);
/**
* @brief Write data on the file
* @param[in] _data Pointer on the buffer that might be set on the file
* @param[in] _blockSize Size of one block of data
* @param[in] _nbBlock Number of block needed
* @return Number of element written (in block number)
*/
int64_t fileWrite(const void* _data, int64_t _blockSize, int64_t _nbBlock);
// TODO: etk::FSNode& operator<< (const etk::Stream& _data);
/**
* @brief Stream write mode
* @param[in] _data Stream to write
* @return The current FSNode reference to add other stream.
* @note not stable API ...
*/
etk::FSNode& operator<< (const etk::Stream& _data);
//! @copydoc etk::FSNode::operator<<(const etk::Stringstream&)
etk::FSNode& operator<< (const etk::String& _data);
//! @copydoc etk::FSNode::operator<<(const etk::Stringstream&)
etk::FSNode& operator<< (const char* _data);
//! @copydoc etk::FSNode::operator<<(const etk::Stringstream&)
etk::FSNode& operator<< (const int32_t _data);
//! @copydoc etk::FSNode::operator<<(const etk::Stringstream&)
etk::FSNode& operator<< (const uint32_t _data);
//! @copydoc etk::FSNode::operator<<(const etk::Stringstream&)
etk::FSNode& operator<< (const float _data);
/**
* @brief Get the position in the file.
* @return the requested position.
*/
int64_t fileTell();
/**
* @brief Move in the file Position
* @param[in] _offset Offset to apply at the file
* @param[in] _origin Origin of the position
* @return true : action done
* @return false : action not done
*/
bool fileSeek(long int _offset, enum etk::seekNode _origin);
/**
* @brief Flush the current file
*/
void fileFlush();
/**
* @brief Read all element in a file and set it in a generic vector
* @return the read vector
*/
template<typename T> etk::Vector<T> fileReadAll() {
etk::Vector<T> value;
value.resize(fileSize());
fileRead(&value[0], sizeof(T), fileSize()/sizeof(T));
return value;
}
/**
* @brief Read all element in a file and set it in a generic etk::String
* @return the read string
*/
etk::String fileReadAllString() {
etk::String value;
value.resize(fileSize());
fileRead(&value[0], sizeof(char), fileSize()/sizeof(char));
return value;
}
/**
* @brief Write all the vector in a file
* @param[in] _value Data to write in the File
*/
template<typename T>
void fileWriteAll(const etk::Vector<T>& _value) {
fileWrite(static_cast<const void*>(&(_value[0])), sizeof(T), _value.size()/sizeof(T));
}
/**
* @brief Write all the vector in a file
* @param[in] _value String data to write in the File
*/
void fileWriteAll(const etk::String& _value) {
fileWrite(static_cast<const void*>(&(_value[0])), sizeof(char), _value.size()/sizeof(char));
}
private:
/**
* @brief Order the list of subnode the folder first and the alphabetical order
* @param[in,out] _list The list to order
*/
void sortElementList(etk::Vector<etk::FSNode *>& _list);
};
//! @not_in_doc
etk::Stream& operator <<(etk::Stream &_os, const etk::FSNode &_obj);
/**
* @brief Set manualy the folder of the Data.(like /usr/shared/applName/ for linux)
* @param[in] _folder folder path of the cathegorie
* @param[in] _applName Base name of the application
*/
void setBaseFolderData(const char* _folder, const char* _applName=null);
/**
* @brief Set the user data folder (like /home/machin/.local/applName/ for linux)
* @param[in] _folder folder path of the cathegorie
*/
void setBaseFolderDataUser(const char* _folder);
/**
* @brief Set the Cach folder for the application (like /tmp)
* @param[in] _folder folder path of the cathegorie
*/
void setBaseFolderCache(const char* _folder);
/**
* @brief Initialyse all the subFolder usable by the user like DATA/HOME/CACHE/USERDATA
* @param[in] _applName the name of the application
*/
void initDefaultFolder(const char* _applName);
/**
* @brief Get the home folder of the user
* @return the home folder : like : "/home/machin/"
*/
etk::String getUserHomeFolder();
/**
* @brief Get the folder of the Program is running
* @return the basic folder name (ex : run ./appl in the pwd=/home/machin/sousFolder ==> this return the pwd folder)
*/
etk::String getUserRunFolder();
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<etk::String> list();
};
/**
* @brief Get the size of a specific file
* @param[in] _path Folder/File/Pipe path of the node
* @return size of the file
*/
uint64_t FSNodeGetSize(const etk::String& _path);
/**
* @brief Simple access for : Remove folder and subFolder, files pipes ...
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
bool FSNodeRemove(const etk::String& _path);
/**
* @brief Simple access for : count the number of element in a path (if it is not a path ==> return -1)
* @param[in] _path Folder/File/Pipe path of the node
* @return number of File inside
* @return -1 : An error occured
*/
int64_t FSNodeGetCount(const etk::String& _path);
/**
* @brief Simple access for : Create a file or a folder depending of the request
* @param[in] _path Folder/File/Pipe path of the node
* @param[in] _right Right of the creation
* @param[in] _type Type of the element that might be created
* @return true : Action done corectly
* @return false : An error occured
*/
bool FSNodeCreate(const etk::String& _path, etk::FSNodeRight _right, enum etk::typeNode _type=etk::typeNode_folder);
/**
* @brief Simple access for : chexk the exestance of an element
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
bool FSNodeExist(const etk::String& _path);
/**
* @brief Simple access for : chexk the exestance of an element
* @param[in] _path1 Folder/File/Pipe path of the node sources
* @param[in] _path2 Folder/File/Pipe path of the node destination
* @return true : Action done corectly
* @return false : An error occured
*/
bool FSNodeMove(const etk::String& _path1, const etk::String& _path2);
/**
* @brief Simple access for : Get right of the current Node
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
etk::FSNodeRight FSNodeGetRight(const etk::String& _path);
/**
* @brief Simple access for : Get type of the current node
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
enum etk::typeNode FSNodeGetType(const etk::String& _path);
/**
* @brief Simple access for : Getting creation time of the current node
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
uint64_t FSNodeGetTimeCreated(const etk::String& _path);
/**
* @brief Simple access for : Getting Modification time of the current node
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
uint64_t FSNodeGetTimeModified(const etk::String& _path);
/**
* @brief Simple access for : Getting Accessing time of the current node
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
uint64_t FSNodeGetTimeAccessed(const etk::String& _path);
/**
* @brief Simple access for : Update Modification time with the current time of the node (>)
* @param[in] _path Folder/File/Pipe path of the node
* @return true : Action done corectly
* @return false : An error occured
*/
bool FSNodeTouch(const etk::String& _path);
/**
* @brief Simple access for : Basic write on the node (like console echo)
* @param[in] _path Folder/File/Pipe path of the node
* @param[in] _dataTowrite write data in the Node
* @return true : Action done corectly
* @return false : An error occured
*/
bool FSNodeEcho(const etk::String& _path, const etk::String& _dataTowrite);
/**
* @brief Simple access for : Basic write on the node (like console echo) in adding mode (>>)
* @param[in] _path Folder/File/Pipe path of the node
* @param[in] _dataTowrite write data in the Node
* @return true : Action done corectly
* @return false : An error occured
*/
bool FSNodeEchoAdd(const etk::String& _path, const etk::String& _dataTowrite);
/**
* @brief move file to generate an history of the current file
* @param[in] _path Folder/File/Pipe path of the node
* @param[in] _historyCount number of saved file in the history (-xxx)
*/
void FSNodeHistory(const etk::String& _path, int32_t _historyCount);
/**
* @brief Read all the data from a file
* @param[in] _path Folder/File/Pipe path of the node
* @return all the data of the file in a string
*/
etk::String FSNodeReadAllData(const etk::String& _path);
/**
* @brief Write all the data in a file
* @param[in] _path Folder/File/Pipe path of the node
* @param[in] _data All the data of the file in a string
*/
void FSNodeWriteAllData(const etk::String& _path, const etk::String& _data);
/**
* @brief Read all the data from a file
* @param[in] _path Folder/File/Pipe path of the node
* @param[in] _offset Start offset in byte in the file
* @return all the data of the file in a typed vector
*/
template<typename TTT> etk::Vector<TTT> FSNodeReadAllDataType(const etk::String& _path, int32_t _offset=0) {
etk::Vector<TTT> out;
etk::FSNode node(_path);
if (node.fileOpenRead() == false) {
//TK_ERROR("can not open file : '" << node << "'");
return out;
}
uint64_t nbByte = node.fileSize();
nbByte -= _offset;
out.resize(nbByte/sizeof(TTT));
if (out.size()*sizeof(TTT) != nbByte) {
//TK_WARNING("Error in reading the file missing some byte at the end ...");
}
node.fileSeek(_offset, seekNode_start);
node.fileRead(&out[0], sizeof(TTT), nbByte/sizeof(TTT));
node.fileClose();
return out;
}
/**
* @brief Write all the data in a file
* @param[in] _path Folder/File/Pipe path of the node
* @param[in] _data All the data of the file in a vector Typed bits ...
*/
template<typename TTT> void FSNodeWriteAllDataType(const etk::String& _path, const etk::Vector<TTT>& _data) {
etk::FSNode node(_path);
if (node.fileOpenWrite() == false) {
//TK_ERROR("can not open file : '" << node << "'");
return;
}
node.fileWrite(&_data[0], sizeof(TTT), _data.size());
node.fileClose();
}
/**
* @brief get the system name of the current path
* @param[in] _path "DATA:xxx" etk file name.
* @return return real file name "/aaa/bbb/ccc/xxx"
*/
etk::String FSNodeGetRealName(const etk::String& _path);
/**
* @brief Get all the Path contain in the specidy path:
* @param[in] _path Generic path to parse ...
* @return The list of path found
* @code
* auto out = etk::FSNodeExplodeMultiplePath("{ewol}DATA:font");
* // out contain: {"DATA:font", "{@ewol}DATA:font"}
* @endcode
* @code
* auto out = etk::FSNodeExplodeMultiplePath("{@ewol}DATA:font");
* // out contain: {"{@ewol}DATA:font"}
* @endcode
*/
etk::Vector<etk::String> FSNodeExplodeMultiplePath(const etk::String& _path);
};