]> gitweb.hamatoma.de Git - reqt/commitdiff
ReFileSystem + ReMatcher
authorhama <hama@siduction.net>
Sat, 19 Sep 2015 00:25:04 +0000 (02:25 +0200)
committerhama <hama@siduction.net>
Sat, 19 Sep 2015 00:25:04 +0000 (02:25 +0200)
base/ReMatcher.cpp
base/ReMatcher.hpp
cunit/allTests.cpp
cunit/cuReFileSystem.cpp
os/ReFileSystem.cpp
os/ReFileSystem.hpp

index 3b9a5a9309cf2cedc3f19d0f24b55a1bc7964db4..2d86b277dfe3116452e883cee37c22fc40fb967a 100644 (file)
@@ -20,6 +20,8 @@
  */
 #include "base/rebase.hpp"
 
+QStringList* ReListMatcher::m_allMatchingList = NULL;
+ReListMatcher* ReListMatcher::m_allMatcher = NULL;
 
 /**
  * Constructor.
@@ -38,7 +40,7 @@ ReMatcher::ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensivity,
                m_restLengths(),
                m_anchored(anchored),
                m_caseSensivitiy(caseSensivity) {
-       setPattern(pattern);
+       setPattern(pattern, anchored);
 }
 
 /**
@@ -71,13 +73,20 @@ bool ReMatcher::matches(const QString& text) {
  * Sets the search pattern.
  *
  * @param pattern      the search pattern, with wildcards '*' (any string)
+ * @param anchored     <code>true</code>: the pattern must match at the begin<br>
+ *                                     <code>false</code>: the pattern can match anywhere
  */
-void ReMatcher::setPattern(const QString& pattern) {
+void ReMatcher::setPattern(const QString& pattern, bool anchored) {
+       m_anchored = anchored;
+       m_allMatching = false;
        if (pattern.isEmpty())
                m_needles.clear();
        else {
-               if (pattern.startsWith("*"))
+               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--) {
@@ -94,6 +103,36 @@ void ReMatcher::setPattern(const QString& pattern) {
                }
        }
 }
+/**
+ * Returns whether the matcher accepts all strings (pattern "*").
+ *
+ * @return <code>true</code>: the matcher accepts all strings
+ */
+bool ReMatcher::allMatching() const
+{
+       return m_allMatching;
+}
+
+/**
+ * Returns the case sensitivity of the pattern matching.
+ *
+ * @return     <code>true</code>: the character case is relevant
+ */
+Qt::CaseSensitivity ReMatcher::caseSensivitiy() const
+{
+       return m_caseSensivitiy;
+}
+
+/**
+ * Sets the case sensisitivy of the pattern matching.
+ *
+ * @param caseSensivitiy       <code>true</code>: the character case is relevant
+ */
+void ReMatcher::setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy)
+{
+       m_caseSensivitiy = caseSensivitiy;
+}
+
 
 /**
  * Constructor.
@@ -106,15 +145,13 @@ void ReMatcher::setPattern(const QString& pattern) {
  *                                                     the string
  */
 ReListMatcher::ReListMatcher(const QStringList& patterns,
-                                                        Qt::CaseSensitivity caseSensitivty, bool anchored) :
+                                                        Qt::CaseSensitivity caseSensivity, bool anchored) :
+       m_patterns(patterns),
        m_list(),
-       m_empty(false)
+       m_empty(false),
+       m_allMatching(false)
 {
-       QStringList::const_iterator it;
-       for (it = patterns.constBegin(); it != patterns.cend(); ++it){
-               m_list.append(new ReMatcher(*it, caseSensitivty, anchored));
-               m_empty = true;
-       }
+       setPatterns(patterns, caseSensivity, anchored);
 }
 /**
   * Destructor.
@@ -122,6 +159,40 @@ ReListMatcher::ReListMatcher(const QStringList& patterns,
 ReListMatcher::~ReListMatcher(){
        destroy();
 }
+
+/**
+ * Returns whether the search finds all (pattern "*").
+ *
+ * @return <code>true</code>: the matcher accept all strings
+ */
+bool ReListMatcher::allMatching() const
+{
+       return m_allMatching;
+}
+
+/**
+ * Returns a string list with one entry "*".
+ *
+ * @return a
+ */
+const QStringList& ReListMatcher::allMatchingList()
+{
+       if (m_allMatchingList == NULL){
+               m_allMatchingList = new QStringList();
+               m_allMatchingList->append("*");
+       }
+       return *m_allMatchingList;
+}
+
+/**
+ * Returns the case sensitivity of the pattern matching.
+ *
+ * @return     <code>true</code>: the character case is relevant
+ */
+Qt::CaseSensitivity ReListMatcher::caseSensivitiy() const
+{
+       return m_list.at(0)->caseSensivitiy();
+}
 /**
  * Frees the resources.
  */
@@ -133,6 +204,30 @@ void ReListMatcher::destroy(){
        m_list.clear();
 }
 
+/**
+ * Returns a pattern match processor accepting all strings.
+ *
+ * @return a matcher accepting all strings
+ */
+const ReListMatcher& ReListMatcher::allMatcher()
+{
+       if (m_allMatcher == NULL){
+               m_allMatcher = new ReListMatcher(allMatchingList());
+       }
+       return *m_allMatcher;
+}
+
+
+/**
+ * Returns the current pattern list.
+ *
+ * @return the pattern list
+ */
+const QStringList& ReListMatcher::patterns() const
+{
+       return m_patterns;
+}
+
 /**
  * Returns whether the pattern list is empty.
  *
@@ -159,6 +254,43 @@ bool ReListMatcher::matches(const QString& text)
        return rc;
 }
 
+/**
+ * Sets the case sensisitivy of the pattern matching.
+ *
+ * @param caseSensivitiy       <code>true</code>: the character case is relevant
+ */
+void ReListMatcher::setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy)
+{
+       QList<ReMatcher*>::const_iterator it;
+       for (it = m_list.begin(); it != m_list.end(); ++it){
+               (*it)->setCaseSensivitiy(caseSensivitiy);
+       }
+}
+
+/**
+ * Sets a new pattern list.
+ *
+ * @param patterns     the patterns to search
+ * @param anchored     <code>true<code>: the pattern must match the string's start<br>
+ *                                     <code>false<code>: the pattern can match anywhere
+ */
+void ReListMatcher::setPatterns(const QStringList& patterns,
+       Qt::CaseSensitivity caseSensivity, bool anchored)
+{
+       destroy();
+       m_patterns = patterns;
+       m_empty = true;
+       m_allMatching = false;
+       QStringList::const_iterator it;
+       for (it = patterns.constBegin(); it != patterns.cend(); ++it){
+               ReMatcher* matcher = new ReMatcher(*it, caseSensivity, anchored);
+               m_list.append(matcher);
+               if (matcher->allMatching())
+                       m_allMatching = true;
+               m_empty = false;
+       }
+}
+
 
 /**
  * Constructor.
@@ -172,11 +304,39 @@ bool ReListMatcher::matches(const QString& text)
  *                                                     the string
  */
 ReIncludeExcludeMatcher::ReIncludeExcludeMatcher(const QStringList& includes,
-       const QStringList& excludes, Qt::CaseSensitivity caseSensitivty,
+       const QStringList& excludes, Qt::CaseSensitivity caseSensivity,
        bool anchored) :
-       m_includes(includes, caseSensitivty, anchored),
-       m_excludes(excludes, caseSensitivty, anchored)
+       m_includes(includes, caseSensivity, anchored),
+       m_excludes(excludes, caseSensivity, anchored)
+{
+}
+
+/**
+ * Returns the case sensitivity of the pattern matching.
+ *
+ * @return     <code>true</code>: the character case is relevant
+ */
+Qt::CaseSensitivity ReIncludeExcludeMatcher::caseSensivitiy() const
+{
+       return m_includes.caseSensivitiy();
+}
+
+/**
+ * Returns the exclude matcher.
+ * @return the exclude matcher
+ */
+const ReListMatcher& ReIncludeExcludeMatcher::excludes() const
 {
+       return m_excludes;
+}
+
+/**
+ * Returns the include matcher.
+ * @return the include matcher
+ */
+const ReListMatcher& ReIncludeExcludeMatcher::includes() const
+{
+       return m_includes;
 }
 
 /**
@@ -195,3 +355,15 @@ bool ReIncludeExcludeMatcher::matches(const QString& text, bool excludeToo)
                rc = ! m_excludes.matches(text);
        return rc;
 }
+
+/**
+ * Sets the case sensitivity of the pattern matching.
+ *
+ * @param caseSensivitiy       <code>true</code>: the character case is relevant
+ */
+void ReIncludeExcludeMatcher::setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy)
+{
+       m_includes.setCaseSensivitiy(caseSensivitiy);
+       m_excludes.setCaseSensivitiy(caseSensivitiy);
+}
+
index c5eb9b787f67ab2d4433c20db1e8442eadfdbfef..3ba8e8f023170883da1a943200f37437dbc95fae 100644 (file)
@@ -23,14 +23,19 @@ public:
        ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensitivty =
                Qt::CaseSensitive, bool anchored = false);
 public:
+       bool allMatching() const;
+       Qt::CaseSensitivity caseSensivitiy() const;
        bool matches(const QString& text);
-       void setPattern(const QString& pattern);
+       void setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy);
+       void setPattern(const QString& pattern, bool anchored = false);
+
 protected:
        QStringList m_needles;
        // m_restLengths[ix] = sum(m_needles[ix..last].size()
        QList<int> m_restLengths;
        bool m_anchored;
        Qt::CaseSensitivity m_caseSensivitiy;
+       bool m_allMatching;
 };
 
 /**
@@ -42,13 +47,27 @@ public:
                        Qt::CaseSensitive, bool anchored = false);
        ~ReListMatcher();
 public:
-       bool matches(const QString& text);
+       bool allMatching() const;
+       Qt::CaseSensitivity caseSensivitiy() const;
        bool empty() const;
+       bool matches(const QString& text);
+       const QStringList& patterns() const;
+       void setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy);
+       void setPatterns(const QStringList& patterns,
+               Qt::CaseSensitivity caseSensivity = Qt::CaseSensitive, bool anchored = false);
+public:
+       static const ReListMatcher& allMatcher();
+       static const QStringList& allMatchingList();
 protected:
        void destroy();
+private:
+       static QStringList* m_allMatchingList;
+       static ReListMatcher* m_allMatcher;
 protected:
+       QStringList m_patterns;
        QList<ReMatcher*> m_list;
        bool m_empty;
+       bool m_allMatching;
 };
 
 /**
@@ -61,7 +80,12 @@ public:
                        Qt::CaseSensitivity caseSensitivty = Qt::CaseSensitive,
                        bool anchored = false);
 public:
+       Qt::CaseSensitivity caseSensivitiy() const;
        bool matches(const QString& text, bool excludeToo = true);
+       const ReListMatcher& includes() const;
+       const ReListMatcher& excludes() const;
+       void setCaseSensivitiy(const Qt::CaseSensitivity& caseSensivitiy);
+
 protected:
        ReListMatcher m_includes;
        ReListMatcher m_excludes;
index 9c16df1307e6e90ea636f2218a6b1a56d287cc1a..ddd81692d6b288541eb33e27915b21d80fc1f4b6 100644 (file)
@@ -84,7 +84,9 @@ static void testNet() {
 
 }
 static void testOs() {
+       void testReFileSystem();
 
+       testReFileSystem();
 }
 void allTests() {
        testBase();
index 6f732eb559b8faf7ef5facacfd6640bfa7d9915f..743d32e2d74446013abfaeae3b02f9ce10e2b570 100644 (file)
@@ -27,21 +27,41 @@ private:
 protected:
        void init(){
                m_base = ReFileUtils::tempDir("refilesystem");
-               m_subDir1 = tempDir("dir1", "refilesystem");
-               tempDir("dir2", "refilesystem");
+               m_subDir1 = ReFileUtils::tempDir("dir1", "refilesystem");
+               ReFileUtils::tempDir("dir2", "refilesystem");
                QString node;
                for (int ix = 1; ix <= 7; ix++){
                        node.sprintf("test%d.txt", ix);
-                       QString fn = ReFileUtils::tempFile(node, "refilesystem", false);
-                       ReFileUtils::writeToFile(fn, node);
-                       fn.sprintf("%stext%d.txt", m_subDir1.constData(), ix);
-                       ReFileUtils::writeToFile(fn, fn);
+                       QByteArray fn = ReFileUtils::tempFile(node.toUtf8().constData(),
+                               "refilesystem", false);
+                       ReFileUtils::writeToFile(fn.constData(), node.toUtf8().constData());
+                       fn = m_subDir1;
+                       fn.append("text").append(QByteArray::number(ix));
+                       ReFileUtils::writeToFile(fn.constData(), fn.constData());
                }
        }
+       void testContains(const char* name, QList<ReFileMetaData*> nodes){
+               bool rc = false;
+               QList<ReFileMetaData*>::const_iterator it;
+               for (it = nodes.cbegin(); it != nodes.cend(); ++it){
+                       if ((*it)->m_node == name)
+                               rc = true;
+               }
+               if (! rc)
+                       checkT(rc);
+       }
+
        void testReLocalFileSystem() {
                ReLocalFileSytem fs(m_base);
-               fs.
-
+               checkEqu(QString(m_base), fs.directory());
+               checkEqu(QString(m_base), fs.basePath());
+               QList<ReFileMetaData*> nodes;
+               ReIncludeExcludeMatcher matcher(ReListMatcher::allMatchingList(),
+                       ReQStringUtils::m_emptyList, Qt::CaseInsensitive, false);
+               fs.listInfos(matcher, nodes);
+               testContains("dir1", nodes);
+               testContains("test1.txt", nodes);
+               testContains("test7.txt", nodes);
        }
        virtual void run() {
                init();
index 862e77f6c9b75360d9ead4fc67a7561dd9de73f0..b88f0a3c7e245a9434a1c0ad32092ba1f6cce2e8 100644 (file)
@@ -66,18 +66,21 @@ ReLocalFileSytem::ReLocalFileSytem(const QString& basePath) :
 }
 
 /**
- * Changes the current directory of the filesystem.
+ * Destructor.
+ */
+ReLocalFileSytem::~ReLocalFileSytem()
+{
+
+}
+
+/**
+ * Returns the base path 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
+ * @return the base path
  */
-ReFileSystem::ErrorCode ReLocalFileSytem::setDirectory(const QString& path)
+const QString& ReLocalFileSytem::basePath() const
 {
-       ErrorCode rc = m_dir.setCurrent(path) ? EC_SUCCESS : EC_PATH_NOT_FOUND;
-       m_currentPath = m_dir.absolutePath();
-       return rc;
+       return m_basePath;
 }
 
 /**
@@ -91,37 +94,80 @@ const QString& ReLocalFileSytem::directory() const
 }
 
 /**
- * Returns a list of the file infos of the current directory.
+ * Fills a list with the items of the current directory.
  *
- * @param patterns     only files matching these patterns will be in the result.
- *                                     Can contain wildcard '*' (for any string)
- * @return                     a list of the files matching the patterns
+ * @param matcher      the matching processor
+ * @return                     the count of the found entries (<code>list.size()</code>)
  */
 int ReLocalFileSytem::listInfos(const ReIncludeExcludeMatcher& matcher,
                        QList<ReFileMetaData*>& list)
 {
-       QList<ReFileMetaData*> rc;
-       QStringList list = pattern.size() == 0 ? m_dir.entryList()
-                                                                                  : m_dir.entryList(pattern);
+       list.clear();
+       const QStringList& patterns = matcher.includes().patterns();
+       QStringList nodes = patterns.size() == 0 ? m_dir.entryList()
+                                                                                  : m_dir.entryList(patterns);
        QStringList::const_iterator it;
        QByteArray full = m_currentPath.toUtf8();
        full.append(OS_SEPARATOR);
        int pathLength = full.length();
        struct stat info;
-       for (it = list.cbegin(); it != list.cend(); it++){
+       for (it = nodes.cbegin(); it != nodes.cend(); it++){
                QString node = *it;
                full.resize(pathLength);
                full.append(node.toUtf8());
                if (stat(full.constData(), &info) == 0){
-                       ReFileMetaData* meta = new ReFileMetaData(node);
-                       meta->m_modified = QDateTime::fromTime_t(info.st_mtim);
-                       meta->m_created = QDateTime::fromTime_t(info.st_ctim);
-                       meta->m_group = info.st_gid;
-                       meta->m_owner = info.st_uid;
-                       meta->m_mode = info.st_mode;
-                       rc.append(meta);
+                       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);
                }
        }
+       return list.size();
+}
+
+/**
+ * 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
+ */
+ReFileSystem::ErrorCode ReLocalFileSytem::setDirectory(const QString& path)
+{
+       ErrorCode rc = m_dir.setCurrent(path) ? EC_SUCCESS : EC_PATH_NOT_FOUND;
+       m_currentPath = m_dir.absolutePath();
        return rc;
 }
 
+
+/**
+ * Constructor.
+ *
+ * @param node         the filename without path
+ * @param modified     the modification date/time
+ * @param created      the creation date/time
+ * @param owner                the owner of the file (UID)
+ * @param group                the group of the file (GID)
+ * @param mode         rights and attributs of the file
+ */
+ReFileMetaData::ReFileMetaData(const QString& node, const QDateTime& modified,
+               const QDateTime& created, int owner, int group, mode_t mode) :
+       m_node(node),
+       m_modified(modified),
+       m_created(created),
+       m_owner(owner),
+       m_group(group),
+       m_mode(mode)
+{
+
+}
+
+/**
+ * Destructor.
+ */
+ReFileMetaData::~ReFileMetaData()
+{
+
+}
index d48648c7eb8e57e5b0ec80dbfebf4dd5235f0fd4..b194c13f99c350019ed9ebe989bfb19566c5ac0a 100644 (file)
@@ -14,7 +14,9 @@
 
 class ReFileMetaData {
 public:
-       ReFileMetaData(const QString& node);
+       ReFileMetaData(const QString& node, const QDateTime& modified,
+               const QDateTime& created,
+               int owner, int group, mode_t mode);
        virtual ~ReFileMetaData();
 public:
        QString m_node;
@@ -56,12 +58,9 @@ public:
         * @return      the name of the current directory
         */
        virtual const QString& directory() const = 0;
-       /** Returns a list of the file infos of the current directory.
-        * @param patterns      only files matching these patterns will be in the result
-        *                                      Can contain wildcard '*' (for any string)
-        * @param excludePatterns       only files not matching this patterns
-        *                                                      can be in the result list
-        * @return                      a list of the files matching the patterns
+       /** 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,
                                                  QList<ReFileMetaData*>& list) = 0;
@@ -79,10 +78,12 @@ public:
        ReLocalFileSytem(const QString& basePath);
        virtual ~ReLocalFileSytem();
 public:
-       ErrorCode setDirectory(const QString& path);
+       const QString& basePath() const;
        const QString& directory() const;
        virtual int listInfos(const ReIncludeExcludeMatcher& matcher,
                                                  QList<ReFileMetaData*>& list);
+       ErrorCode setDirectory(const QString& path);
+
 protected:
        QString m_basePath;
        QString m_currentPath;