]> gitweb.hamatoma.de Git - reqt/commitdiff
ReFileSystem, memory leaks in ReEdit
authorhama <hama@siduction.net>
Mon, 21 Sep 2015 22:05:06 +0000 (00:05 +0200)
committerhama <hama@siduction.net>
Mon, 21 Sep 2015 22:05:06 +0000 (00:05 +0200)
16 files changed:
base/ReFileUtils.cpp
base/ReFileUtils.hpp
base/ReMatcher.cpp
base/ReMatcher.hpp
cunit/allTests.cpp
cunit/cuReFileSystem.cpp
cunit/cuReFileUtils.cpp
cunit/cuReMatcher.cpp
cunit/cuReQStringUtils.cpp
gui/ReEdit.cpp
gui/ReEdit.hpp
gui/ReSettings.cpp
gui/ReSettings.hpp
os/ReFileSystem.cpp
os/ReFileSystem.hpp
remodules.hpp

index ca78ec338de488a29ed3ac66bb980f6761cfcb41..c5f92862fb85ef4f54c1fb2029260722fa0d3cdd 100644 (file)
@@ -63,6 +63,43 @@ bool ReFileUtils::isAbsolutPath(const char* path)
        return rc;
 }
 
+/** Sets the read position of a file.
+ * @param file         file to process
+ * @param offset       the position. @see <code>whence</code>
+ * @param whence       SEEK_SET: offset is absolute (from file's start)
+ *                                     SEEK_END: offset is relative to the file' end
+ *                                     SEEK_CUR: offset is relative to the current position
+ * @return                     0: success<br>
+ *                                     otherwise: error code
+ */
+int ReFileUtils::seek(FILE* file, int64_t offset, int whence){
+       int rc;
+#if defined __linux__
+       rc = fseeko(file, offset, whence);
+#elif defined __WIN32__
+       rc = _fseek64(file, offset, whence);
+#endif
+       return rc;
+}
+
+/**
+ * Returns the current file position.
+ *
+ * @param file file to process
+ * @return     < 0: error occurred<br>
+ *                     otherwise: the current read/write position (from the file's start)
+ */
+int64_t ReFileUtils::tell(FILE* file)
+{
+       int64_t rc;
+#if defined __linux__
+       rc = ftello(file);
+#elif defined __WIN32__
+       rc = _ftell64(file);
+#endif
+       return rc;
+}
+
 /**
  * Delete a directory tree.
  *
index c8844b335e18e4f9f076a7d95993a5dc8ecdbcd1..d27181f18459806738e97539976b6d3f628aa249 100644 (file)
@@ -28,17 +28,18 @@ public:
  */
 class ReFileUtils {
 public:
+       static bool deleteTree(const QString& path, bool withBase, ReLogger* logger);
        static bool isAbsolutPath(const QString& path);
        static bool isAbsolutPath(const char* path);
+       static int seek(FILE* file, int64_t offset, int whence);
+       static int64_t tell(FILE* file);
        static QByteArray tempDir(const char* node, const char* parent = NULL,
-           bool withSeparator = true);
+               bool withSeparator = true);
        static QByteArray tempFile(const char* node, const char* parent = NULL,
-           bool deleteIfExists = true);
+               bool deleteIfExists = true);
        static QByteArray& readFromFile(const char* filename, QByteArray& buffer);
        static void writeToFile(const char* filename, const char* content,
-           size_t contentLength = (size_t) - 1, const char* mode = "w");
-       static bool deleteTree(const QString& path, bool withBase,
-           ReLogger* logger);
+               size_t contentLength = (size_t) - 1, const char* mode = "w");
 };
 
 #endif // REFILEUTILS_HPP
index 2d86b277dfe3116452e883cee37c22fc40fb967a..b32b218a185c08a34ab8af1c0fea43b7df2e3ade 100644 (file)
@@ -36,6 +36,7 @@ ReListMatcher* ReListMatcher::m_allMatcher = NULL;
 
 ReMatcher::ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensivity,
        bool anchored) :
+       m_pattern(),
                m_needles(),
                m_restLengths(),
                m_anchored(anchored),
@@ -50,20 +51,31 @@ ReMatcher::ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensivity,
  * @return             <code>true</code>: the pattern matches
  */
 bool ReMatcher::matches(const QString& text) {
-       bool found = m_needles.size() == 0;
-       if (!found) {
-               found =
-                       m_anchored ?
-                               text.startsWith(m_needles.at(0), m_caseSensivitiy) : true;
-               if (found) {
-                       int startIx = m_anchored ? 1 : 0;
-                       int textIndex = m_anchored ? m_needles.at(0).length() : 0;
-                       for (int ix = startIx; found && ix < m_needles.size(); ix++) {
-                               found = text.size() - textIndex >= m_restLengths.at(ix);
-                               if (found)
-                                       found = (textIndex = text.indexOf(m_needles.at(ix),
-                                               textIndex, m_caseSensivitiy)) >= 0;
-                       }
+       bool found = m_allMatching || m_needles.size() == 0;
+       int endIx = m_needles.size() - 1;
+       if (! found && m_anchored){
+               found = m_needles.at(0).size() == 0
+                               || text.startsWith(m_needles.at(0), m_caseSensivitiy);
+               if (found && (endIx > 0 || text.length() != m_pattern.length())){
+                       found = m_needles.at(endIx).size() == 0
+                                       || text.endsWith(m_needles.at(endIx), m_caseSensivitiy);
+               }
+       }
+       if (!found || m_anchored && endIx > 1) {
+               int startIx = 0;
+               int textIndex = 0;
+               if (! m_anchored)
+                       found = true;
+               else {
+                       startIx++;
+                       endIx--;
+                       textIndex = m_needles.at(0).length();
+               }
+               for (int ix = startIx; found && ix <= endIx; ix++) {
+                       found = text.size() - textIndex >= m_restLengths.at(ix);
+                       if (found)
+                               found = (textIndex = text.indexOf(m_needles.at(ix),
+                                                                                                 textIndex, m_caseSensivitiy)) >= 0;
                }
        }
        return found;
@@ -79,17 +91,14 @@ bool ReMatcher::matches(const QString& text) {
 void ReMatcher::setPattern(const QString& pattern, bool anchored) {
        m_anchored = anchored;
        m_allMatching = false;
+       m_pattern = pattern;
+       m_needles.clear();
        if (pattern.isEmpty())
                m_needles.clear();
        else {
-               if (pattern.startsWith("*")){
-                       m_anchored = false;
-                       if (pattern.length() == 1)
-                               m_allMatching = true;
-               }
                m_needles = pattern.split('*');
-               // Eliminate empty entries:
-               for (int ix = m_needles.size() - 1; ix >= 0; ix--) {
+               // Eliminate empty entries but not first and next:
+               for (int ix = m_needles.size() - 2; ix > 0; ix--) {
                        if (m_needles.at(ix).length() == 0)
                                m_needles.removeAt(ix);
                        else
@@ -103,6 +112,16 @@ void ReMatcher::setPattern(const QString& pattern, bool anchored) {
                }
        }
 }
+/**
+ * Returns the current pattern.
+ *
+ * @return     the current pattern
+ */
+const QString& ReMatcher::pattern() const
+{
+       return m_pattern;
+}
+
 /**
  * Returns whether the matcher accepts all strings (pattern "*").
  *
@@ -240,15 +259,17 @@ bool ReListMatcher::empty() const
 
 /**
  * Tests whether at least one pattern of the list matches the given text
+ *
  * @param text text to test
- * @return             <code>true</code>: one of the stored patterns matches the text<br>
+ * @return             <code>true</code>: empty list or one of the stored patterns
+ *                             matches the text<br>
  *                             <code>false</code>: none of the patterns matches
  */
 bool ReListMatcher::matches(const QString& text)
 {
        QList<ReMatcher*>::const_iterator it;
-       bool rc = false;
-       for (it = m_list.constBegin(); ! rc && it != m_list.cend(); ++it){
+       bool rc = m_list.size() == 0;
+       for (it = m_list.cbegin(); ! rc && it != m_list.cend(); ++it){
                rc = (*it)->matches(text);
        }
        return rc;
index 3ba8e8f023170883da1a943200f37437dbc95fae..0c5cb40c0bb82400c0f800813950f61b0a24c12d 100644 (file)
@@ -26,10 +26,13 @@ public:
        bool allMatching() const;
        Qt::CaseSensitivity caseSensivitiy() const;
        bool matches(const QString& text);
+       const QString& pattern() const;
        void setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy);
        void setPattern(const QString& pattern, bool anchored = false);
 
+
 protected:
+       QString m_pattern;
        QStringList m_needles;
        // m_restLengths[ix] = sum(m_needles[ix..last].size()
        QList<int> m_restLengths;
index ddd81692d6b288541eb33e27915b21d80fc1f4b6..cad6fc215e03ae2f4acc61d572d5fdec0cfee7bd 100644 (file)
@@ -89,6 +89,7 @@ static void testOs() {
        testReFileSystem();
 }
 void allTests() {
+       testOs();
        testBase();
        testGui();
        if (s_allTest) {
index 743d32e2d74446013abfaeae3b02f9ce10e2b570..2ed6ad69a6eabceb0bcd993b7071e745c4f1ab61 100644 (file)
@@ -39,23 +39,24 @@ protected:
                        fn.append("text").append(QByteArray::number(ix));
                        ReFileUtils::writeToFile(fn.constData(), fn.constData());
                }
+               ReFileUtils::tempFile("abc.txt", "refilesytem", true);
        }
-       void testContains(const char* name, QList<ReFileMetaData*> nodes){
+       void testContains(const char* name, ReFileMetaDataList nodes){
                bool rc = false;
-               QList<ReFileMetaData*>::const_iterator it;
+               ReFileMetaDataList::const_iterator it;
                for (it = nodes.cbegin(); it != nodes.cend(); ++it){
-                       if ((*it)->m_node == name)
+                       if ((*it).m_node == name)
                                rc = true;
                }
                if (! rc)
                        checkT(rc);
        }
 
-       void testReLocalFileSystem() {
-               ReLocalFileSytem fs(m_base);
+       void testReListInfos() {
+               ReLocalFileSytem fs(m_base, &m_logger);
                checkEqu(QString(m_base), fs.directory());
                checkEqu(QString(m_base), fs.basePath());
-               QList<ReFileMetaData*> nodes;
+               ReFileMetaDataList nodes;
                ReIncludeExcludeMatcher matcher(ReListMatcher::allMatchingList(),
                        ReQStringUtils::m_emptyList, Qt::CaseInsensitive, false);
                fs.listInfos(matcher, nodes);
@@ -63,9 +64,35 @@ protected:
                testContains("test1.txt", nodes);
                testContains("test7.txt", nodes);
        }
+       void testReadWrite(){
+               ReLocalFileSytem 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));
+               QByteArray buffer2;
+               ReFileMetaDataList nodes;
+               QStringList names;
+               names.append("abc.txt");
+               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("abc", 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("klmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", buffer2);
+       }
+       void testCopy(){
+
+       }
+
        virtual void run() {
                init();
-               testReLocalFileSystem();
+               testReListInfos();
+               testReadWrite();
        }
 };
 void testReFileSystem() {
index d6895b5c8e75aa9986d053a665ba795bd9223e75..2b033c190424ef8798cd70bcd73edc4f04cc0d6c 100644 (file)
@@ -97,8 +97,31 @@ public:
 #endif
                checkF(ReFileUtils::isAbsolutPath(""));
        }
+       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){
+                       checkEqu(0LL, ReFileUtils::tell(fp));
+                       checkEqu(0, ReFileUtils::seek(fp, 3, SEEK_SET));
+                       checkEqu(3LL, ReFileUtils::tell(fp));
+                       char cc;
+                       checkEqu(1, fread(&cc, 1, 1, fp));
+                       checkEqu('3', cc);
+                       checkEqu(4LL, ReFileUtils::tell(fp));
+
+                       checkEqu(0, ReFileUtils::seek(fp, -2, SEEK_CUR));
+                       checkEqu(2LL, ReFileUtils::tell(fp));
+
+                       checkEqu(0, ReFileUtils::seek(fp, -2, SEEK_END));
+                       checkEqu(8LL, ReFileUtils::tell(fp));
+               }
+
+       }
 
        virtual void run() {
+               testSeekTell();
                testIsAbsolutePath();
                testDeleteTree();
                testTempDir();
index 4321c28839c56ccdc84ea444485935dc51b4173f..b14aa71f1d70e1afa054aac6f43be5f31ae488cd 100644 (file)
@@ -23,7 +23,7 @@ public:
 
 public:
        void testBasics() {
-               ReMatcher m1("a*b*c", Qt::CaseSensitive, true);
+               ReMatcher m1("a*b*c*", Qt::CaseSensitive, true);
                checkT(m1.matches("a b c d"));
                checkT(m1.matches("abc d"));
                checkT(m1.matches("ababc"));
@@ -34,14 +34,15 @@ public:
                checkT(m2.matches("a b c d"));
                checkT(m2.matches("ababc"));
                checkT(m2.matches("a b a b c"));
-               checkT(m2.matches(" abc"));
+               checkT(m2.matches(" abc "));
                checkF(m2.matches(" ab"));
 
                ReMatcher m3("a**B*C", Qt::CaseInsensitive, true);
-               checkT(m3.matches("a b c d"));
-               checkT(m3.matches("abc d"));
+               checkT(m3.matches("a b C"));
+               checkT(m3.matches("ab c"));
                checkT(m3.matches("ababc"));
                checkT(m3.matches("abc"));
+               checkF(m3.matches("abcd"));
 
                ReMatcher m4("A*B*c", Qt::CaseInsensitive, false);
                checkT(m4.matches("a b c d"));
@@ -55,11 +56,107 @@ public:
                m4.setPattern("");
                checkT(m4.matches("any"));
        }
+       void test1Star(){
+               ReMatcher matcher("*abc", Qt::CaseSensitive, true);
+               checkT(matcher.matches("abc"));
+               checkF(matcher.matches("aBc"));
+               checkT(matcher.matches("xyzabc"));
+               checkF(matcher.matches("abc "));
+
+               matcher.setCaseSensivitiy(Qt::CaseInsensitive);
+               checkT(matcher.matches("abc"));
+               checkT(matcher.matches("aBc"));
+               checkT(matcher.matches("xyzabc"));
+               checkF(matcher.matches("abc "));
+
+               checkT(matcher.matches("AbC"));
+               checkT(matcher.matches("aBc"));
+               checkT(matcher.matches("xyzAbc"));
+               checkF(matcher.matches("abC "));
+
+               matcher.setPattern(matcher.pattern(), false);
+               matcher.setCaseSensivitiy(Qt::CaseSensitive);
+               checkT(matcher.matches("abc"));
+               checkF(matcher.matches("aBc"));
+               checkT(matcher.matches("xyzabc"));
+               checkT(matcher.matches("abc "));
+               checkT(matcher.matches("_abc_"));
+               checkF(matcher.matches("_a bc_"));
+
+               matcher.setCaseSensivitiy(Qt::CaseInsensitive);
+               checkT(matcher.matches("abc"));
+               checkT(matcher.matches("aBc"));
+               checkT(matcher.matches("xyzAbc"));
+               checkT(matcher.matches("aBc "));
+               checkT(matcher.matches("_abC_"));
+               checkF(matcher.matches("_a bc_"));
+
+               matcher.setPattern("x*y", true);
+               matcher.setCaseSensivitiy(Qt::CaseSensitive);
+               checkT(matcher.matches("x y"));
+               checkF(matcher.matches("X y"));
+               checkF(matcher.matches("x Y"));
+               checkT(matcher.matches("xy"));
+               checkF(matcher.matches("Xy"));
+               checkF(matcher.matches(" xy"));
+               checkF(matcher.matches("xy "));
+
+               matcher.setCaseSensivitiy(Qt::CaseInsensitive);
+               checkT(matcher.matches("X Y"));
+               checkT(matcher.matches("xY"));
+               checkT(matcher.matches("Xy"));
+               checkF(matcher.matches(" xy"));
+               checkF(matcher.matches("xy "));
+
+               matcher.setPattern(matcher.pattern(), false);
+               matcher.setCaseSensivitiy(Qt::CaseSensitive);
+               checkT(matcher.matches("x y"));
+               checkT(matcher.matches("ax y"));
+               checkT(matcher.matches("x y!"));
+               checkT(matcher.matches("123xyz!"));
+               checkF(matcher.matches("x"));
+               checkF(matcher.matches("xY"));
+               checkF(matcher.matches("Xy"));
+
+               matcher.setCaseSensivitiy(Qt::CaseInsensitive);
+               checkT(matcher.matches("X y"));
+               checkT(matcher.matches("aX y"));
+               checkT(matcher.matches("x Y!"));
+               checkT(matcher.matches("123XY!"));
+               checkF(matcher.matches("x"));
+               checkF(matcher.matches("xY"));
+               checkF(matcher.matches("Xy"));
+       }
+       void test0Star(){
+               ReMatcher matcher("abc", Qt::CaseSensitive, true);
+               checkT(matcher.matches("abc"));
+               checkF(matcher.matches("aBc"));
+               checkF(matcher.matches(" abc"));
+               checkF(matcher.matches("abc "));
+
+               checkT(matcher.caseSensivitiy());
+               matcher.setCaseSensivitiy(Qt::CaseInsensitive);
+               checkF(matcher.caseSensivitiy());
+
+               checkT(matcher.matches("abc"));
+               checkT(matcher.matches("aBc"));
+               checkF(matcher.matches(" aBc"));
+               checkF(matcher.matches("aBc "));
+
+               matcher.setPattern(matcher.pattern(), false);
+               matcher.setCaseSensivitiy(Qt::CaseSensitive);
+               checkT(matcher.matches("abc"));
+               checkF(matcher.matches("aBc"));
+               checkT(matcher.matches(" abc"));
+               checkT(matcher.matches("abc "));
+       }
+
        void testList(){
                QStringList patterns;
                patterns << "*.txt" << "*.doc";
                ReListMatcher matcher(patterns, Qt::CaseInsensitive, true);
                checkT(matcher.matches("README.TXT"));
+               checkF(matcher.matches("readme_txt"));
                checkT(matcher.matches("Xyz.Doc"));
                checkF(matcher.matches("a.doc.bak"));
 
@@ -70,6 +167,8 @@ public:
 
        virtual void run(void) {
                testBasics();
+               test0Star();
+               test1Star();
                testList();
        }
 };
index e3dd466042e7d4eb15442f7ebd41f9c54d27b3b2..0711f787a2d4ab0d511d9b09aa7497f1e2a6218a 100644 (file)
@@ -17,7 +17,7 @@
 class TestReQStringUtil: public ReTest {
 public:
        TestReQStringUtil() :
-                   ReTest("ReQStringUtil") {
+                       ReTest("ReQStringUtil") {
                doIt();
        }
 
@@ -35,20 +35,20 @@ public:
        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);
@@ -85,19 +85,19 @@ public:
                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));
@@ -105,7 +105,7 @@ public:
                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);
        }
 
@@ -128,7 +128,7 @@ public:
                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');
@@ -186,42 +186,8 @@ public:
                checkEqu(8, ReQStringUtils::lengthOfTime("301:02:09x", 1, &time));
                checkEqu(QTime(1, 2, 9), time);
        }
-       void testReMatcher() {
-               ReMatcher m1("a*b*c", Qt::CaseSensitive, true);
-               checkT(m1.matches("a b c d"));
-               checkT(m1.matches("abc d"));
-               checkT(m1.matches("ababc"));
-               checkT(m1.matches("abc"));
-               checkF(m1.matches("aBc"));
-
-               ReMatcher m2("a*b*c", Qt::CaseSensitive, false);
-               checkT(m2.matches("a b c d"));
-               checkT(m2.matches("ababc"));
-               checkT(m2.matches("a b a b c"));
-               checkT(m2.matches(" abc"));
-               checkF(m2.matches(" ab"));
-
-               ReMatcher m3("a**B*C", Qt::CaseInsensitive, true);
-               checkT(m3.matches("a b c d"));
-               checkT(m3.matches("abc d"));
-               checkT(m3.matches("ababc"));
-               checkT(m3.matches("abc"));
-
-               ReMatcher m4("A*B*c", Qt::CaseInsensitive, false);
-               checkT(m4.matches("a b c d"));
-               checkT(m4.matches("ababc"));
-               checkT(m4.matches("a b a b c"));
-               checkT(m4.matches(" abc"));
-               checkF(m4.matches(" ab"));
-
-               m4.setPattern("*");
-               checkT(m4.matches("x"));
-               m4.setPattern("");
-               checkT(m4.matches("any"));
-       }
 
        virtual void run(void) {
-               testReMatcher();
                testLengtOfTime();
                testLengtOfDate();
                testDateTimeParser();
index 3007ba89a653dd137eb9a6d6313dcf73e9acf47e..cedf156e43afac755c45329c627d3d25fd88fd94 100644 (file)
@@ -36,11 +36,11 @@ inline int heightToFullHeight(int height) {
  * @param edit          the parent
  */
 ReLook::ReLook() :
-           m_font(NULL),
-           m_metrics(NULL),
-           m_foreground(FG_STANDARD),
-           m_background(BG_STANDARD),
-           m_edit(NULL) {
+               m_font(NULL),
+               m_metrics(NULL),
+               m_foreground(FG_STANDARD),
+               m_background(BG_STANDARD),
+               m_edit(NULL) {
 }
 
 /**
@@ -50,8 +50,8 @@ ReLook::ReLook() :
  * @param look  the presentation of the text
  */
 ReEditText::ReEditText(const QString& text, ReLook* look) :
-           m_text(text),
-           m_look(look) {
+               m_text(text),
+               m_look(look) {
 
 }
 
@@ -64,7 +64,7 @@ ReEditText::ReEditText(const QString& text, ReLook* look) :
  * @param edit      the edit field (parent)
  */
 void ReCursortLineBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
-    ReEdit* edit) {
+       ReEdit* edit) {
        if (lineNo == edit->cursorLineNo()) {
                for (int ix = 0; ix < paragraph.length(); ix++) {
                        ReEditText* text = paragraph.at(ix);
@@ -100,32 +100,32 @@ void ReCursortLineBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
  * @param parent    NULL or a widget which destroy the instance
  */
 ReEdit::ReEdit(QWidget* parent) :
-           QWidget(parent),
-           ReMouseCatcher(),
-           m_widthEdit(0),
-           m_heightEdit(0),
-           m_insertMode(true),
-           m_breakLines(false),
-           m_widthLineNumbers(50),
-           m_widthVScrollBar(16),
-           m_heightHScrollBar(16),
-           m_looks(),
-           m_standardBrush(new QBrush(Qt::SolidPattern)),
-           m_scrollbarBrush(new QBrush(Qt::SolidPattern)),
-           m_sliderBrush(new QBrush(Qt::ConicalGradientPattern)),
-           m_brushColors(),
-           m_standardPen(new QPen(Qt::SolidLine)),
-           m_standardFont(NULL),
-           m_standardMetrics(NULL),
-           m_fontColors(),
-           m_keyAlt(),
-           m_keyAltControl(),
-           m_keyAltControlShift(),
-           m_keyAltShift(),
-           m_keyControl(),
-           m_keyControlShift(),
-           m_keyRaw(),
-           m_keyShift() {
+               QWidget(parent),
+               ReMouseCatcher(),
+               m_widthEdit(0),
+               m_heightEdit(0),
+               m_insertMode(true),
+               m_breakLines(false),
+               m_widthLineNumbers(50),
+               m_widthVScrollBar(16),
+               m_heightHScrollBar(16),
+               m_looks(),
+               m_standardBrush(new QBrush(Qt::SolidPattern)),
+               m_scrollbarBrush(new QBrush(Qt::SolidPattern)),
+               m_sliderBrush(new QBrush(Qt::ConicalGradientPattern)),
+               m_brushColors(),
+               m_standardPen(new QPen(Qt::SolidLine)),
+               m_standardFont(NULL),
+               m_standardMetrics(NULL),
+               m_fontColors(),
+               m_keyAlt(),
+               m_keyAltControl(),
+               m_keyAltControlShift(),
+               m_keyAltShift(),
+               m_keyControl(),
+               m_keyControlShift(),
+               m_keyRaw(),
+               m_keyShift() {
        setFocusPolicy(Qt::WheelFocus);
        m_standardFont = new QFont("Courier");
        m_standardFont->setStyleHint(QFont::TypeWriter);
@@ -145,6 +145,23 @@ ReEdit::ReEdit(QWidget* parent) :
        appendBuilder(new ReCursortLineBuilder());
        assignKeysStandard();
 }
+
+/**
+ * Destructor.
+ */
+ReEdit::~ReEdit()
+{
+       for (size_t ix = 0; ix < sizeof(m_fontColors) / sizeof m_fontColors[0]; ix++)
+               delete m_fontColors[ix];
+       for (size_t ix = 0; ix < sizeof(m_brushColors) / sizeof m_brushColors[0]; ix++)
+               delete m_brushColors[ix];
+       delete m_standardBrush;
+       delete m_scrollbarBrush;
+       delete m_sliderBrush;
+       delete m_standardPen;
+       delete m_standardFont;
+       delete m_standardMetrics;
+}
 /**
  * Assigns a standard version of colors to symbolic colors.
  */
@@ -230,7 +247,7 @@ void ReEdit::assignKeysStandard() {
  * @param length        OUT: the slider length in pixel
  */
 void calcSliderSize(int size, int minSize, double sizeFactor, double posFactor,
-    int& position, int& length) {
+       int& position, int& length) {
        if (sizeFactor > 1.0)
                sizeFactor = 1.0;
        if (posFactor > 100)
@@ -277,8 +294,8 @@ int ReEdit::cursorLineNo() const {
  * @param posHorizontal     the position of the scrollbar as factor [0..1]
  */
 void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect,
-    double sizeVertical, double posVertical, double sizeHorizontal,
-    double posHorizontal) {
+       double sizeVertical, double posVertical, double sizeHorizontal,
+       double posHorizontal) {
        // We paint the vertical scrollbar:
        QBrush brush(*m_brushColors[ReLook::BG_SCROLLBAR], Qt::SolidPattern);
        painter.setBrush(brush);
@@ -287,14 +304,14 @@ void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect,
        static int width = 1;
        static int width2 = 2 * width;
        m_vScrollBar->setRect(x + width2, rect.top(), m_widthVScrollBar - width2,
-           rect.height() - m_heightHScrollBar - width);
+               rect.height() - m_heightHScrollBar - width);
        painter.drawRect(*m_vScrollBar);
 
        // We paint the horizontal scrollbar:
        m_hScrollBar->setRect(rect.left() + m_widthLineNumbers,
-           rect.bottom() - m_heightHScrollBar + width,
-           rect.width() - m_widthVScrollBar - m_widthLineNumbers,
-           m_heightHScrollBar - width2);
+               rect.bottom() - m_heightHScrollBar + width,
+               rect.width() - m_widthVScrollBar - m_widthLineNumbers,
+               m_heightHScrollBar - width2);
        painter.drawRect(*m_hScrollBar);
 
        // Slider (vertical)
@@ -303,36 +320,36 @@ void ReEdit::drawScrollbars(QPainter& painter, const QRect& rect,
        int sliderSize = 0;
        int sliderPos = 0;
        calcSliderSize(rect.height() - m_heightHScrollBar, m_heightHScrollBar,
-           sizeVertical, posVertical, sliderPos, sliderSize);
+               sizeVertical, posVertical, sliderPos, sliderSize);
        m_vSlider->setRect(x + width2, rect.top() + sliderPos + width,
-           m_widthVScrollBar - width2, sliderSize - width2);
+               m_widthVScrollBar - width2, sliderSize - width2);
        painter.drawRect(*m_vSlider);
        int middle = m_vSlider->top() + m_vSlider->height() / 2;
        painter.drawLine(m_vSlider->left() + 2, middle, m_vSlider->right() - 2,
-           middle);
+               middle);
        middle -= m_heightHScrollBar / 2 - 2;
        painter.drawLine(m_vSlider->left() + 2, middle, m_vSlider->right() - 2,
-           middle);
+               middle);
        middle += m_heightHScrollBar - 4;
        painter.drawLine(m_vSlider->left() + 2, middle, m_vSlider->right() - 2,
-           middle);
+               middle);
        // Slider (horizontal)
        calcSliderSize(rect.width() - m_widthLineNumbers - m_widthVScrollBar,
-           m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos,
-           sliderSize);
+               m_heightHScrollBar, sizeHorizontal, posHorizontal, sliderPos,
+               sliderSize);
        m_hSlider->setRect(rect.left() + m_widthLineNumbers + sliderPos,
-           rect.bottom() - m_heightHScrollBar + width, sliderSize - width,
-           m_heightHScrollBar - width2);
+               rect.bottom() - m_heightHScrollBar + width, sliderSize - width,
+               m_heightHScrollBar - width2);
        painter.drawRect(*m_hSlider);
        middle = m_hSlider->left() + m_hSlider->width() / 2;
        painter.drawLine(middle, m_hSlider->top() + 2, middle,
-           m_hSlider->bottom() - 2);
+               m_hSlider->bottom() - 2);
        middle -= m_heightHScrollBar / 2 - 2;
        painter.drawLine(middle, m_hSlider->top() + 2, middle,
-           m_hSlider->bottom() - 2);
+               m_hSlider->bottom() - 2);
        middle += m_heightHScrollBar - 4;
        painter.drawLine(middle, m_hSlider->top() + 2, middle,
-           m_hSlider->bottom() - 2);
+               m_hSlider->bottom() - 2);
 }
 
 /**
@@ -420,7 +437,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) {
                        m_cursorCol = m_lines->lineAt(m_cursorLineNo - 1).length() - 1;
                }
                if (m_lines->removePart(m_cursorLineNo, columnToIndex(currentCol), 1,
-                   true))
+                       true))
                        m_cursorLineNo = max(0, m_cursorLineNo - 1);
 
                break;
@@ -429,7 +446,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) {
                int lastIx = lastColOfCurrent();
                if (m_cursorCol <= lastIx) {
                        m_lines->removePart(m_cursorLineNo, m_cursorCol + 1,
-                           lastIx - m_cursorCol, true);
+                               lastIx - m_cursorCol, true);
                        ensureCursorVisible();
                }
                break;
@@ -476,7 +493,7 @@ void ReEdit::editorAction(ReEdit::EditorAction action) {
  */
 void ReEdit::ensureCursorVisible() {
        if (m_cursorLineNo < m_firstLine
-           || m_cursorLineNo >= m_firstLine + pageSize()) {
+               || m_cursorLineNo >= m_firstLine + pageSize()) {
                reposition(m_cursorLineNo, m_cursorCol);
        }
        if (m_cursorCol < 0)
@@ -518,7 +535,7 @@ void ReEdit::keyPressEvent(QKeyEvent* event) {
                        break;
                }
        } else if (shift && !keyText.isEmpty() && key != Qt::Key_Delete
-           && key != Qt::Key_Backspace) {
+               && key != Qt::Key_Backspace) {
                m_lines->insertText(m_cursorLineNo, m_cursorCol + 1, keyText);
                m_cursorCol++;
        } else {
@@ -564,7 +581,7 @@ ReLines& ReEdit::lines() {
  * @return
  */
 ReLook* ReEdit::lookOf(ReLook::ForeGround foreground,
-    ReLook::BackGround background) {
+       ReLook::BackGround background) {
        int index = foreground * ReLook::BG_COUNT + background;
        ReLook* rc = m_looks[index];
        if (rc == NULL) {
@@ -591,8 +608,8 @@ ReLook* ReEdit::lookOf(ReLook::ForeGround foreground,
  */
 void ReEdit::mouseMoveEvent(QMouseEvent* event) {
        if (m_lastMousePosition.x() >= 0
-           && (handleHScrollBar(event, true, this)
-               || handleVScrollBar(event, true, this))) {
+               && (handleHScrollBar(event, true, this)
+                       || handleVScrollBar(event, true, this))) {
                emit repaint();
        }
 }
@@ -610,12 +627,12 @@ void ReEdit::mousePressEvent(QMouseEvent* event) {
        } else {
                QPoint position = event->pos();
                m_cursorLineNo = position.y()
-                   / heightToFullHeight(m_standardMetrics->height()) + m_firstLine;
+                       / heightToFullHeight(m_standardMetrics->height()) + m_firstLine;
                int x = position.x();
                int charWidth = m_standardMetrics->width('x');
                x -= m_widthLineNumbers;
                if (x >= 0
-                   && x < m_widthEdit - m_widthLineNumbers - m_widthVScrollBar) {
+                       && x < m_widthEdit - m_widthLineNumbers - m_widthVScrollBar) {
                        if (x <= +charWidth / 2)
                                m_cursorCol = m_firstCol - 1;
                        else
@@ -658,14 +675,14 @@ void ReEdit::paintEvent(QPaintEvent* event) {
        int pageSize = (rect.height() - m_heightHScrollBar) / lineHeight;
        int charWidth = m_standardMetrics->averageCharWidth();
        int pageWidth = (rect.width() - m_widthVScrollBar - m_widthLineNumbers)
-           / charWidth;
+               / charWidth;
        int firstLine = m_firstLine;
        load(firstLine, pageSize, pageWidth, this);
        QPainter painter(this);
        ReLook* look = lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
        painter.setBrush(*look->m_brush);
        QRect editArea(rect.left() + m_widthLineNumbers, rect.top(),
-           rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar);
+               rect.right() - m_widthVScrollBar, rect.bottom() - m_heightHScrollBar);
        // Painting the frame of the edit field:
        painter.drawRect(editArea);
        // Painting the edit field area (text...)
@@ -680,13 +697,13 @@ void ReEdit::paintEvent(QPaintEvent* event) {
        for (int ix = 0; ix < maxIx; ix++, lineNo++) {
                QString number = QString::number(lineNo);
                ReLook* look =
-                   lineNo == m_cursorLineNo + 1 ?
-                       lookOf(ReLook::FG_CURRENT_LINE, ReLook::BG_CURRENT_LINE) :
-                       lookStd;
+                       lineNo == m_cursorLineNo + 1 ?
+                               lookOf(ReLook::FG_CURRENT_LINE, ReLook::BG_CURRENT_LINE) :
+                               lookStd;
                int width = look->m_metrics->width(number);
                if (ix == 0)
                        y = rect.top() + look->m_metrics->height()
-                           - look->m_metrics->descent();
+                               - look->m_metrics->descent();
                painter.setFont(*look->m_font);
                painter.setPen(*look->m_pen);
                painter.drawText(left + m_widthLineNumbers - width - 5, y, number);
@@ -694,13 +711,13 @@ void ReEdit::paintEvent(QPaintEvent* event) {
        }
        // We paint the cursor:
        if (m_cursorVisible && m_cursorLineNo >= firstLine
-           && m_cursorLineNo < firstLine + pageSize) {
+               && m_cursorLineNo < firstLine + pageSize) {
                ReParagraph* cursorPara = cursorParagraph();
                int col = min(m_cursorCol, cursorPara->m_columns - 1);
                col = indexToColumn(col + 1, m_tabWidth,
-                   m_lines->lineAt(m_cursorLineNo)) - m_firstCol;
+                       m_lines->lineAt(m_cursorLineNo)) - m_firstCol;
                int x = rect.left() + m_widthLineNumbers + 1
-                   + col * lookStd->m_metrics->width('x');
+                       + col * lookStd->m_metrics->width('x');
                int y = rect.top() + (m_cursorLineNo - firstLine) * lineHeight;
                painter.setPen(*look->m_pen);
                painter.drawLine(x, y, x, y + lineHeight);
@@ -708,11 +725,11 @@ void ReEdit::paintEvent(QPaintEvent* event) {
        int maxLines = max(1, m_lines->lineCount() - pageSize);
 
        drawScrollbars(painter, rect, fraction(pageSize, maxLines, 1.0),
-           fraction(m_firstLine, maxLines, 0.0),
-           fraction(m_screenWidth, m_maxCols, 1.0),
-           fraction(m_firstCol, max(0, m_maxCols - m_screenWidth), 0.0));
+               fraction(m_firstLine, maxLines, 0.0),
+               fraction(m_screenWidth, m_maxCols, 1.0),
+               fraction(m_firstCol, max(0, m_maxCols - m_screenWidth), 0.0));
        ReLogger::globalLogger()->logv(LOG_INFO, 3, "draw: %.4f",
-           double(clock() - start) / CLOCKS_PER_SEC);
+               double(clock() - start) / CLOCKS_PER_SEC);
 }
 
 /**
@@ -772,16 +789,16 @@ void ReEdit::setTabStrings(int tabWidth) {
  * Constructor.
  */
 ReParagraphs::ReParagraphs() :
-           m_builders(),
-           m_firstLine(0),
-           m_firstCol(0),
-           m_cursorLineNo(0),
-           m_cursorCol(-1),
-           m_lines(NULL),
-           m_list(),
-           m_maxCols(0),
-           m_screenWidth(0),
-           m_cursorVisible(true) {
+               m_builders(),
+               m_firstLine(0),
+               m_firstCol(0),
+               m_cursorLineNo(0),
+               m_cursorCol(-1),
+               m_lines(NULL),
+               m_list(),
+               m_maxCols(0),
+               m_screenWidth(0),
+               m_cursorVisible(true) {
 }
 
 /**
@@ -823,7 +840,7 @@ void ReParagraphs::clear() {
  *                                     expanded tabs
  */
 int ReParagraphs::columnToIndex(int column, int tabWidth,
-    const QString& string) {
+       const QString& string) {
        int rc = 0;
        if (column < 0)
                rc = -1;
@@ -855,7 +872,7 @@ int ReParagraphs::columnToIndex(int column, int tabWidth,
 ReParagraph* ReParagraphs::cursorParagraph() {
        ReParagraph* rc = NULL;
        if (m_cursorLineNo >= m_firstLine
-           && m_cursorLineNo < m_firstLine + m_list.length()) {
+               && m_cursorLineNo < m_firstLine + m_list.length()) {
                rc = m_list.at(m_cursorLineNo - m_firstLine);
        }
        return rc;
@@ -869,7 +886,7 @@ ReParagraph* ReParagraphs::cursorParagraph() {
  */
 int ReParagraphs::columnToIndex(int cursorCol) {
        int rc = columnToIndex(cursorCol, m_tabWidth,
-           m_lines->lineAt(m_cursorLineNo));
+               m_lines->lineAt(m_cursorLineNo));
        return rc;
 }
 
@@ -907,7 +924,7 @@ void ReParagraphs::draw(QPainter& painter, int top, int left) {
  * @return
  */
 int ReParagraphs::indexToColumn(int index, int tabWidth,
-    const QString& string) {
+       const QString& string) {
        int rc = 0;
        if (index > 0) {
                int length = string.length();
@@ -974,13 +991,13 @@ void ReParagraphs::setLines(ReLines* lines) {
  * @param edit      the parent, the edit field
  */
 void ReParagraphBuilder::buildParagraph(ReParagraph& paragraph, int lineNo,
-    ReEdit* edit) {
+       ReEdit* edit) {
        if (paragraph.length() == 0) {
                int firstCol = edit->m_firstCol;
                const QString& text = edit->lines().lineAt(lineNo);
                ReLook* look = edit->lookOf(ReLook::FG_STANDARD, ReLook::BG_STANDARD);
                ReLook* lookTab = edit->lookOf(ReLook::FG_GREY_LIGHT,
-                   ReLook::BG_STANDARD);
+                       ReLook::BG_STANDARD);
                paragraph.m_columns = 0;
                int ixTab;
                ReEditText* part;
@@ -1067,14 +1084,14 @@ void ReParagraph::draw(QPainter& painter, int& top, int left) {
  * Constructor.
  */
 ReMouseCatcher::ReMouseCatcher() :
-           m_clickObjects(),
-           m_vScrollBar(new ClickPosition(CO_VSCROLLBAR)),
-           m_hScrollBar(new ClickPosition(CO_HSCROLLBAR)),
-           m_hSlider(new ClickPosition(CO_HSLIDER)),
-           m_vSlider(new ClickPosition(CO_VSLIDER)),
-           m_lastMousePosition(),
-           m_lastTopVSlider(0),
-           m_lastLeftHSlider(0) {
+               m_clickObjects(),
+               m_vScrollBar(new ClickPosition(CO_VSCROLLBAR)),
+               m_hScrollBar(new ClickPosition(CO_HSCROLLBAR)),
+               m_hSlider(new ClickPosition(CO_HSLIDER)),
+               m_vSlider(new ClickPosition(CO_VSLIDER)),
+               m_lastMousePosition(),
+               m_lastTopVSlider(0),
+               m_lastLeftHSlider(0) {
 
 }
 /**
@@ -1107,10 +1124,10 @@ void ReMouseCatcher::insertClickObject(ReMouseCatcher::ClickPosition* object) {
  * @return      <code>true</code>: the mouse click is inside the horizontal sb
  */
 bool ReMouseCatcher::handleHScrollBar(QMouseEvent* event, bool isDragged,
-    ReEdit* edit) {
+       ReEdit* edit) {
        QPoint pos = event->pos();
        bool rc = rectContains(*m_hScrollBar, pos, "hScrollBar")
-           || (isDragged && m_hScrollBar->contains(m_lastMousePosition));
+               || (isDragged && m_hScrollBar->contains(m_lastMousePosition));
        if (rc) {
                if (isDragged) {
                        int distance = pos.x() - m_lastMousePosition.x();
@@ -1118,8 +1135,8 @@ bool ReMouseCatcher::handleHScrollBar(QMouseEvent* event, bool isDragged,
                        int moveGap = m_hScrollBar->width() - m_hSlider->width();
                        double position = moveGap == 0 ? 0.0 : double(sliderPos) / moveGap;
                        int col = roundInt(
-                           (edit->m_maxCols - edit->m_screenWidth)
-                               * max(0.0, min(position, 1.0)));
+                               (edit->m_maxCols - edit->m_screenWidth)
+                                       * max(0.0, min(position, 1.0)));
                        //ReLogger::globalLogger()->logv(LOG_INFO, 4,
                        //      "x: %d dist: %d last: %d slPos: %d pos: %.2f gap: %d col: %d / %d scw: %d",
                        //      pos.x(), distance, m_lastLeftHSlider, sliderPos, position, moveGap,
@@ -1144,10 +1161,10 @@ bool ReMouseCatcher::handleHScrollBar(QMouseEvent* event, bool isDragged,
  * @return          <code>true</code>: the mouse click is inside the vertical sb
  */
 bool ReMouseCatcher::handleVScrollBar(QMouseEvent* event, bool isDragged,
-    ReEdit* edit) {
+       ReEdit* edit) {
        QPoint pos = event->pos();
        bool rc = rectContains(*m_vScrollBar, pos, "vScrollBar")
-           || (isDragged && m_vScrollBar->contains(m_lastMousePosition));
+               || (isDragged && m_vScrollBar->contains(m_lastMousePosition));
        if (rc) {
                if (isDragged) {
                        int distance = pos.y() - m_lastMousePosition.y();
@@ -1155,8 +1172,8 @@ bool ReMouseCatcher::handleVScrollBar(QMouseEvent* event, bool isDragged,
                        int moveGap = m_vScrollBar->height() - m_vSlider->height();
                        double position = moveGap == 0 ? 0.0 : double(sliderPos) / moveGap;
                        int line = roundInt(
-                           (edit->lines().lineCount() - edit->pageSize())
-                               * max(0.0, min(position, 1.0)));
+                               (edit->lines().lineCount() - edit->pageSize())
+                                       * max(0.0, min(position, 1.0)));
                        edit->reposition(line, edit->m_cursorCol);
                } else {
                        if (pos.y() < m_vSlider->top())
index 127be8515e824b64333a04bd1c7aa87d4901528d..e10cde4a578b2366d50877576fb7cd75cef63b46 100644 (file)
@@ -85,8 +85,8 @@ public:
         * @param source    source to copy
         */
        inline ReEditText(const ReEditText& source) :
-                   m_text(source.m_text),
-                   m_look(source.m_look) {
+                       m_text(source.m_text),
+                       m_look(source.m_look) {
        }
        /** Assignment operator.
         * @param source    source to copy
@@ -146,14 +146,14 @@ public:
 class ReParagraphBuilder {
 public:
        virtual void buildParagraph(ReParagraph& paragraph, int lineNo,
-           ReEdit* edit);
+               ReEdit* edit);
 };
 
 class ReCursortLineBuilder: public ReParagraphBuilder {
        // ReParagraphBuilder interface
 public:
        virtual void buildParagraph(ReParagraph& paragraph, int lineNo,
-           ReEdit* edit);
+               ReEdit* edit);
 };
 
 /**
@@ -234,10 +234,10 @@ public:
        class ClickPosition: public QRect {
        public:
                ClickPosition(ClickObjType type) :
-                           QRect(0, 0, 0, 0),
-                           m_type(type),
-                           m_title(),
-                           m_object(NULL) {
+                               QRect(0, 0, 0, 0),
+                               m_type(type),
+                               m_title(),
+                               m_object(NULL) {
                }
        public:
                bool operator <(const ClickPosition& op) {
@@ -302,6 +302,7 @@ public:
        };
 public:
        explicit ReEdit(QWidget *parent = 0);
+       virtual ~ReEdit();
 public:
        void assignColorsStandard();
        void assignKeysStandard();
@@ -317,7 +318,7 @@ public:
        }
        ReLines& lines();
        ReLook* lookOf(ReLook::ForeGround foreground,
-           ReLook::BackGround background);
+               ReLook::BackGround background);
        /** Returns the current page size.
         * return    number of visible lines in the edit field
         */
@@ -342,8 +343,8 @@ public:
 protected:
        QBrush* createBrush(ReLook::BackGround background);
        void drawScrollbars(QPainter& painter, const QRect& rect,
-           double sizeVertical, double posVertical, double sizeHorizontal,
-           double posHorizontal);
+               double sizeVertical, double posVertical, double sizeHorizontal,
+               double posHorizontal);
        void ensureCursorVisible();protected slots:
        void keyPressEvent(QKeyEvent* event);
        void paintEvent(QPaintEvent *);
index cde1280ae3244c1b4380ea6da03ae9d7d9e1b05b..ea6556fc64f36bba90949ab35e0237b92732066b 100644 (file)
@@ -114,6 +114,14 @@ ReSettings::ReSettings(const QString& path, const QString& prefix,
        setPath(path);
 }
 
+/**
+ * Destructor.
+ */
+ReSettings::~ReSettings()
+{
+
+}
+
 /*
  * Adds an entry to a history item at the first position.
  *
index eca2444bf7e54cef0d8a37316275d8fecd2b5846..eb4e73de1941c6480c334adb1c16f1ff1d2c1cf6 100644 (file)
@@ -66,12 +66,16 @@ private:
        ReLogger* m_logger;
 };
 
+typedef QMap<QByteArray, ReProperty*> RePropertyMap;
+typedef QMap<QByteArray, QList<ReProperty*>*> ReChapterMap;
+
 class ReSettings {
 public:
        static QString TRUE;
        static QString FALSE;
 public:
        ReSettings(const QString& path, const QString& prefix, ReLogger* logger);
+       ~ReSettings();
 public:
        void addHistoryEntry(const char* key, const QString& value, char separator,
                int maxEntries);
@@ -95,8 +99,8 @@ protected:
        QString m_path;
        QString m_fileHistory;
        QString m_fileSettings;
-       QMap<QByteArray, ReProperty*> m_settings;
-       QMap<QByteArray, QList<ReProperty*>*> m_chapters;
+       RePropertyMap m_settings;
+       ReChapterMap m_chapters;
        ReLogger* m_logger;
 };
 
index b88f0a3c7e245a9434a1c0ad32092ba1f6cce2e8..e1f99dd0ea79911557366f20c786001208ecff46 100644 (file)
 #include "base/rebase.hpp"
 #include "os/reos.hpp"
 
+enum {
+       LOC_READ_1 = LOC_FIRST_OF(LOC_FILESYSTEM), // 12001
+       LOC_WRITE_1,            // 12002
+       LOC_WRITE_2,            // 12003
+       LOC_WRITE_3,            // 12004
+       LOC_WRITE_4,            // 12005
+       LOC_READ_2,                     // 12006
+       LOC_MAKE_DIR_1,         // 12007
+       LOC_MAKE_DIR_2,         // 12008
+       LOC_MAKE_DIR_3,         // 12009
+       LOC_SET_PROPERTIES_1,   // 12010
+       LOC_SET_PROPERTIES_2,   // 12011
+       LOC_SET_PROPERTIES_3,   // 12012
+       LOC_REMOVE_1,           // 12013
+       LOC_REMOVE_2,           // 12014
+       LOC_REMOVE_3,           // 12015
+};
 
 /**
  * Constructor.
  *
  * @param name the name of the filesystem
  */
-ReFileSystem::ReFileSystem(const QString& name) :
-       m_name(name), m_writeable(false)
+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()
 {
 
 }
@@ -29,7 +47,33 @@ ReFileSystem::ReFileSystem(const QString& name) :
  */
 ReFileSystem::~ReFileSystem()
 {
+}
 
+/**
+ * Copy a file from a source filesystem to the current directory of the instance.
+ *
+ * @param source       meta data of the source file (in current directory)
+ * @param sourceFS     the filesystem containing the source
+ * @return                     EC_SUCCESS: success<br>
+ *
+ */
+ReFileSystem::ErrorCode ReFileSystem::copy(ReFileMetaData& source,
+               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)
+                       rc = rc2;
+               else if ( (rc2 = write(source.m_node, size, m_buffer)) != EC_SUCCESS)
+                       rc = rc2;
+               size += blocksize;
+       }
+       close();
+       sourceFS.close();
+       return rc;
 }
 
 /**
@@ -52,17 +96,66 @@ void ReFileSystem::setWriteable(bool writeable)
 {
        m_writeable = writeable;
 }
+/**
+ * Returns the current blocksize (for copy operations).
+ *
+ * @return the current blocksize
+ */
+int ReFileSystem::blocksize() const
+{
+       return m_blocksize;
+}
+
+/**
+ * Finds the first file given by a pattern.
+ *
+ * @param pattern      pattern to find
+ * @param file         OUT: the found file (valid only if return code is <code>true</code>
+ * @return                     <code>true</code>: at least one file found<br>
+ *                                     <code>false</code>: no file found
+ */
+bool ReFileSystem::first(const QString& pattern, ReFileMetaData& file)
+{
+       ReFileMetaDataList list;
+       QStringList names;
+       names.append(pattern);
+       ReIncludeExcludeMatcher matcher(names,
+               ReQStringUtils::m_emptyList, Qt::CaseInsensitive, true);
+       listInfos(matcher, list);
+       bool rc = list.size() > 0;
+       if (rc)
+               file = list.at(0);
+       return rc;
+}
+
+/**
+ * Sets the size of the internal buffer for copy operations.
+ *
+ * @param blocksize    the new blocksize
+ */
+void ReFileSystem::setBlocksize(int blocksize)
+{
+       m_blocksize = blocksize;
+}
+
 
 /**
  * Constructor.
+ *
+ * @param basePath     the root directory of the filesystem<br>
+ *                                     Windows: e.g. "c:\" or "\\server\data"<br>
+ *                                     Linux: Mount point, e.g. "/" or "/media/data"
+ * @param logger
  */
-ReLocalFileSytem::ReLocalFileSytem(const QString& basePath) :
-       ReFileSystem("localfs"),
+ReLocalFileSytem::ReLocalFileSytem(const QString& basePath, ReLogger* logger) :
+       ReFileSystem("localfs", logger),
        m_basePath(basePath),
        m_currentPath(basePath),
-       m_dir(basePath)
+       m_dir(basePath),
+       m_readFile(NULL),
+       m_writeFile(NULL)
 {
-
+       setWriteable(true);
 }
 
 /**
@@ -83,6 +176,21 @@ const QString& ReLocalFileSytem::basePath() const
        return m_basePath;
 }
 
+/**
+ * Closes the open files.
+ */
+void ReLocalFileSytem::close()
+{
+       if (m_readFile != NULL){
+               fclose(m_readFile);
+               m_readFile = NULL;
+       }
+       if (m_writeFile != NULL){
+               fclose(m_writeFile);
+               m_writeFile = NULL;
+       }
+}
+
 /**
  * Returns the name of the current directory.
  *
@@ -100,7 +208,7 @@ const QString& ReLocalFileSytem::directory() const
  * @return                     the count of the found entries (<code>list.size()</code>)
  */
 int ReLocalFileSytem::listInfos(const ReIncludeExcludeMatcher& matcher,
-                       QList<ReFileMetaData*>& list)
+                       ReFileMetaDataList& list)
 {
        list.clear();
        const QStringList& patterns = matcher.includes().patterns();
@@ -116,16 +224,41 @@ int ReLocalFileSytem::listInfos(const ReIncludeExcludeMatcher& matcher,
                full.resize(pathLength);
                full.append(node.toUtf8());
                if (stat(full.constData(), &info) == 0){
-                       ReFileMetaData* meta = new ReFileMetaData(node,
-                               QDateTime::fromTime_t(info.st_mtime),
-                               QDateTime::fromTime_t(info.st_ctime),
-                               info.st_uid, info.st_gid, info.st_mode);
-                       list.append(meta);
+                       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));
                }
        }
        return list.size();
 }
 
+/** Creates a directory.
+ * @param node the name without path (in the current directory)
+ * @return             EC_SUCCESS: successful<br>
+ *                             EC_FS_READ_ONLY: the filesystem is readonly<br>
+ *                             EC_ALREADY_EXISTS: a file with this name exists<br>
+ *                             EC_NOT_ACCESSIBLE: creation failed
+ */
+ReFileSystem::ErrorCode ReLocalFileSytem::makeDir(const QString& node)
+{
+       ErrorCode rc = EC_SUCCESS;
+       if (! m_writeable){
+               m_logger->log(LOG_ERROR, LOC_MAKE_DIR_1,
+                                         "filesystem is readonly");
+               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());
+               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());
+               rc = EC_NOT_ACCESSIBLE;
+       }
+       return rc;
+}
+
 /**
  * Changes the current directory of the filesystem.
  *
@@ -141,6 +274,211 @@ ReFileSystem::ErrorCode ReLocalFileSytem::setDirectory(const QString& 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 ReLocalFileSytem::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 = m_currentPath + 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;
+}
+
+/**
+ * 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: successful<br>
+ *                                     EC_FS_READ_ONLY: filesystem is readonly<br>
+ *                                     EC_ALREADY_EXISTS: renaming failed: target node exists already<br>
+ *                                     EC_RENAME: renaming failed
+ *
+ */
+ReFileSystem::ErrorCode ReLocalFileSytem::setProperties(
+               const ReFileMetaData& source, const ReFileMetaData& target)
+{
+       ErrorCode rc = EC_SUCCESS;
+       if (! m_writeable){
+               m_logger->log(LOG_ERROR, LOC_SET_PROPERTIES_1,
+                                         "filesystem is readonly");
+               rc = EC_FS_READ_ONLY;
+       } else {
+               if (target.m_node != source.m_node){
+                       if (m_dir.exists(source.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());
+                       } else if (! m_dir.rename(target.m_node, source.m_node)){
+                               rc = EC_RENAME;
+                               m_logger->logv(LOG_ERROR, LOC_SET_PROPERTIES_3,
+                                                         "renaming impossible: %s -> %s",
+                                                          source.m_node.toUtf8().constData(),
+                                                         fullNameAsUTF8(target.m_node).constData());
+                       }
+               }
+               if (rc == EC_SUCCESS && source.m_modified != target.m_modified
+                               && source.m_modified != m_undefinedTime){
+               }
+               if (rc == EC_SUCCESS && source.m_created != target.m_created
+                               && source.m_created != m_undefinedTime){
+               }
+               if (rc == EC_SUCCESS && source.m_mode != target.m_mode
+                               && source.m_mode != (mode_t) -1){
+               }
+               if (rc == EC_SUCCESS && source.m_owner != target.m_owner
+                               && source.m_owner != -1){
+               }
+               if (rc == EC_SUCCESS && source.m_group != target.m_group
+                               && source.m_group != -1){
+               }
+       }
+       return rc;
+}
+
+/**
+ * Removes a file or directory.
+ *
+ * @param node the properties ot the node (in the current directory)
+ * @return             EC_SUCCESS: successful<br>
+ *                             EC_FS_READ_ONLY: filesystem is readonly<br>
+ *                             EC_NOT_EXISTS: the node does not exist
+ *                             EC_NOT_ACCESSIBLE: removing failed
+ *
+ */
+ReFileSystem::ErrorCode ReLocalFileSytem::remove(const ReFileMetaData& node)
+{
+       ErrorCode rc = EC_SUCCESS;
+       if (! m_writeable){
+               m_logger->log(LOG_ERROR, LOC_REMOVE_1,
+                                         "filesystem is readonly");
+               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());
+               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());
+                               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());
+                               rc = EC_NOT_ACCESSIBLE;
+                       }
+               }
+       }
+       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 ReLocalFileSytem::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 = m_currentPath + 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.
+ */
+ReFileMetaData::ReFileMetaData() : m_node(), m_modified(), m_created(),
+       m_owner(0), m_group(0), m_mode(0), m_size(-1){
+
+}
 
 /**
  * Constructor.
@@ -151,15 +489,18 @@ ReFileSystem::ErrorCode ReLocalFileSytem::setDirectory(const QString& path)
  * @param owner                the owner of the file (UID)
  * @param group                the group of the file (GID)
  * @param mode         rights and attributs of the file
+ * @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) :
+               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_mode(mode),
+       m_size(size)
 {
 
 }
@@ -171,3 +512,37 @@ ReFileMetaData::~ReFileMetaData()
 {
 
 }
+/**
+ * Copy constructor.
+ *
+ * @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)
+{
+
+}
+
+/**
+ * Assign operator.
+ *
+ * @param source       source to copy
+ * @return                     the instance itself
+ */
+ReFileMetaData&ReFileMetaData::operator =(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;
+       return *this;
+}
index b194c13f99c350019ed9ebe989bfb19566c5ac0a..c0cf4d5c92d3177453733c6a40b13a8cf78ecb5b 100644 (file)
 
 class ReFileMetaData {
 public:
+       ReFileMetaData();
        ReFileMetaData(const QString& node, const QDateTime& modified,
                const QDateTime& created,
-               int owner, int group, mode_t mode);
+               int owner, int group, mode_t mode, int64_t size);
        virtual ~ReFileMetaData();
+       ReFileMetaData(const ReFileMetaData& source);
+       ReFileMetaData& operator =(const ReFileMetaData& source);
 public:
        QString m_node;
        QDateTime m_modified;
@@ -25,7 +28,9 @@ public:
        int16_t m_owner;
        int16_t m_group;
        mode_t m_mode;
+       int64_t m_size;
 };
+typedef QList<ReFileMetaData> ReFileMetaDataList;
 
 class ReFileSystem {
 public:
@@ -41,19 +46,24 @@ public:
                EC_SUCCESS,
                EC_PATH_NOT_FOUND,
                EC_NOT_ACCESSIBLE,
+               EC_NOT_READABLE,
+               EC_READ,
+               EC_FS_READ_ONLY,
+               EC_NOT_WRITEABLE,
+               EC_WRITE,
+               EC_POSITION,
+               EC_ALREADY_EXISTS,
+               EC_NOT_EXISTS,
+               EC_RENAME,
        };
 
 public:
-       ReFileSystem(const QString& name);
+       ReFileSystem(const QString& name, ReLogger* logger);
        virtual ~ReFileSystem();
 public:
-       /** Changes the current directory of the filesystem.
-        * @param path  the new current directory
-        * @return      0: success<br>
-        *                      EC_PATH_NOT_FOUND       directory does not exist<br>
-        *                      EC_NOT_ACCESSIBLE       parent not readable
+       /** Frees resources like open files.
         */
-       virtual ErrorCode setDirectory(const QString& path) = 0;
+       virtual void close() = 0;
        /** Returns the name of the current directory.
         * @return      the name of the current directory
         */
@@ -63,31 +73,111 @@ public:
         * @return                      the count of the found entries (<code>list.size()</code>)
         */
        virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
-                                                 QList<ReFileMetaData*>& list) = 0;
+                                                 ReFileMetaDataList& list) = 0;
+       /** Creates a directory.
+        * @param node  the name without path (in 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 remove(const ReFileMetaData& node) = 0;
+       /** Sets the current directory.
+        * @param path  relative or absolute path. If absolute it must be part of the
+        *                              base path
+        * @return              EC_SUCCESS or error code
+        */
+       virtual ErrorCode setDirectory(const QString& path) = 0;
+       /** 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
+        */
+       virtual ErrorCode setProperties(const ReFileMetaData& source,
+                                                                       const ReFileMetaData& target) = 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
+        * @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:
-       bool writeable() const;
+       virtual ErrorCode copy(ReFileMetaData& source, ReFileSystem& sourceFS);
+public:
+       int blocksize() const;
+       bool first(const QString& pattern, ReFileMetaData& file);
+       /** Returns the full name (with path).
+        * @param node  the name without path
+        * @return              the full filename
+        */
+       inline QString fullName(const QString& node) const{
+               return m_directory + node;
+       }
+       /** Returns the full name (with path) as UTF-8 string.
+        * @param node  the name without path
+        * @return              the full filename
+        */
+       QByteArray fullNameAsUTF8(const QString& node) const{
+               return (m_directory + node).toUtf8();
+       }
        void setWriteable(bool writeable);
+       void setBlocksize(int blocksize);
+       bool writeable() const;
+
 protected:
        QString m_name;
        QString m_directory;
        bool m_writeable;
+       ReLogger* m_logger;
+       QByteArray m_buffer;
+       int m_blocksize;
+       QDateTime m_undefinedTime;
 };
 
 class ReLocalFileSytem : public ReFileSystem {
 public:
-       ReLocalFileSytem(const QString& basePath);
+       ReLocalFileSytem(const QString& basePath, ReLogger* logger);
        virtual ~ReLocalFileSytem();
 public:
        const QString& basePath() const;
        const QString& directory() const;
-       virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
-                                                 QList<ReFileMetaData*>& list);
        ErrorCode setDirectory(const QString& path);
 
+public:
+       // ReFileSystem interface
+       virtual void close();
+       virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
+                                                 ReFileMetaDataList& list);
+       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, const ReFileMetaData& target);
+       virtual ErrorCode write(const QString& target, int64_t offset,
+                                                       const QByteArray& buffer);
+
 protected:
        QString m_basePath;
        QString m_currentPath;
        QDir m_dir;
+
+       FILE* m_readFile;
+       FILE* m_writeFile;
+
 };
 
 #endif /* OS_REFILESYSTEM_HPP_ */
index e7d54070dfc7bfb644cbda4be7770b436324d57c..3f5aff969a6e3556110adac1e37d2ea0052044d2 100644 (file)
@@ -32,6 +32,7 @@ enum {
        LOC_FILE,
        LOC_FILETREE,
        LOC_STATESTORAGE,       // 120
+       LOC_FILESYSTEM,
 };
 #define LOC_FIRST_OF(moduleNo) (moduleNo*100+1)
 class RplModules {