m_fileSizes(0L) {
}
+/**
+ * Appends a relative path to base directory name (absolute or relative).
+ *
+ * @param base the base directory, relative or absolute
+ * @param path a relative path (relative to <code>base</code>)
+ * @return <code>path</code> if it is an absolute path<br>
+ * otherwise: the combined path
+ */
+QString ReFileUtils::pathAppend(const QString& base, const QString& path) {
+ QString rc;
+ if (isAbsolutPath(path))
+ rc = path;
+ else if (!base.isEmpty())
+ rc = QDir::cleanPath(base + OS_SEPARATOR + path);
+ else {
+ rc = path;
+ rc.replace("\\", "/");
+ if (path.startsWith("/"))
+ rc.remove(0, 1);
+ }
+ return rc;
+}
+
+/**
+ * Appends a relative path to base directory name (absolute or relative).
+ *
+ * @param base the base directory, relative or absolute
+ * @param path a relative path (relative to <code>base</code>)
+ * @return <code>path</code> if it is an absolute path<br>
+ * otherwise: the combined path
+ */
+QByteArray ReFileUtils::pathAppend(const char* base, const char* path) {
+ QByteArray rc;
+ if (base[0] != '\0') {
+ rc.append(base).append(OS_SEPARATOR).append(path);
+ } else {
+ rc = path;
+ }
+ return rc = cleanPath(rc);
+}
+
/**
* Delete a directory tree.
*
}
return rc;
}
+
+/**
+ * Extracts the extension of a filename.
+ *
+ * The extension is the last part of a node separated by a '.'.
+ * The separator '.' in part of the extension.
+ * If the node starts with the only dot the extension is empty.
+ *
+ * Works with '/' and with '\\'.
+ *
+ * @param filename the filename (with or without path)
+ * @return "": no extension found<br>
+ * otherwise: the extension of <code>filename</code>
+ */
+QString ReFileUtils::extensionOf(const QString& filename) {
+ QString rc;
+ int ix = max(0, filename.size() - 1);
+ QChar cc;
+ while (ix > 0) {
+ if ((cc = filename.at(ix)) == QChar('.')) {
+ if ((cc = filename.at(ix - 1)) != '/' && cc != '\\')
+ rc = filename.mid(ix);
+ break;
+ } else if (cc == QChar('\\') || cc == QChar('/'))
+ break;
+ ix--;
+ }
+ return rc;
+}
+
+/**
+ * Extracts the extension of a filename.
+ *
+ * The extension is the last part of a node separated by a '.'.
+ * The separator '.' in part of the extension.
+ * If the node starts with the only dot the extension is empty.
+ *
+ * Works with '/' and with '\\'.
+ *
+ * @param filename the filename (with or without path)
+ * @return "": no extension found<br>
+ * otherwise: the extension of <code>filename</code>
+ */
+QByteArray ReFileUtils::extensionOf(const char* filename) {
+ QByteArray rc;
+ if (filename[0] != '\0') {
+ size_t ix = strlen(filename) - 1;
+ char cc;
+ while (ix > 0) {
+ if ((cc = filename[ix]) == '.') {
+ if ((cc = filename[ix - 1]) != '/' && cc != '\\')
+ rc.append(filename + ix);
+ break;
+ } else if (cc == '\\' or cc == '/')
+ break;
+ ix--;
+ }
+ }
+ return rc;
+}
+
/**
* Returns whether a path is an absolute path.
*
return rc;
}
+/**
+ * Extracts the node of a filename.
+ *
+ * The node is the filename without path.
+ *
+ * @param filename the filename (with or without path)
+ * @return the node of <code>filename</code>
+ */
+QString ReFileUtils::nodeOf(const QString& filename) {
+ QString rc;
+
+ int ix = filename.size() - 1;
+ while (ix >= 0) {
+ if (filename[ix] == '/' || filename[ix] == '\\') {
+ rc = filename.mid(ix + 1);
+ break;
+ }
+ ix--;
+ }
+ if (ix < 0)
+ rc = filename;
+ return rc;
+}
+
+/**
+ * Extracts the node of a filename.
+ *
+ * The node is the filename without path.
+ *
+ * @param filename the filename (with or without path)
+ * @return the node of <code>filename</code>
+ */
+QByteArray ReFileUtils::nodeOf(const char* filename) {
+ QByteArray rc;
+ int ix = (int) strlen(filename) - 1;
+ while (ix >= 0) {
+ if (filename[ix] == '/' || filename[ix] == '\\') {
+ rc.append(filename + ix + 1);
+ break;
+ }
+ ix--;
+ }
+ if (ix < 0)
+ rc = filename;
+ return rc;
+}
+
+/** Normalizes a file path.
+ *
+ * Removes duplicated slashes and "." and "..", but not leading ".."
+ *
+ * @param path path to clean
+ * @return the path without duplicated separators and "." and ".."
+ */
+QByteArray ReFileUtils::cleanPath(const char* path) {
+ QByteArray rc;
+ int length = strlen(path);
+ rc.reserve(length);
+ int minLength = 0;
+#ifdef __WIN32__
+ // UNC path, e.g. "\\server\share"?
+ if (path[0] == OS_SEPARATOR && path[1] == OS_SEPARATOR) {
+ rc.append("\\\\");
+ path += 2;
+ minLength = 2;
+ }
+#endif
+ const char* ptr;
+ if (path[0] == OS_SEPARATOR) {
+ rc.append(OS_SEPARATOR);
+ path++;
+ }
+ while ((ptr = strchr(path, OS_SEPARATOR)) != NULL) {
+ // ignore duplicated slashes:
+ if (ptr != path) {
+ int length = ptr - path;
+ if (length == 1 && path[0] == '.') {
+ // ignore ".": do nothing
+ } else if (length == 2 && path[0] == '.' && path[1] == '.') {
+ // remove the last slash and node
+ if (rc.size() > minLength) {
+ rc.resize(rc.size() - 1);
+ int ix = rc.lastIndexOf(OS_SEPARATOR);
+ if (ix > minLength)
+ rc.resize(ix + 1);
+ }
+
+ } else {
+ // copy with separator:
+ rc.append(path, length + 1);
+ }
+
+ }
+ path = ptr + 1;
+ }
+ if (path[0] != '\0') {
+ if (path[0] == '.' && path[1] == '\0') {
+ if (rc.size() == 0)
+ rc.append('.');
+ } else if (path[0] == '.' && path[1] == '.' && path[3] == '\0') {
+ // remove the last slash and node
+ if (rc.size() > minLength) {
+ rc.resize(rc.size() - 1);
+ int ix = rc.lastIndexOf(OS_SEPARATOR);
+ if (ix > minLength)
+ rc.resize(ix);
+ }
+ } else {
+ // copy with separator:
+ rc.append(path);
+ }
+ }
+ return rc;
+}
+
/**
* Reads a string from a given file.
*
return buffer;
}
+/**
+ * Replaces the file extension of a filename.
+ *
+ * @param path the filename to change
+ * @param ext the new file extension, e.g. ".txt"
+ * @return path with a new file extension
+ */
+
+QString ReFileUtils::replaceExtension(const QString& path, const QString& ext) {
+ QString oldExt = extensionOf(path);
+ QString rc;
+ if (oldExt.isEmpty())
+ rc = path + ext;
+ else
+ rc = path.mid(0, path.size() - oldExt.size()) + ext;
+ return rc;
+}
+/**
+ * Replaces the file extension of a filename.
+ *
+ * @param path the filename to change
+ * @param ext the new file extension, e.g. ".txt"
+ * @return path with a new file extension
+ */
+
+QByteArray ReFileUtils::replaceExtension(const char* path, const char* ext) {
+ QByteArray oldExt = extensionOf(path);
+ QByteArray rc;
+ if (oldExt.isEmpty())
+ rc.append(path).append(ext);
+ else {
+ size_t length = strlen(path);
+ size_t lengthExt = strlen(ext);
+ rc.reserve(length - oldExt.size() + lengthExt);
+ rc.append(path, length - oldExt.size());
+ rc.append(ext);
+ }
+ return rc;
+}
/**
* Sets the filetimes.
*
temp.resize(temp.length() - 1);
return temp;
}
+/**
+ * @brief Returns the name of a directory in the temp dir.
+ *
+ * If the named directory does not exist it will be created.
+ *
+ * @param node NULL or the node (name without path)
+ * @param parent NULL or a node of the parent
+ * @param withSeparator true: the result ends with slash/backslash
+ * @return the name of an existing directory
+ */
+QByteArray ReFileUtils::tempDirEmpty(const char* node, const char* parent,
+ bool withSeparator) {
+ QByteArray rc = tempDir(node, parent, withSeparator);
+ deleteTree(rc, false, NULL);
+ return rc;
+}
/**
* @brief Returns a name of a file in a temporary directory.
public:
static bool deleteTree(const QString& path, bool withBase,
ReLogger* logger);
+ static QByteArray cleanPath(const char* path);
+ static QString extensionOf(const QString& filename);
+ static QByteArray extensionOf(const char* filename);
static bool isAbsolutPath(const QString& path);
static bool isAbsolutPath(const char* path);
+ static QString nodeOf(const QString& filename);
+ static QByteArray nodeOf(const char* filename);
+ static QString pathAppend(const QString& base, const QString& path);
+ static QByteArray pathAppend(const char* base, const char* path);
static QByteArray& readFromFile(const char* filename, QByteArray& buffer);
+ static QString replaceExtension(const QString& path, const QString& ext);
+ static QByteArray replaceExtension(const char* path, const char* ext);
static int seek(FILE* file, int64_t offset, int whence);
static bool setTimes(const char* filename, const QDateTime& modified,
const QDateTime& accessed = m_undefinedTime, ReLogger* logger = NULL);
static int64_t tell(FILE* file);
static QByteArray tempDir(const char* node, const char* parent = NULL,
bool withSeparator = true);
+ static QByteArray tempDirEmpty(const char* node, const char* parent = NULL,
+ bool withSeparator = true);
static QByteArray tempFile(const char* node, const char* parent = NULL,
bool deleteIfExists = true);
static void writeToFile(const char* filename, const char* content,
return value;
}
-/**
- * Extracts the extension of a filename.
- *
- * @param filename the filename (with or without path)
- * @return "": no extension found<br>
- * otherwise: the extension of <code>filename</code>
- */
-ReString ReQStringUtils::extensionOf(const ReString& filename) {
- QString rc;
- int index = filename.lastIndexOf('.');
- int index2 = 0;
- if (index > 0) {
- index2 = filename.lastIndexOf('/');
- if (index2 >= 0) {
- if (index > index2)
- rc = filename.mid(index);
- } else {
-#if defined __linux__
- rc = filename.mid(index);
-#elif defined WIN32
- index2 = filename.lastIndexOf('\\');
- if (index2 < 0 || index > index2)
- rc = filename.mid(index);
-#endif
- }
- }
- return rc;
-}
-
/**
* @brief Determines the length and vlaue of an integer.
*
return found ? ix - start : 0;
}
-/**
- * Extracts the node of a filename.
- *
- * The node is the filename without path.
- *
- * @param filename the filename (with or without path)
- * @return the node of <code>filename</code>
- */
-ReString ReQStringUtils::nodeOf(const ReString& filename) {
- QString rc;
-
- int index = filename.lastIndexOf('/');
- if (index >= 0)
- rc = filename.mid(index + 1);
- else {
-#if defined WIN32
- index = filename.lastIndexOf('\\');
- if (index < 0)
- rc = filename;
- else
- rc = filename.mid(index + 1);
-#endif
- }
- return rc;
-}
-
-/**
- * Appends a relative path to base directory name (absolute or relative).
- *
- * @param base the base directory, relative or absolute
- * @param toAdd a relative path (relative to <code>base</code>)
- * @return the combined path
- */
-QString ReQStringUtils::pathAppend(const QString& base, const QString& path) {
- QString rc;
- if (!base.isEmpty())
- rc = QDir::cleanPath(base + QDir::separator() + path);
- else {
- rc = path;
- rc.replace("\\", "/");
- if (path.startsWith("/"))
- rc.remove(0, 1);
- }
- return rc;
-}
-
-/**
- * Replaces the file extension of a filename.
- *
- * @param path the filename to change
- * @param ext the new file extension, e.g. ".txt"
- * @return path with a new file extension
- */
-
-QString ReQStringUtils::replaceExtension(const QString& path,
- const QString& ext) {
- QString oldExt = extensionOf(path);
- QString rc;
- if (oldExt.isEmpty())
- rc = path + ext;
- else
- rc = path.mid(0, path.size() - oldExt.size()) + ext;
- return rc;
-}
/**
* Replaces placeholders by their values.
*
static ReString chomp(const ReString& text);
static int countOf(const QString& value, QChar toFind, int start = 0);
static QString& ensureLastChar(QString& value, QChar lastChar);
- static ReString extensionOf(const ReString& filename);
+ static QString extensionOf(const QString& filename);
+ static QByteArray extensionOf(const char* filename);
static int lengthOfDate(const ReString& text, int start = 0, QDate* value =
NULL);
static int lengthOfDateTime(const ReString& text, int start = 0,
return path;
#endif
}
- static ReString nodeOf(const ReString& filename);
- static QString pathAppend(const QString& base, const QString& path);
- static QString replaceExtension(const QString& path, const QString& ext);
static bool replacePlaceholders(QString& text,
const QMap<QString, QString>& placeholders, QString* error);
static void skipExpected(const ReString& text, QChar expected, int& index,
class TestReFileSystem: public ReTest {
public:
TestReFileSystem() :
- ReTest("ReFileSystem") {
+ ReTest("ReFileSystem") {
doIt();
}
private:
QByteArray m_base;
QByteArray m_subDir1;
protected:
- void init(){
+ void init() {
m_base = ReFileUtils::tempDir("refilesystem");
m_subDir1 = ReFileUtils::tempDir("dir1", "refilesystem");
ReFileUtils::tempDir("dir2", "refilesystem");
QString node;
- for (int ix = 1; ix <= 7; ix++){
+ for (int ix = 1; ix <= 7; ix++) {
node.sprintf("test%d.txt", ix);
QByteArray fn = ReFileUtils::tempFile(node.toUtf8().constData(),
- "refilesystem", false);
+ "refilesystem", false);
ReFileUtils::writeToFile(fn.constData(), node.toUtf8().constData());
fn = m_subDir1;
fn.append("text").append(QByteArray::number(ix));
}
ReFileUtils::tempFile("abc.txt", "refilesytem", true);
}
- void testContains(const char* name, ReFileMetaDataList nodes){
+ void testContains(const char* name, ReFileMetaDataList nodes) {
bool rc = false;
ReFileMetaDataList::const_iterator it;
- for (it = nodes.cbegin(); it != nodes.cend(); ++it){
+ for (it = nodes.cbegin(); it != nodes.cend(); ++it) {
if ((*it).m_node == name)
rc = true;
}
- if (! rc)
+ if (!rc)
checkT(rc);
}
checkEqu(QString(m_base), fs.basePath());
ReFileMetaDataList nodes;
ReIncludeExcludeMatcher matcher(ReListMatcher::allMatchingList(),
- ReQStringUtils::m_emptyList, Qt::CaseInsensitive, false);
+ ReQStringUtils::m_emptyList, Qt::CaseInsensitive, false);
fs.listInfos(matcher, nodes);
testContains("dir1", nodes);
testContains("test1.txt", nodes);
testContains("test7.txt", nodes);
}
- void testReadWrite(){
+ void testReadWrite() {
ReLocalFileSytem fs(m_base, &m_logger);
QByteArray buffer;
buffer.append("abcdefghijklmnopqrstuvwxyz");
ReFileMetaDataList nodes;
QStringList names;
names.append("abc.txt");
- ReIncludeExcludeMatcher matcher(names,
- ReQStringUtils::m_emptyList, Qt::CaseInsensitive, true);
+ ReIncludeExcludeMatcher matcher(names, ReQStringUtils::m_emptyList,
+ Qt::CaseInsensitive, true);
checkEqu(1, fs.listInfos(matcher, nodes));
checkEqu(1, nodes.size());
checkEqu(0, fs.read(nodes.at(0), 0LL, 3, buffer2));
checkEqu(0, fs.read(nodes.at(0), 10LL, 99, buffer2));
checkEqu("klmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", buffer2);
}
- void testCopy(){
+ void testSetProperties() {
+ ReLocalFileSytem fs(m_base, &m_logger);
+ ReFileMetaData meta1;
+ const char* trgNode = "later.txt";
+ ReFileUtils::tempFile(trgNode, "refilesystem", true);
+ QDateTime modified = QDateTime::fromString("2015.09.12 11:44:55.765",
+ "yyyy.MM.dd hh:mm:ss.zzz");
+ ReFileMetaData meta2(trgNode, modified, ReFileUtils::m_undefinedTime,
+ -1, -1, (mode_t) - 1, 1);
+ checkT(fs.first("test1.txt", meta1));
+ checkEqu(0, fs.setProperties(meta2, meta1, true));
+ ReFileMetaData meta3;
+ checkT(fs.first(trgNode, meta3));
+ checkEqu(meta3.m_modified, modified);
+ }
+ void testSetPropertiesOwner() {
+#ifdef __linux__
+ if (geteuid() == 0) {
+ ReLocalFileSytem fs(m_base, &m_logger);
+ ReFileMetaData meta1;
+ ReFileUtils::tempFile("later2.txt", "refilesystem", true);
+ int rights = S_IRUSR | S_IWGRP | S_IRGRP| S_IROTH | S_IWOTH;
+ QDateTime modified = QDateTime::fromString("2015.08.13 10:34:55.765",
+ "yyyy.MM.dd hh:mm:ss:zzz");
+ ReFileMetaData meta2("later2.txt",
+ modified, ReFileUtils::m_undefinedTime,
+ 1001, 1002, rights, 1);
+ checkT(fs.first("test2.txt", meta1));
+ checkEqu(0, fs.setProperties(meta2, meta1, true));
+ ReFileMetaData meta3;
+ checkT(fs.first("later2.txt", meta3));
+ checkEqu(meta3.m_modified, modified);
+ checkEqu(meta3.m_owner, 1001);
+ checkEqu(meta3.m_group, 1002);
+ checkEqu(meta3.m_mode & ALLPERMS, rights);
+ }
+#endif
+
+ }
+ void compareMeta(ReFileMetaData& meta1, ReFileMetaData& meta2) {
+ checkEqu(meta1.m_node, meta2.m_node);
+ checkEqu(meta1.m_modified, meta2.m_modified);
+ checkEqu((int ) meta1.m_mode, (int ) meta2.m_mode);
+ checkEqu(meta1.m_group, meta2.m_group);
+ checkEqu(meta1.m_owner, meta2.m_owner);
+ checkEqu(meta1.m_size, meta2.m_size);
+ }
+ void testCopy() {
+ ReLocalFileSytem fsSource(m_base, &m_logger);
+ QByteArray base2 = ReFileUtils::tempDir("refilesystem.trg", NULL,
+ false);
+ ReFileUtils::deleteTree(base2, false, &m_logger);
+ ReLocalFileSytem fsTarget(base2, &m_logger);
+ ReFileMetaData metaSource;
+ checkT(fsSource.first("test3.txt", metaSource));
+ checkEqu(0, fsTarget.copy(metaSource, fsSource));
+ ReFileMetaData metaTarget;
+ checkT(fsTarget.first("test3.txt", metaTarget));
+ compareMeta(metaSource, metaTarget);
+ checkEqu(0, fsTarget.makeDir("dir.01"));
+ checkEqu(0, fsTarget.setDirectory("dir.01"));
+ checkEqu(0, fsTarget.copy(metaSource, fsSource));
+ QString path = fsTarget.fullName(metaSource.m_node);
+ checkT(path.indexOf("dir.01"));
+ struct stat info;
+ checkEqu(0, stat(path.toUtf8().constData(), &info));
}
virtual void run() {
init();
testReListInfos();
+ testSetProperties();
+ testSetPropertiesOwner();
+ testCopy();
testReadWrite();
}
};
class TestReFileUtils: public ReTest {
public:
TestReFileUtils() :
- ReTest("ReFileUtils") {
+ ReTest("ReFileUtils") {
doIt();
}
checkEqu(0, stat(dir, &info));
checkT(S_ISDIR(info.st_mode));
}
+ void testTempDirEmpty() {
+ QByteArray dir(
+ ReFileUtils::tempDirEmpty("subdir2", "cuReFileUtils", true));
+ QByteArray subdir(dir);
+ subdir.append("subdirX");
+ mkdir(subdir.constData(), ALLPERMS);
+ struct stat info;
+ checkEqu(0, stat(subdir.constData(), &info));
+ ReFileUtils::tempDirEmpty("subdir2", "cuReFileUtils", true);
+ checkEqu(-1, stat(subdir.constData(), &info));
+ }
void testWriteRead() {
QByteArray fn(ReFileUtils::tempFile("node.txt", "subdir", true));
ReFileUtils::writeToFile(fn, "123");
ReFileUtils::readFromFile(fn, content);
checkEqu("ab", content);
}
- QByteArray buildTree(){
+ QByteArray buildTree() {
QByteArray base = ReFileUtils::tempDir("ReFileUtils");
- for (char cc = 'a'; cc < 'f'; cc++){
+ for (char cc = 'a'; cc < 'f'; cc++) {
QByteArray subdir(base + cc);
mkdir(subdir.constData(), ALLPERMS);
- for (char cc2 = '1'; cc2 < '5'; cc2++){
- QByteArray name( subdir);
+ for (char cc2 = '1'; cc2 < '5'; cc2++) {
+ QByteArray name(subdir);
name.append(OS_SEPARATOR_STR).append(&cc2, 1);
ReFileUtils::writeToFile(name, name);
name += "dir";
base.remove(base.length() - 1, 1);
return base;
}
- void testDeleteTree(){
+ void testDeleteTree() {
QByteArray base = buildTree();
checkT(ReFileUtils::deleteTree(QString(base), false, &m_logger));
struct stat info;
checkT(ReFileUtils::deleteTree(QString(base), false, &m_logger));
checkEqu(0, stat(base, &info));
}
- void testIsAbsolutePath(){
+ void testIsAbsolutePath() {
#ifdef __linux__
checkT(ReFileUtils::isAbsolutPath("/abc/def/xyz.123"));
checkT(ReFileUtils::isAbsolutPath("/"));
#endif
checkF(ReFileUtils::isAbsolutPath(""));
}
- void testSeekTell(){
+ void testSeekTell() {
QByteArray fn(ReFileUtils::tempFile("seektest.txt", NULL, false));
ReFileUtils::writeToFile(fn.constData(), "0123456789");
FILE* fp = fopen(fn.constData(), "rb");
checkNN(fp);
- if (fp != NULL){
+ if (fp != NULL) {
checkEqu(0LL, ReFileUtils::tell(fp));
checkEqu(0, ReFileUtils::seek(fp, 3, SEEK_SET));
checkEqu(3LL, ReFileUtils::tell(fp));
checkEqu(0, ReFileUtils::seek(fp, -2, SEEK_END));
checkEqu(8LL, ReFileUtils::tell(fp));
}
+ }
+ void testSetTimes() {
+ QByteArray fn(ReFileUtils::tempFile("timetest.txt", NULL, true));
+ ReFileUtils::writeToFile(fn.constData(), "");
+ QDateTime time = QDateTime::fromString("03.09.2015 07:14:24.432",
+ "dd.MM.yyyy hh:mm:ss.zzz");
+ checkT(
+ ReFileUtils::setTimes(fn.constData(), time,
+ ReFileUtils::m_undefinedTime, &m_logger));
+ QFileInfo info(fn);
+ checkEqu(time, info.lastModified());
+ }
+ void testCleanPath() {
+#if defined __linux__
+ // no change:
+ checkEqu("/x/y/z.x", ReFileUtils::cleanPath("/x/y/z.x"));
+ checkEqu("x/y/z.x", ReFileUtils::cleanPath("./x/y/z.x"));
+ checkEqu("x/y/z.x/", ReFileUtils::cleanPath("x/y/z.x/"));
+ // remove duplicated slashes:
+ checkEqu("x/y/z.x/", ReFileUtils::cleanPath("x//y/////z.x//"));
+ // remove "./"
+ checkEqu("x/y/z.x", ReFileUtils::cleanPath("./x/././y/z.x"));
+ // remove "..":
+ // inside...
+ checkEqu("x/y/a/b", ReFileUtils::cleanPath("x/y/z/../a/b"));
+ checkEqu("x/a/b", ReFileUtils::cleanPath("x/y/z/../../a/b"));
+ // at the end..
+ checkEqu("x", ReFileUtils::cleanPath("x/y/z/../.."));
+ // wrong forms:
+ checkEqu("..", ReFileUtils::cleanPath(".."));
+ checkEqu("../..", ReFileUtils::cleanPath("../.."));
+ checkEqu("..", ReFileUtils::cleanPath("../x/.."));
+
+#elif defined __WIN32__
+#error "not implemented"
+#endif
+ }
+ void checkExtensionOf(const char* expected, const char* arg1, int lineNo) {
+ assertEquals(QString(expected), ReFileUtils::extensionOf(QString(arg1)),
+ __FILE__, lineNo);
+ assertEquals(expected, ReFileUtils::extensionOf(QString(arg1)),
+ __FILE__, lineNo);
+ QByteArray exp(expected);
+ QByteArray sArg1(arg1);
+ exp.replace("/", "\\");
+ sArg1.replace("/", "\\");
+ assertEquals(QString(exp), ReFileUtils::extensionOf(QString(sArg1)),
+ __FILE__, lineNo);
+ assertEquals(exp.constData(),
+ ReFileUtils::extensionOf(sArg1.constData()),
+ __FILE__, lineNo);
+ }
+
+ void testExtensionOf() {
+ checkExtensionOf("", "", __LINE__);
+ // full path
+ checkExtensionOf(".x", "/abc/def.x", __LINE__);
+ // prior node with extension too:
+ checkExtensionOf(".xyz", "/abc.z/def.xyz", __LINE__);
+ // sizeof (ext) == 2:
+ checkExtensionOf(".x", "/abc.z/def.xx.x", __LINE__);
+ // sizeof (ext) == 1:
+ checkExtensionOf(".x", "def.x", __LINE__);
+ checkExtensionOf(".", "def.", __LINE__);
+ // empty extension:
+ checkExtensionOf("", "/abc.x/def", __LINE__);
+ // empty last node:
+ checkExtensionOf("", "/abc.x/", __LINE__);
+ // node starting with "."
+ checkExtensionOf("", "/abc.x/.x", __LINE__);
+ checkExtensionOf("", ".xyz", __LINE__);
+ // Special:
+ checkExtensionOf("", "", __LINE__);
+ }
+ void checkNodeOf(const char* expected, const char* toTest, int lineNo) {
+ assertEquals(QString(expected), ReFileUtils::nodeOf(QString(toTest)),
+ __FILE__, lineNo);
+ assertEquals(expected, ReFileUtils::nodeOf(QString(toTest)),
+ __FILE__, lineNo);
+ QByteArray exp(expected);
+ QByteArray toTst(toTest);
+ exp.replace("/", "\\");
+ toTst.replace("/", "\\");
+ assertEquals(QString(exp), ReFileUtils::nodeOf(QString(toTst)),
+ __FILE__, lineNo);
+ assertEquals(exp, ReFileUtils::nodeOf(toTst.constData()),
+ __FILE__, lineNo);
+ }
+
+ void testNodeOf() {
+ checkNodeOf("abc.def", "/abc.def", __LINE__);
+ checkNodeOf("abc.def", "abc.def", __LINE__);
+ checkNodeOf("abc.def", "x/y/abc.def", __LINE__);
+ checkNodeOf("abc", "x/y/abc", __LINE__);
+ checkNodeOf("", "", __LINE__);
+ }
+
+ void checkPathAppend(const char* expected, const char* arg1,
+ const char* arg2, int lineNo) {
+ assertEquals(QString(expected),
+ ReFileUtils::pathAppend(QString(arg1), QString(arg2)),
+ __FILE__, lineNo);
+ assertEquals(expected, ReFileUtils::pathAppend(arg1, arg2),
+ __FILE__, lineNo);
+ QByteArray exp(expected);
+ QByteArray sArg1(arg1);
+ QByteArray sArg2(arg2);
+ exp.replace("/", "\\");
+ sArg1.replace("/", "\\");
+ sArg2.replace("/", "\\");
+ assertEquals(QString(exp),
+ ReFileUtils::pathAppend(QString(sArg1), QString(sArg2)),
+ __FILE__, lineNo);
+ assertEquals(exp,
+ ReFileUtils::pathAppend(sArg1.constData(), sArg2.constData()),
+ __FILE__, lineNo);
}
+ void testPathAppend() {
+ // no base:
+ checkPathAppend("abc/def", "", "abc/def", __LINE__);
+ checkPathAppend("abc/def", NULL, "abc/def", __LINE__);
+ // abs path:
+ checkPathAppend("/abc/def", "", "/abc/def", __LINE__);
+ checkPathAppend("/abc/def", NULL, "/abc/def", __LINE__);
+ checkPathAppend("/abc/def", "xyz", "/abc/def", __LINE__);
+ // true combination:
+ checkPathAppend("/abc/bef", "/abc", "bef", __LINE__);
+ checkPathAppend("/abc/bef", "/abc/", "bef", __LINE__);
+ checkPathAppend("/abc", "/", "bef", __LINE__);
+ }
+ void checkReplaceExt(const char* expected, const char* arg1,
+ const char* arg2, int lineNo) {
+ assertEquals(QString(expected),
+ ReFileUtils::replaceExtension(QString(arg1), QString(arg2)),
+ __FILE__, lineNo);
+ assertEquals(expected, ReFileUtils::replaceExtension(arg1, arg2),
+ __FILE__, lineNo);
+ QByteArray exp(expected);
+ QByteArray sArg1(arg1);
+ QByteArray sArg2(arg2);
+ exp.replace("/", "\\");
+ sArg1.replace("/", "\\");
+ sArg2.replace("/", "\\");
+ assertEquals(QString(exp),
+ ReFileUtils::replaceExtension(QString(sArg1), QString(sArg2)),
+ __FILE__, lineNo);
+ assertEquals(exp,
+ ReFileUtils::replaceExtension(sArg1.constData(), sArg2.constData()),
+ __FILE__, lineNo);
+
+ }
+ void testReplaceExtension() {
+ checkReplaceExt("/abc/def.123", "/abc/def.xyz", ".123", __LINE__);
+ checkReplaceExt("def.123", "def.xyz", ".123", __LINE__);
+ checkReplaceExt("/abc.1/def.123", "/abc.1/def.xyz", ".123", __LINE__);
+ checkReplaceExt("/abc.1/def.123", "/abc.1/def", ".123", __LINE__);
+ }
virtual void run() {
+ testReplaceExtension();
+ testNodeOf();
+ testExtensionOf();
+ testCleanPath();
+ testSetTimes();
testSeekTell();
testIsAbsolutePath();
testDeleteTree();
class TestReQStringUtil: public ReTest {
public:
TestReQStringUtil() :
- ReTest("ReQStringUtil") {
+ ReTest("ReQStringUtil") {
doIt();
}
void testLengthOfUInt64() {
quint64 value = -3;
checkEqu(1,
- ReQStringUtils::lengthOfUInt64(ReString("0"), 0, 10, &value));
+ ReQStringUtils::lengthOfUInt64(ReString("0"), 0, 10, &value));
checkEqu(int64_t(0), value);
checkEqu(3, ReQStringUtils::lengthOfUInt64("x432", 1, 10, &value));
checkEqu(int64_t(432LL), value);
checkEqu(3, ReQStringUtils::lengthOfUInt64("x432 x", 1, 10, &value));
checkEqu(int64_t(432LL), value);
checkEqu(3,
- ReQStringUtils::lengthOfUInt64("x432fabc x", 1, 10, &value));
+ ReQStringUtils::lengthOfUInt64("x432fabc x", 1, 10, &value));
checkEqu(int64_t(432LL), value);
checkEqu(16,
- ReQStringUtils::lengthOfUInt64("a1234567890123567", 1, 10, &value));
+ ReQStringUtils::lengthOfUInt64("a1234567890123567", 1, 10, &value));
checkEqu(int64_t(1234567890123567LL), value);
checkEqu(10,
- ReQStringUtils::lengthOfUInt64("x1234abcdef", 1, 16, &value));
+ ReQStringUtils::lengthOfUInt64("x1234abcdef", 1, 16, &value));
checkEqu(int64_t(0x1234abcdefLL), value);
checkEqu(3, ReQStringUtils::lengthOfUInt64("432", 0, 8, &value));
checkEqu(int64_t(0432LL), value);
checkEqu(1, ReQStringUtils::lengthOfReal(ReString(" 0"), 1, &value));
checkEqu(0.0, value);
checkEqu(17,
- ReQStringUtils::lengthOfReal(ReString("X12345678901234567"), 1,
- &value));
+ ReQStringUtils::lengthOfReal(ReString("X12345678901234567"), 1,
+ &value));
checkEqu(12345678901234567.0, value);
checkEqu(2, ReQStringUtils::lengthOfReal(ReString(".5"), 0, &value));
checkEqu(0.5, value);
checkEqu(5,
- ReQStringUtils::lengthOfReal(ReString("2.5e2x"), 0, &value));
+ ReQStringUtils::lengthOfReal(ReString("2.5e2x"), 0, &value));
checkEqu(250.0, value);
checkEqu(6,
- ReQStringUtils::lengthOfReal(ReString("2.5e+2"), 0, &value));
+ ReQStringUtils::lengthOfReal(ReString("2.5e+2"), 0, &value));
checkEqu(250.0, value);
checkEqu(7,
- ReQStringUtils::lengthOfReal(ReString("2.5E-33"), 0, &value));
+ ReQStringUtils::lengthOfReal(ReString("2.5E-33"), 0, &value));
checkEqu(2.5e-33, value);
checkEqu(3, ReQStringUtils::lengthOfReal(ReString("2.5E"), 0, &value));
checkEqu(3, ReQStringUtils::lengthOfReal(ReString("2.5E+"), 0, &value));
checkEqu(2.5, value);
checkEqu(3,
- ReQStringUtils::lengthOfReal(ReString("2.5E-a"), 0, &value));
+ ReQStringUtils::lengthOfReal(ReString("2.5E-a"), 0, &value));
checkEqu(2.5, value);
}
ReString name = "Heinz Müller";
char buffer[32];
checkEqu("Heinz Müller",
- ReQStringUtils::utf8(name, buffer, sizeof buffer));
+ ReQStringUtils::utf8(name, buffer, sizeof buffer));
memset(buffer, 'x', sizeof buffer);
checkEqu("Heinz", ReQStringUtils::utf8(name, buffer, (size_t)(5 + 1)));
checkEqu(buffer[6], 'x');
* @param name the name of the filesystem
*/
ReFileSystem::ReFileSystem(const QString& name, ReLogger* logger) :
- m_name(name),
- m_writeable(false),
- m_logger(logger),
- m_buffer(),
- m_blocksize(4 * 1024 * 1024),
- m_undefinedTime() {
+ m_name(name),
+#ifdef __linux__
+ m_uid(geteuid()),
+ m_gid(getegid()),
+#endif
+ m_writeable(false),
+ m_logger(logger),
+ m_buffer(),
+ m_blocksize(4 * 1024 * 1024),
+ m_undefinedTime() {
}
*
*/
ReFileSystem::ErrorCode ReFileSystem::copy(ReFileMetaData& source,
- ReFileSystem& sourceFS) {
+ ReFileSystem& sourceFS) {
int blocksize = min(m_blocksize, sourceFS.blocksize());
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)
+ != EC_SUCCESS)
rc = rc2;
else if ((rc2 = write(source.m_node, size, m_buffer)) != EC_SUCCESS)
rc = rc2;
}
close();
sourceFS.close();
+ ReFileMetaData target(source.m_node, ReFileUtils::m_undefinedTime,
+ ReFileUtils::m_undefinedTime, m_uid, m_gid);
+ setProperties(source, target, false);
return rc;
}
+/**
+ * Returns the name of the current directory.
+ *
+ * @return the name of the current directory
+ */
+const QString& ReFileSystem::directory() const {
+ return m_directory;
+}
+
/**
* Returns whether the filesystem is writeable.
*
QStringList names;
names.append(pattern);
ReIncludeExcludeMatcher matcher(names, ReQStringUtils::m_emptyList,
- Qt::CaseInsensitive, true);
+ Qt::CaseInsensitive, true);
listInfos(matcher, list);
bool rc = list.size() > 0;
if (rc)
* @param logger
*/
ReLocalFileSytem::ReLocalFileSytem(const QString& basePath, ReLogger* logger) :
- ReFileSystem("localfs", logger),
- m_basePath(basePath),
- m_currentPath(basePath),
- m_dir(basePath),
- m_readFile(NULL),
- m_writeFile(NULL) {
+ ReFileSystem("localfs", logger),
+ m_basePath(basePath),
+ m_dir(basePath),
+ m_readFile(NULL),
+ m_writeFile(NULL) {
+ m_directory = basePath;
+ ReQStringUtils::ensureLastChar(m_directory, OS_SEPARATOR);
setWriteable(true);
}
}
}
-/**
- * Returns the name of the current directory.
- *
- * @return the name of the current directory
- */
-const QString& ReLocalFileSytem::directory() const {
- return m_currentPath;
-}
-
/**
* Fills a list with the items of the current directory.
*
* @return the count of the found entries (<code>list.size()</code>)
*/
int ReLocalFileSytem::listInfos(const ReIncludeExcludeMatcher& matcher,
- ReFileMetaDataList& list) {
+ ReFileMetaDataList& list) {
list.clear();
const QStringList& patterns = matcher.includes().patterns();
QStringList nodes =
- patterns.size() == 0 ? m_dir.entryList() : m_dir.entryList(patterns);
+ patterns.size() == 0 ? m_dir.entryList() : m_dir.entryList(patterns);
QStringList::const_iterator it;
- QByteArray full = m_currentPath.toUtf8();
+ QByteArray full = m_directory.toUtf8();
full.append(OS_SEPARATOR);
int pathLength = full.length();
struct stat info;
full.append(node.toUtf8());
if (stat(full.constData(), &info) == 0) {
list.append(
- ReFileMetaData(node, QDateTime::fromTime_t(info.st_mtime),
- QDateTime::fromTime_t(info.st_ctime), info.st_uid,
- info.st_gid, info.st_mode, info.st_size));
+ ReFileMetaData(node, QDateTime::fromTime_t(info.st_mtime),
+ QDateTime::fromTime_t(info.st_ctime), info.st_uid,
+ info.st_gid, info.st_mode, info.st_size));
}
}
return list.size();
rc = EC_FS_READ_ONLY;
} else if (m_dir.exists(node)) {
m_logger->logv(LOG_ERROR, LOC_MAKE_DIR_2, "node exists already: %s",
- fullNameAsUTF8(node).constData());
+ fullNameAsUTF8(node).constData());
rc = EC_ALREADY_EXISTS;
} else if (!m_dir.mkdir(node)) {
m_logger->logv(LOG_ERROR, LOC_MAKE_DIR_2, "cannot create directory: %s",
- fullNameAsUTF8(node).constData());
+ fullNameAsUTF8(node).constData());
rc = EC_NOT_ACCESSIBLE;
}
return rc;
*/
ReFileSystem::ErrorCode ReLocalFileSytem::setDirectory(const QString& path) {
ErrorCode rc = m_dir.setCurrent(path) ? EC_SUCCESS : EC_PATH_NOT_FOUND;
- m_currentPath = m_dir.absolutePath();
+ m_directory = m_dir.absolutePath();
+ ReQStringUtils::ensureLastChar(m_directory, OS_SEPARATOR);
return rc;
}
* EC_READ: error while reading
*/
ReFileSystem::ErrorCode ReLocalFileSytem::read(const ReFileMetaData& source,
- int64_t offset, int size, QByteArray& buffer) {
+ int64_t offset, int size, QByteArray& buffer) {
ErrorCode rc = EC_SUCCESS;
if (offset == 0) {
if (m_readFile != NULL)
fclose(m_readFile);
- QString fn = m_currentPath + source.m_node;
+ 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());
+ "cannot open for reading (%d): %s", errno,
+ fn.toUtf8().constData());
rc = EC_NOT_READABLE;
}
}
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());
+ source.m_node.toUtf8().constData());
nRead = 0;
rc = EC_READ;
}
rc = EC_FS_READ_ONLY;
} else if (!m_dir.exists(node.m_node)) {
m_logger->logv(LOG_ERROR, LOC_REMOVE_2, "node does not exists: %s",
- fullNameAsUTF8(node.m_node).constData());
+ fullNameAsUTF8(node.m_node).constData());
rc = EC_NOT_EXISTS;
} else {
if (S_ISDIR(node.m_mode)) {
if (!m_dir.rmdir(node.m_node)) {
m_logger->logv(LOG_ERROR, LOC_REMOVE_3,
- "cannot remove directory: %s",
- fullNameAsUTF8(node.m_node).constData());
+ "cannot remove directory: %s",
+ fullNameAsUTF8(node.m_node).constData());
rc = EC_NOT_ACCESSIBLE;
}
} else {
if (!m_dir.remove(node.m_node)) {
m_logger->logv(LOG_ERROR, LOC_REMOVE_3,
- "cannot remove file: %s",
- fullNameAsUTF8(node.m_node).constData());
+ "cannot remove file: %s",
+ fullNameAsUTF8(node.m_node).constData());
rc = EC_NOT_ACCESSIBLE;
}
}
*
* @param source the properties to copy
* @param target the properties of the file to change
+ * @param force <code>true</code>: try to change rights to enable other changes<br>
+ * <code>false</code>: current rights will be respected
* @return EC_SUCCESS: successful<br>
* EC_FS_READ_ONLY: filesystem is readonly<br>
* EC_ALREADY_EXISTS: renaming failed: target node exists already<br>
*
*/
ReFileSystem::ErrorCode ReLocalFileSytem::setProperties(
- const ReFileMetaData& source, const ReFileMetaData& target) {
+ const ReFileMetaData& source, ReFileMetaData& target,
+ bool force) {
ErrorCode rc = EC_SUCCESS;
if (!m_writeable) {
m_logger->log(LOG_ERROR, LOC_SET_PROPERTIES_1,
- "filesystem is readonly");
+ "filesystem is readonly");
rc = EC_FS_READ_ONLY;
} else
do {
- if (target.m_node != source.m_node) {
+ QByteArray name;
+ bool nameChanged = target.m_node != source.m_node;
+ bool timeChanged = source.m_modified != target.m_modified
+ && source.m_modified != ReFileUtils::m_undefinedTime;
+#ifdef __linux__
+ bool modeChanged = (source.m_mode & ALLPERMS) != (target.m_mode & ALLPERMS)
+ && source.m_mode != (mode_t) -1;
+ bool ownerChanged = (source.m_owner != target.m_owner
+ && source.m_owner != -1)
+ || (source.m_group != source.m_group
+ && source.m_group != -1);
+ if (force && m_uid != 0 && (nameChanged || timeChanged || modeChanged
+ || ownerChanged)){
+ name = fullNameAsUTF8(target.m_node);
+ chmod(name.constData(), ALLPERMS);
+ modeChanged = true;
+ }
+
+#endif
+ if (nameChanged) {
if (m_dir.exists(source.m_node)) {
+ if (name.length() == 0)
+ name = fullNameAsUTF8(target.m_node);
rc = EC_ALREADY_EXISTS;
m_logger->logv(LOG_ERROR, LOC_SET_PROPERTIES_2,
- "renaming impossible: node exists: %s",
- fullNameAsUTF8(target.m_node).constData());
+ "renaming impossible: node exists: %s",
+ name.constData());
break;
} else if (!m_dir.rename(target.m_node, source.m_node)) {
rc = EC_RENAME;
+ if (name.length() == 0)
+ name = fullNameAsUTF8(target.m_node);
m_logger->logv(LOG_ERROR, LOC_SET_PROPERTIES_3,
- "renaming impossible: %s -> %s",
- source.m_node.toUtf8().constData(),
- fullNameAsUTF8(target.m_node).constData());
+ "renaming impossible: %s -> %s",
+ source.m_node.toUtf8().constData(),
+ name.constData());
break;
+ } else {
+ name.resize(0);
+ target.m_node = source.m_node;
}
}
- QByteArray name;
- if (source.m_modified != target.m_modified
- && source.m_modified != ReFileUtils::m_undefinedTime) {
+ if (timeChanged) {
if (name.length() == 0)
name = fullNameAsUTF8(target.m_node);
if (!ReFileUtils::setTimes(name.constData(), source.m_modified,
- ReFileUtils::m_undefinedTime, m_logger))
+ ReFileUtils::m_undefinedTime, m_logger))
rc = EC_NOT_ACCESSIBLE;
}
#ifdef __linux__
- if (source.m_mode != target.m_mode
- && source.m_mode != (mode_t) -1) {
- if (chmod(name.constData(), source.m_mode) != 0) {
- rc = EC_NOT_ACCESSIBLE;
- m_logger->logv(LOG_ERROR, LOC_SET_PROPERTIES_4,
- "changing permissions is impossible: %s",
- name.constData());}
- }
- if ( (source.m_owner != target.m_owner
- && source.m_owner != -1)
- || (source.m_group != source.m_group
- && source.m_group != -1)) {
+ if (ownerChanged) {
int uid = source.m_owner == -1 ? target.m_owner : source.m_owner;
int gid = source.m_group == -1 ? target.m_group : source.m_group;
if (name.length() == 0)
name.constData());
}
}
+ if (modeChanged) {
+ mode_t mode = source.m_mode == (mode_t) -1
+ ? target.m_mode : source.m_mode;
+ if (chmod(name.constData(), mode & ALLPERMS) != 0) {
+ rc = EC_NOT_ACCESSIBLE;
+ m_logger->logv(LOG_ERROR, LOC_SET_PROPERTIES_4,
+ "changing permissions is impossible: %s",
+ name.constData());}
+ }
#endif
} while (false);
return rc;
*
*/
ReFileSystem::ErrorCode ReLocalFileSytem::write(const QString& node,
- int64_t offset, const QByteArray& buffer) {
+ int64_t offset, const QByteArray& buffer) {
ErrorCode rc = EC_SUCCESS;
if (!writeable()) {
m_logger->log(LOG_ERROR, LOC_WRITE_1, "filesystem is readonly");
if (offset == 0) {
if (m_writeFile != NULL)
fclose(m_writeFile);
- QString fn = m_currentPath + node;
+ 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());
+ "cannot open for writing (%d): %s", errno,
+ fn.toUtf8().constData());
rc = EC_NOT_WRITEABLE;
}
}
if (position != offset) {
rc = EC_POSITION;
m_logger->logv(LOG_ERROR, LOC_WRITE_4,
- "wrong file position: %lld/%lld", offset, position);
+ "wrong file position: %lld/%lld", offset, position);
} else {
int nWritten = fwrite(buffer.constData(), 1, buffer.length(),
- m_writeFile);
+ 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());
+ "cannot write (%d): %s written: %d/%d", errno,
+ node.toUtf8().constData(), nWritten, buffer.length());
rc = EC_WRITE;
}
fflush(m_writeFile);
* Constructor.
*/
ReFileMetaData::ReFileMetaData() :
- m_node(),
- m_modified(),
- m_created(),
- m_owner(-1),
- m_group(-1),
- m_mode(-1),
- m_size(-1) {
+ m_node(),
+ m_modified(),
+ m_created(),
+ m_owner(-1),
+ m_group(-1),
+ m_mode(-1),
+ m_size(-1) {
}
* @param size the filesize (0 for directories)
*/
ReFileMetaData::ReFileMetaData(const QString& node, const QDateTime& modified,
- const QDateTime& created, int owner, int group, mode_t mode, int64_t size) :
- m_node(node),
- m_modified(modified),
- m_created(created),
- m_owner(owner),
- m_group(group),
- m_mode(mode),
- m_size(size) {
+ const QDateTime& created, int owner, int group, mode_t mode, int64_t size) :
+ m_node(node),
+ m_modified(modified),
+ m_created(created),
+ m_owner(owner),
+ m_group(group),
+ m_mode(mode),
+ m_size(size) {
}
* @param source source to copy
*/
ReFileMetaData::ReFileMetaData(const ReFileMetaData& source) :
- m_node(source.m_node),
- m_modified(source.m_modified),
- m_created(source.m_created),
- m_owner(source.m_owner),
- m_group(source.m_group),
- m_mode(source.m_mode),
- m_size(source.m_size) {
+ m_node(source.m_node),
+ m_modified(source.m_modified),
+ m_created(source.m_created),
+ m_owner(source.m_owner),
+ m_group(source.m_group),
+ m_mode(source.m_mode),
+ m_size(source.m_size) {
}
public:
ReFileMetaData();
ReFileMetaData(const QString& node, const QDateTime& modified,
- const QDateTime& created, int owner, int group, mode_t mode,
- int64_t size);
+ const QDateTime& created,
+ int owner = -1, int group = -1,
+ mode_t mode = (mode_t) -1, int64_t size = 0);
virtual ~ReFileMetaData();
ReFileMetaData(const ReFileMetaData& source);
ReFileMetaData& operator =(const ReFileMetaData& source);
/** Returns the name of the current directory.
* @return the name of the current directory
*/
- virtual const QString& directory() const = 0;
+ virtual const QString& directory() const;
/** Fills a list with the items of the current directory.
* @param matcher the matching processor
* @return the count of the found entries (<code>list.size()</code>)
*/
virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
- ReFileMetaDataList& list) = 0;
+ ReFileMetaDataList& list) = 0;
/** Creates a directory.
* @param node the name without path (in the current directory)
* @return EC_SUCCESS or error code
* @return EC_SUCCESS or error code
*/
virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
- int size, QByteArray& buffer) = 0;
+ 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
/** Sets the properties of a file in the current directory.
* @param source the properties to copy
* @param target the properties of the file to change
- * @return EC_SUCCESS or error code
+ * @param force <code>true</code>: try to change rights to enable
+ * other changes<br>
+ * <code>false</code>: current rights will be respected
+ * @return EC_SUCCESS or error code
*/
virtual ErrorCode setProperties(const ReFileMetaData& source,
- const ReFileMetaData& target) = 0;
+ ReFileMetaData& target, bool force) = 0;
/** Writes a buffer to a file.
* @param node the file to write (without path, inside the current directory)
* @param offset first position to write
* @return EC_SUCCESS or error code
*/
virtual ErrorCode write(const QString& target, int64_t offset,
- const QByteArray& buffer) = 0;
+ const QByteArray& buffer) = 0;
public:
virtual ErrorCode copy(ReFileMetaData& source, ReFileSystem& sourceFS);
public:
protected:
QString m_name;
+#ifdef __linux__
+ int m_uid;
+ int m_gid;
+#endif
+ // ending with OS_SEPARATOR:
QString m_directory;
bool m_writeable;
ReLogger* m_logger;
virtual ~ReLocalFileSytem();
public:
const QString& basePath() const;
- const QString& directory() const;
ErrorCode setDirectory(const QString& path);
public:
// ReFileSystem interface
virtual void close();
virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
- ReFileMetaDataList& list);
+ ReFileMetaDataList& list);
ErrorCode makeDir(const QString& node);
virtual ErrorCode read(const ReFileMetaData& source, int64_t offset,
- int size, QByteArray& buffer);
+ int size, QByteArray& buffer);
ErrorCode remove(const ReFileMetaData& node);
ErrorCode setProperties(const ReFileMetaData& source,
- const ReFileMetaData& target);
+ ReFileMetaData& target, bool force = false);
virtual ErrorCode write(const QString& target, int64_t offset,
- const QByteArray& buffer);
+ const QByteArray& buffer);
protected:
QString m_basePath;
- QString m_currentPath;
QDir m_dir;
-
FILE* m_readFile;
FILE* m_writeFile;