*/
#include "base/rebase.hpp"
+QStringList* ReListMatcher::m_allMatchingList = NULL;
+ReListMatcher* ReListMatcher::m_allMatcher = NULL;
/**
* Constructor.
m_restLengths(),
m_anchored(anchored),
m_caseSensivitiy(caseSensivity) {
- setPattern(pattern);
+ setPattern(pattern, anchored);
}
/**
* 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--) {
}
}
}
+/**
+ * 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.
* 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.
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.
*/
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.
*
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.
* 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;
}
/**
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);
+}
+
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;
};
/**
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;
};
/**
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;
}
static void testOs() {
+ void testReFileSystem();
+ testReFileSystem();
}
void allTests() {
testBase();
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();
}
/**
- * 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;
}
/**
}
/**
- * 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()
+{
+
+}
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;
* @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;
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;