--- /dev/null
+# This file is used to ignore files which are generated
+# ----------------------------------------------------------------------------
+
+*~
+*.autosave
+*.a
+*.core
+*.moc
+*.o
+*.obj
+*.orig
+*.rej
+*.so
+*.so.*
+*_pch.h.cpp
+*_resource.rc
+*.qm
+.#*
+*.*#
+core
+!core/
+tags
+.DS_Store
+*.debug
+Makefile*
+*.prl
+*.app
+moc_*.cpp
+ui_*.h
+qrc_*.cpp
+Thumbs.db
+*.res
+*.rc
+/.qmake.cache
+/.qmake.stash
+
+# qtcreator generated files
+*.pro.user*
+
+# xemacs temporary files
+*.flc
+
+# Vim temporary files
+.*.swp
+
+# Visual Studio generated files
+*.ib_pdb_index
+*.idb
+*.ilk
+*.pdb
+*.sln
+*.suo
+*.vcproj
+*vcproj.*.*.user
+*.ncb
+*.sdf
+*.opensdf
+*.vcxproj
+*vcxproj.*
+
+# MinGW generated files
+*.Debug
+*.Release
+
+# Python byte code
+*.pyc
+
+# Binaries
+# --------
+*.dll
+*.exe
+
+
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#include "resh.hpp"
+
+ReShellTree::ReShellTree()
+{
+
+}
+
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#ifndef RESHELLTREE_HPP
+#define RESHELLTREE_HPP
+
+class ReShellStatement{
+public:
+ enum StatementFlags {
+ SF_UNDEF,
+ SF_INTERNAL_CMD = 1,
+ SF_VAR_EXPANSION = 2,
+ SF_INTERPOLATION = 4,
+ SF_INP_REDIRECT = 8,
+ SF_OUT_REDIRECT = 16,
+ SF_SHELL_SCRIPT = 32,
+ SF_OUT_TO_STRING = 64,
+ };
+public:
+ ReSource* source;
+ ReShellStatement* m_next;
+ int m_flags;
+};
+
+class ReShellIf : public ReShellStatement{
+public:
+ ReShellStatement* m_condition;
+ ReShellStatement* m_then;
+ ReShellStatement* m_else;
+};
+
+class ReShellWhile : public ReShellStatement{
+public:
+ ReShellStatement* m_condition;
+ ReShellStatement* m_body;
+};
+
+class ReCaseAlternative {
+public:
+ QByteArray m_value;
+ ReShellStatement* m_statement;
+ ReCaseAlternative* m_next;
+};
+
+
+class ReShellCase : public ReShellStatement{
+protected:
+ ReCaseAlternative* m_condition;
+ ReShellStatement* m_body;
+};
+
+class ReShellFunction {
+public:
+ QByteArray m_name;
+ ReShellStatement* m_body;
+};
+
+
+class ReShellTree
+{
+public:
+ ReShellTree();
+public:
+ QList<ReShellFunction> m_functions;
+ ReShellStatement m_body;
+};
+
+#endif // RESHELLTREE_HPP
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#include <QCoreApplication>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication a(argc, argv);
+
+ return a.exec();
+}
+
--- /dev/null
+/*
+ * Licence:
+ * You can use and modify this file without any restriction.
+ * There is no warranty.
+ * You also can use the licence from http://www.wtfpl.net/.
+ * The original sources can be found on https://github.com/republib.
+*/
+
+
+#ifndef RESH_HPP
+#define RESH_HPP
+
+#include "base/rebase.hpp"
+#include "expr/reexpr.hpp"
+#include "os/reos.hpp"
+#include "ReShellTree.hpp"
+#endif // RESH_HPP
+
--- /dev/null
+QT += core
+#QT -= gui
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = resh
+CONFIG += console
+CONFIG -= app_bundle
+
+TEMPLATE = app
+
+INCLUDEPATH = ../..
+
+SOURCES += main.cpp \
+ ../../base/ReStringUtils.cpp \
+ ../../base/ReQStringUtils.cpp \
+ ../../base/ReCharPtrMap.cpp \
+ ../../base/ReException.cpp \
+ ../../base/ReLogger.cpp \
+ ../../expr/ReSource.cpp \
+ ../../expr/ReLexer.cpp \
+ ReShellTree.cpp
+# ../../expr/ReExpression.cpp \
+
+HEADERS += \
+ resh.hpp
+
ReLocalFileSystem fs(m_base, &m_logger);
QByteArray buffer;
buffer.append("abcdefghijklmnopqrstuvwxyz");
- checkEqu(0, fs.write("abc.txt", 0LL, buffer));
- checkEqu(0, fs.write("abc.txt", 26LL, buffer));
+
+ //checkEqu(0, fs.write("abc.txt", 0LL, buffer));
+ //checkEqu(0, fs.write("abc.txt", 26LL, buffer));
QByteArray buffer2;
ReFileMetaDataList nodes;
QStringList names;
names.append("abc.txt");
+ names.append("new.txt");
ReIncludeExcludeMatcher matcher(names, ReQStringUtils::m_emptyList,
Qt::CaseInsensitive, true);
checkEqu(1, fs.listInfos(matcher, nodes, ReFileSystem::LO_UNDEF));
checkEqu(1, nodes.size());
- checkEqu(0, fs.read(nodes.at(0), 0LL, 3, buffer2));
+ QByteArray content("This is a content\nLine 2");
+ checkEqu(0, fs.createFile("new.txt", false));
+ ReFileMetaData meta;
+ checkT(fs.exists("new.txt", &meta));
+ ReLeafFile* leaf1 = fs.buildFile(meta);
+ leaf1->open(true);
+ leaf1->write(content);
+ leaf1->close();
+ delete leaf1;
+ checkT(fs.exists("new.txt", &meta));
+ ReLeafFile* leaf2 = fs.buildFile(meta);
+ leaf2->open(false);
+ leaf2->read(500, buffer);
+ leaf2->close();
+ delete leaf2;
+
+ //checkEqu(0, fs.read(nodes.at(0), 0LL, 3, buffer2));
checkEqu("abc", buffer2);
- checkEqu(0, fs.read(nodes.at(0), 3LL, 7, buffer2));
+ //checkEqu(0, fs.read(nodes.at(0), 3LL, 7, buffer2));
checkEqu("defghij", buffer2);
- checkEqu(0, fs.read(nodes.at(0), 10LL, 99, buffer2));
+ //checkEqu(0, fs.read(nodes.at(0), 10LL, 99, buffer2));
checkEqu("klmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", buffer2);
}
void testSetProperties() {
LOC_MAKE_DIR_1, // 12308
LOC_FILE_OPEN_1, // 12309
LOC_FILE_WRITE_1, // 12310
+ LOC_CREATE_FILE_1, // 12311
};
const int ReCryptFileSystem::NODE_LENGHT = 44;
ReCryptFileSystem::~ReCryptFileSystem() {
}
+/**
+ * Returns a filesystem dependent instance of a file.
+ *
+ * The file must exist in the current directory.
+ * The caller must free the instance.
+ *
+ * @param meta the metadata of the file
+ * @return NULL: no file found<br>
+ * otherwise: the file
+ */
+ReLeafFile* ReCryptFileSystem::buildFile(const ReFileMetaData& metadata)
+{
+ return new ReCryptLeafFile(metadata, fullName(metadata.m_node), m_logger2);
+}
+
QString ReCryptFileSystem::canonicalPathOf(const QString& path)
{
return ReFileUtils::cleanPath(path);
}
-/** Frees resources like open files.
+/**
+ * Creates a new file in the current directory.
+ *
+ * @param node the name of the new file
+ * @param inDirectoryOnly <code>false</code>: the file is made physically<br>
+ * otherwise: the file exists only in the metadata
+ * of the directory
+ * @param metadata OUT: NULL or the metadata of the new file
+ * @return EC_SUCCESS: success<br>
+ * EC_ALREADY_EXISTS: the file already exists
+ * EC_WRITE: the file could not be written
*/
-void ReCryptFileSystem::close()
+ReFileSystem::ErrorCode ReCryptFileSystem::createFile(const QString& node,
+ bool inDirectoryOnly, ReFileMetaData* metadata)
{
+ ErrorCode rc = EC_SUCCESS;
+ if (exists(node, NULL))
+ rc = EC_ALREADY_EXISTS;
+ else{
+ QDateTime now = QDateTime::currentDateTime();
+ int id = ++m_maxFileId;
+ ReFileMetaData meta = ReFileMetaData(node, now, now,
+ m_osPermissions.m_user, m_osPermissions.m_group,
+ m_osPermissions.m_dirMode, 0, id);
+ m_list.append(meta);
+ if (metadata != NULL){
+ *metadata = meta;
+ }
+ if (! inDirectoryOnly){
+ QString hostName = buildHostedNode(id);
+ QByteArray fullName = fullNameAsUTF8(hostName);
+ FILE* fp = fopen(fullName.constData(), "w");
+ if (fp == NULL){
+ rc = EC_WRITE;
+ m_logger2->logv(LOG_ERROR, LOC_CREATE_FILE_1, "cannot open (%d): %s",
+ errno, fullName.constData());
+ } else
+ fclose(fp);
+ }
+ }
+ return rc;
}
/**
}
return rc;
}
+
+/**
+ * Constructor.
+ *
+ * @param metaData metadata of the file
+ * @param fullName filename with path
+ * @param logger the logger
+ */
+ReCryptLeafFile::ReCryptLeafFile(const ReFileMetaData& metaData,
+ const QString& fullName, ReLogger* logger) :
+ ReLeafFile(metaData, fullName, logger)
+{
+
+}
+
+/**
+ * Destructor.
+ */
+ReCryptLeafFile::~ReCryptLeafFile()
+{
+
+}
+
+ReFileSystem::ErrorCode ReCryptLeafFile::open(bool writeable)
+{
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ return rc;
+}
+
+ReFileSystem::ErrorCode ReCryptLeafFile::close()
+{
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ return rc;
+}
+
+ReFileSystem::ErrorCode ReCryptLeafFile::read(int size, QByteArray& buffer)
+{
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ return rc;
+}
+
+ReFileSystem::ErrorCode ReCryptLeafFile::write(const QByteArray& buffer)
+{
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ return rc;
+}
int m_maxFileId;
};
+/**
+ * An abstract base class for leafs of the tree spanned by a filesystem.
+ *
+ * A leaf file could not be a directory.
+ */
+class ReCryptLeafFile : public ReLeafFile{
+public:
+ ReCryptLeafFile(const ReFileMetaData& metaData, const QString& fullName,
+ ReLogger* logger);
+ virtual ~ReCryptLeafFile();
+public:
+ virtual ReFileSystem::ErrorCode open(bool writeable);
+ virtual ReFileSystem::ErrorCode close();
+ virtual ReFileSystem::ErrorCode read(int size, QByteArray& buffer);
+ virtual ReFileSystem::ErrorCode write(const QByteArray& buffer);
+};
+
/**
* A filesystem with encrypted filenames and file content.
*
ReRandomizer& contentRandom, ReLogger* logger);
~ReCryptFileSystem();
public:
+ virtual ReLeafFile* buildFile(const ReFileMetaData& metadata);
virtual QString canonicalPathOf(const QString& path);
- virtual void close();
+ virtual ErrorCode createFile(const QString& node, bool inDirectoryOnly,
+ ReFileMetaData* metadata = NULL);
virtual bool exists(const QString& node, ReFileMetaData* metaInfo) const;
virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
ReFileMetaDataList& list, ListOptions options = LO_ALL);
LOC_REMOVE_3, // 12015
LOC_SET_PROPERTIES_4, // 12016
LOC_SET_PROPERTIES_5, // 12017
+ LOC_OPEN_1, // 12018
+ LOC_CREATE_FILE_1, // 12019
};
/**
ErrorCode rc = EC_SUCCESS;
ErrorCode rc2;
int64_t size = 0;
- while (rc == EC_SUCCESS && size < source.m_size) {
- if ((rc2 = sourceFS.read(source, size, blocksize, m_buffer))
- != EC_SUCCESS)
- rc = rc2;
- else if ((rc2 = write(source.m_node, size, m_buffer)) != EC_SUCCESS)
- rc = rc2;
- size += blocksize;
+ ReLeafFile* sourceFile = sourceFS.buildFile(source);
+ ReFileMetaData targetMeta;
+ if (! exists(source.m_node, &targetMeta)){
+ rc = createFile(source.m_node, false, &targetMeta);
+ }
+ if (rc == EC_SUCCESS){
+ ReLeafFile* targetFile = buildFile(targetMeta);
+ if (sourceFile->open(false) == EC_SUCCESS
+ && targetFile->open(true) == EC_SUCCESS){
+ while (rc == EC_SUCCESS && size < source.m_size) {
+ if ((rc2 = sourceFile->read(blocksize, m_buffer))
+ != EC_SUCCESS)
+ rc = rc2;
+ else if ((rc2 = targetFile->write(m_buffer)) != EC_SUCCESS)
+ rc = rc2;
+ size += blocksize;
+ }
+ }
+ sourceFile->close();
+ targetFile->close();
+ ReFileMetaData target(source.m_node, ReFileUtils::m_undefinedTime,
+ ReFileUtils::m_undefinedTime, m_uid, m_gid);
+ setProperties(source, target, false);
+ delete sourceFile;
+ delete targetFile;
}
- close();
- sourceFS.close();
- ReFileMetaData target(source.m_node, ReFileUtils::m_undefinedTime,
- ReFileUtils::m_undefinedTime, m_uid, m_gid);
- setProperties(source, target, false);
return rc;
}
ReLocalFileSystem::ReLocalFileSystem(const QString& basePath, ReLogger* logger) :
ReFileSystem("localfs", logger),
m_basePath(basePath),
- m_dir(basePath),
- m_readFile(NULL),
- m_writeFile(NULL) {
+ m_dir(basePath) {
m_directory = basePath;
ReQStringUtils::ensureLastChar(m_directory, OS_SEPARATOR);
setWriteable(true);
return m_basePath;
}
-/**
- * Closes the open files.
- */
-void ReLocalFileSystem::close() {
- if (m_readFile != NULL) {
- fclose(m_readFile);
- m_readFile = NULL;
- }
- if (m_writeFile != NULL) {
- fclose(m_writeFile);
- m_writeFile = NULL;
- }
-}
-
/**
* Search a file in the current directory given by name.
*
return rc;
}
+/**
+ * Creates a new file in the current directory.
+ *
+ * @param node the name of the new file
+ * @param inDirectoryOnly <code>false</code>: the file is made physically<br>
+ * otherwise: the file exists only in the metadata
+ * of the directory
+ * @param metadata OUT: NULL or the metadata of the new file
+ * @return EC_SUCCESS: success<br>
+ * EC_ALREADY_EXISTS: the file already exists
+ * EC_WRITE: the file could not be written
+ */
+ReFileSystem::ErrorCode ReLocalFileSystem::createFile(const QString& node,
+ bool inDirectoryOnly, ReFileMetaData* metadata)
+{
+ ErrorCode rc = EC_SUCCESS;
+ if (exists(node))
+ rc = EC_ALREADY_EXISTS;
+ else{
+ if (metadata != NULL){
+ QDateTime now = QDateTime::currentDateTime();
+ *metadata = ReFileMetaData(node, now, now, m_osPermissions.m_user,
+ m_osPermissions.m_group, m_osPermissions.m_dirMode, 0);
+ }
+ if (! inDirectoryOnly){
+ QByteArray name(fullNameAsUTF8(node));
+ FILE* fp = fopen(name.constData(), "w");
+ if (fp == NULL){
+ rc = EC_WRITE;
+ m_logger->logv(LOG_ERROR, LOC_CREATE_FILE_1, "cannot open (%d): %s",
+ errno, name.constData());
+ } else
+ fclose(fp);
+ }
+ }
+ return rc;
+}
+
/**
* Returns the canonical form of a given path.
*
return rc;
}
-/**
- * Reads a part of a file into a buffer.
- *
- * @param source the file to move
- * @param offset first position to read
- * @param size number of bytes to read
- * @param buffer OUT: content of the file
- * @return EC_SUCCESS: success<br>
- * EC_NOT_READABLE: file can't be opened<br>
- * EC_READ: error while reading
- */
-ReFileSystem::ErrorCode ReLocalFileSystem::read(const ReFileMetaData& source,
- int64_t offset, int size, QByteArray& buffer) {
- ErrorCode rc = EC_SUCCESS;
- if (offset == 0) {
- if (m_readFile != NULL)
- fclose(m_readFile);
- QString fn = fullName(source.m_node);
- if ((m_readFile = fopen(fn.toUtf8().constData(), "rb")) == NULL) {
- m_logger->logv(LOG_ERROR, LOC_READ_1,
- "cannot open for reading (%d): %s", errno,
- fn.toUtf8().constData());
- rc = EC_NOT_READABLE;
- }
- }
- if (m_readFile != NULL) {
- ReFileUtils::seek(m_readFile, offset, SEEK_SET);
- buffer.reserve(size);
- int nRead = fread(buffer.data(), 1, size, m_readFile);
- if (nRead < 0) {
- m_logger->logv(LOG_ERROR, LOC_READ_2, "cannot read (%d): %s", errno,
- source.m_node.toUtf8().constData());
- nRead = 0;
- rc = EC_READ;
- }
- buffer.resize(nRead);
- if (feof(m_readFile)) {
- fclose(m_readFile);
- m_readFile = NULL;
- } else {
- fflush(m_readFile);
- }
- }
- return rc;
-}
-
/**
* Removes a file or directory.
*
return rc;
}
-/**
- * Writes a buffer to a file.
- *
- * @param node the file to write (without path, inside the current directory)
- * @param offset first position to write
- * @param buffer content to write
- * @return EC_SUCCESS: successful<br>
- * EC_FS_READ_ONLY: filesystem is readonly<br>
- * EC_NOT_WRITEABLE: open for writing failed
- * EC_POSITION: file position not equals to <code>offset</code>
- * EC_WRITE: writing failed
- *
- */
-ReFileSystem::ErrorCode ReLocalFileSystem::write(const QString& node,
- int64_t offset, const QByteArray& buffer) {
- ErrorCode rc = EC_SUCCESS;
- if (!writeable()) {
- m_logger->log(LOG_ERROR, LOC_WRITE_1, "filesystem is readonly");
- rc = EC_FS_READ_ONLY;
- } else {
- if (offset == 0) {
- if (m_writeFile != NULL)
- fclose(m_writeFile);
- QString fn = fullName(node);
- if ((m_writeFile = fopen(fn.toUtf8().constData(), "wb")) == NULL) {
- m_logger->logv(LOG_ERROR, LOC_WRITE_2,
- "cannot open for writing (%d): %s", errno,
- fn.toUtf8().constData());
- rc = EC_NOT_WRITEABLE;
- }
- }
- if (m_writeFile != NULL) {
- int64_t position = ReFileUtils::tell(m_writeFile);
- if (position != offset) {
- rc = EC_POSITION;
- m_logger->logv(LOG_ERROR, LOC_WRITE_4,
- "wrong file position: %lld/%lld", offset, position);
- } else {
- int nWritten = fwrite(buffer.constData(), 1, buffer.length(),
- m_writeFile);
- if (nWritten != buffer.length()) {
- m_logger->logv(LOG_ERROR, LOC_WRITE_3,
- "cannot write (%d): %s written: %d/%d", errno,
- node.toUtf8().constData(), nWritten, buffer.length());
- rc = EC_WRITE;
- }
- fflush(m_writeFile);
- }
- }
- }
- return rc;
-}
-
/**
* Constructor.
*/
return *this;
}
+/**
+ * Constructor.
+ *
+ * @param metaData the meta data of the file
+ */
+ReLocalLeafFile::ReLocalLeafFile(const ReFileMetaData& metaData,
+ const QString& fullName, ReLogger* logger) :
+ ReLeafFile(metaData, fullName, logger),
+ m_fp(NULL)
+{
+}
+
+/**
+ * Destructor.
+ */
+ReLocalLeafFile::~ReLocalLeafFile(){
+}
+
+/**
+ * Opens a file for reading or writing.
+ *
+ * @param writeable <code>true</code>: open for writing
+ * @return EC_SUCCESS: success<br>
+ * EC_CANNOT_OPEN: opening failed
+ */
+ReFileSystem::ErrorCode ReLocalLeafFile::open(bool writeable){
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ if ( (m_fp = fopen(m_fullName.toUtf8().constData(),
+ writeable ?"wb" : "rb")) == NULL){
+ rc = ReFileSystem::EC_NOT_EXISTS;
+ m_logger->logv(LOG_ERROR, LOC_OPEN_1, "cannot open: %s",
+ m_fullName.toUtf8().constData());
+ }
+ return rc;
+}
+
+/** Frees the resources occupied by <code>open()</code>.
+ *
+ * @return EC_SUCCESS: success
+ */
+ReFileSystem::ErrorCode ReLocalLeafFile::close(){
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ if (m_fp != NULL){
+ fclose(m_fp);
+ m_fp = NULL;
+ }
+ return rc;
+}
+/**
+ * Reads data from the current position into a buffer.
+ *
+ * @param size number of bytes to read
+ * @param buffer OUT: content of the file
+ * @return EC_SUCCESS: success<br>
+ * EC_INVALID_STATE: file not open
+ */
+ReFileSystem::ErrorCode ReLocalLeafFile::read(int maxSize,
+ QByteArray& buffer){
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ if (m_fp == NULL){
+ rc = ReFileSystem::EC_INVALID_STATE;
+ } else {
+ maxSize = min(maxSize, m_meta.m_size - ftell(m_fp));
+ buffer.resize(maxSize);
+ int nRead = 0;
+ if ( (nRead = fread(buffer.data(), 1, maxSize, m_fp)) != maxSize){
+ rc = ReFileSystem::EC_READ;
+ m_logger->logv(LOG_ERROR, LOC_READ_1, "cannnot read %s (%d): %d/%d",
+ m_fullName.toUtf8().constData(), errno, nRead, maxSize);
+ }
+ }
+ return rc;
+}
+
+/**
+ * Writes a buffer to a file at the current position.
+ *
+ * @param buffer content to write
+ * @return EC_SUCCESS or error code
+ */
+ReFileSystem::ErrorCode ReLocalLeafFile::write(const QByteArray& buffer){
+ ReFileSystem::ErrorCode rc = ReFileSystem::EC_SUCCESS;
+ if (m_fp == NULL){
+ rc = ReFileSystem::EC_INVALID_STATE;
+ } else {
+ int nWritten = 0;
+ int nToWrite = buffer.length();
+ if ( (nWritten = fwrite(buffer.constData(), 1, nToWrite, m_fp)) != nToWrite){
+ rc = ReFileSystem::EC_WRITE;
+ m_logger->logv(LOG_ERROR, LOC_WRITE_1, "cannnot read %s (%d): %d/%d",
+ m_fullName.toUtf8().constData(), errno, nWritten, nToWrite);
+ }
+ }
+ return rc;
+}
+
+
+/**
+ * Constructor.
+ *
+ * @param metaData metadata of the file
+ * @param fullName filename with path
+ * @param logger the logger
+ */
+ReLeafFile::ReLeafFile(const ReFileMetaData& metaData, const QString& fullName,
+ ReLogger* logger) :
+ m_fullName(fullName),
+ m_logger(logger),
+ m_meta(metaData)
+{
+}
+
+/**
+ * Destructor.
+ */
+ReLeafFile::~ReLeafFile()
+{
+}
+
+
};
typedef QList<ReFileMetaData> ReFileMetaDataList;
+class ReLeafFile;
+/**
+ * Base class of file systems.
+ *
+ * A file system is a hierarchical set of directories with exact one root
+ * (dirctory). Each directory can contain files and directories.
+ */
class ReFileSystem {
public:
enum ListOptions {
EC_MARKER,
EC_DIR_ALREADY_EXISTS,
EC_REMOTE_MKDIR,
+ EC_CANNOT_OPEN,
+ EC_INVALID_STATE,
+ EC_ALREADY_EXISTS,
};
public:
ReFileSystem(const QString& name, ReLogger* logger);
virtual ~ReFileSystem();
public:
+ /** Creates a new file in the current directory.
+ * @param node the name of the new file
+ * @param inDirectoryOnly <code>false</code>: the file is made physically<br>
+ * otherwise: the file exists only in the metadata
+ * of the directory
+ * @param metadata OUT: NULL or the metadata of the new file
+ * @return EC_SUCCESS or the error code
+ */
+ virtual ErrorCode createFile(const QString& node, bool inDirectoryOnly,
+ ReFileMetaData* metadata = NULL) = 0;
+ /**
+ * Returns a filesystem dependent instance of a file.
+ *
+ * The file must exist in the current directory.
+ * The caller must free the instance.
+ *
+ * @param meta the metadata of the file
+ * @return NULL: no file found<br>
+ * otherwise: the file
+ */
+ virtual ReLeafFile* buildFile(const ReFileMetaData& meta) = 0;
/** Returns the canonical form of a given path.
* @param path path to convert
* @return all nodes of the parts which are links are replaced by its
* link targets
*/
virtual QString canonicalPathOf(const QString& path) = 0;
- /** Frees resources like open files.
- */
- virtual void close() = 0;
/** Returns the name of the current directory.
* @return the name of the current directory
*/
* @return EC_SUCCESS or error code
*/
virtual ErrorCode makeDir(const QString& node) = 0;
- /** Reads a part of a file into a buffer.
- * @param source the file to read (inside the current directory)
- * @param offset first position to read
- * @param size number of bytes to read
- * @param buffer OUT: content of the file
- * @return EC_SUCCESS or error code
- */
- virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
- int size, QByteArray& buffer) = 0;
/** Removes a file or directory.
* @param node the properties ot the node (in the current directory)
* @return EC_SUCCESS or error code
*/
virtual ErrorCode setProperties(const ReFileMetaData& source,
ReFileMetaData& target, bool force) = 0;
- /** Writes a buffer to a file.
- * @param target the file to write (without path, inside the current directory)
- * @param offset first position to write
- * @param buffer content to write
- * @return EC_SUCCESS or error code
- */
- virtual ErrorCode write(const QString& target, int64_t offset,
- const QByteArray& buffer) = 0;
public:
+ /** Returns a filesystem dependent instance of a file.
+ *
+ * The file must exist in the current directory.
+ * The caller must free the instance.
+ *
+ * @param node the filename without path
+ * @return NULL: no file found<br>
+ * otherwise: the file
+ */
+ ReLeafFile* buildFile(const QString& node) {
+ ReFileMetaData meta;
+ return exists(node, &meta) ? buildFile(meta) : NULL;
+ }
+
virtual ErrorCode copy(ReFileMetaData& source, ReFileSystem& sourceFS);
virtual QString errorMessage(ErrorCode rc);
public:
ReOSPermissions m_osPermissions;
};
+/**
+ * An abstract base class for leafs of the tree spanned by a filesystem.
+ *
+ * A leaf file could not be a directory.
+ */
+class ReLeafFile : public ReFileMetaData{
+public:
+ ReLeafFile(const ReFileMetaData& metaData, const QString& fullName,
+ ReLogger* logger);
+ virtual ~ReLeafFile();
+public:
+ /** Opens a file for reading or writing.
+ * @param writeable <code>true</code>: open for writing
+ * @return EC_SUCCESS: success<br>
+ * otherwise: the error code
+ */
+ virtual ReFileSystem::ErrorCode open(bool writeable) = 0;
+ /** Frees the resources occupied by <code>open()</code>.
+ * @return EC_SUCCESS: success<br>
+ * otherwise: the error code
+ */
+ virtual ReFileSystem::ErrorCode close() = 0;
+ /** Reads data from the current position into a buffer.
+ * @param maxSize number of bytes to read
+ * @param buffer OUT: content of the file
+ * @return EC_SUCCESS or error code
+ */
+ virtual ReFileSystem::ErrorCode read(int maxSize, QByteArray& buffer) = 0;
+ /** Writes a buffer to a file at the current position.
+ * @param buffer content to write
+ * @return EC_SUCCESS or error code
+ */
+ virtual ReFileSystem::ErrorCode write(const QByteArray& buffer) = 0;
+protected:
+ QString m_fullName;
+ ReLogger* m_logger;
+ ReFileMetaData m_meta;
+};
+
+
+/**
+ * An abstract base class for leafs of the tree spanned by a filesystem.
+ *
+ * A leaf file could not be a directory.
+ */
+class ReLocalLeafFile : public ReLeafFile{
+public:
+ ReLocalLeafFile(const ReFileMetaData& metaData, const QString& fullName,
+ ReLogger* logger);
+ virtual ~ReLocalLeafFile();
+public:
+ virtual ReFileSystem::ErrorCode open(bool writeable);
+ virtual ReFileSystem::ErrorCode close();
+ virtual ReFileSystem::ErrorCode read(int maxSize, QByteArray& buffer);
+ virtual ReFileSystem::ErrorCode write(const QByteArray& buffer);
+protected:
+ FILE* m_fp;
+};
+
class ReLocalFileSystem: public ReFileSystem {
public:
ReLocalFileSystem(const QString& basePath, ReLogger* logger);
ErrorCode setDirectory(const QString& path);
public:
+ /** Returns a file instance of the local filesystem.
+ * @param meta the metadata of the file
+ * @return NULL: not found<br>
+ * otherwise: the file
+ */
+ virtual ReLeafFile* buildFile(const ReFileMetaData& meta){
+ return new ReLocalLeafFile(meta, fullName(meta.m_node), m_logger);
+ }
/** Returns the canonical form of a given path.
* @param path path to convert
* @return all nodes of the parts which are links are replaced by its
* link targets
*/
virtual QString canonicalPathOf(const QString& path);
- // ReFileSystem interface
- virtual void close();
+ virtual ErrorCode createFile(const QString& node, bool inDirectoryOnly,
+ ReFileMetaData* metadata = NULL);
virtual bool exists(const QString& node, ReFileMetaData* metaData = NULL) const;
virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
ReFileMetaDataList& list, ListOptions options);
- ErrorCode makeDir(const QString& node);
- virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
- int size, QByteArray& buffer);
- ErrorCode remove(const ReFileMetaData& node);
- ErrorCode setProperties(const ReFileMetaData& source,
+ virtual ErrorCode makeDir(const QString& node);
+ virtual ErrorCode remove(const ReFileMetaData& node);
+ virtual ErrorCode setProperties(const ReFileMetaData& source,
ReFileMetaData& target, bool force = false);
- virtual ErrorCode write(const QString& target, int64_t offset,
- const QByteArray& buffer);
protected:
QString m_basePath;
QDir m_dir;
- FILE* m_readFile;
- FILE* m_writeFile;
+
};
+
+
#endif /* OS_REFILESYSTEM_HPP_ */