* otherwise: the length of the integer
*/
int ReQStringUtils::lengthOfUInt64(const ReString& text, int start, int radix,
- quint64* pValue) {
+ quint64* pValue) {
int inputLength = text.size();
int64_t value = 0;
int ix = start;
}
} else {
throw ReException("ReQStringUtil::lengthOfInt(): wrong radix: %d",
- radix);
+ radix);
}
if (pValue != NULL)
*pValue = value;
* otherwise: the length of the integer
*/
int ReQStringUtils::lengthOfUInt(const ReString& text, int start, int radix,
- uint* pValue) {
+ uint* pValue) {
quint64 value;
int rc = lengthOfUInt64(text, start, radix, &value);
if (pValue != NULL)
* otherwise: the length of the date in the string
*/
int ReQStringUtils::lengthOfDate(const ReString& text, int start,
- QDate* value) {
+ QDate* value) {
uint day = 0;
uint month = 0;
uint year = 0;
}
}
if (day < 1 || day > 31 || month < 1 || month > 12 || year < 1970
- || year > 2100)
+ || year > 2100)
length = 0;
if (length != 0 && value != NULL)
*value = QDate(year, month, day);
* otherwise: the length of the date in the string
*/
int ReQStringUtils::lengthOfDateTime(const ReString& text, int start,
- bool allowDateOnly, bool allowTimeOnly, QDateTime* value) {
+ bool allowDateOnly, bool allowTimeOnly, QDateTime* value) {
QDate date;
QTime time;
int length = lengthOfDate(text, start, &date);
* otherwise: the length of the date in the string
*/
int ReQStringUtils::lengthOfTime(const ReString& text, int start,
- QTime* value) {
+ QTime* value) {
uint hour = 0;
uint minute = 0;
uint sec = 0;
* otherwise: the length of the floating point number
*/
int ReQStringUtils::lengthOfReal(const ReString& text, int start,
- qreal* pValue) {
+ qreal* pValue) {
int inputLength = text.size();
qreal value = 0.0;
int cc;
*/
QString ReQStringUtils::replaceExtension(const QString& path,
- const QString& ext) {
+ const QString& ext) {
QString oldExt = extensionOf(path);
QString rc;
if (oldExt.isEmpty())
* <code>false</code>: unknown name found (not replaced)
*/
bool ReQStringUtils::replacePlaceholders(QString& text,
- const QMap<QString, QString>& placeholders, QString* error) {
+ const QMap<QString, QString>& placeholders, QString* error) {
int start = 0;
bool rc = true;
QString name;
* otherwise: the length is incremented
*/
void ReQStringUtils::skipExpected(const ReString& text, QChar expected,
- int& index, int& length) {
+ int& index, int& length) {
if (length == 0) {
// error state, do nothing
} else if (index >= text.length() || text[index] != expected) {
* @return <code>buffer</code>
*/
char*ReQStringUtils::utf8(const ReString& source, char buffer[],
- size_t bufferSize) {
+ size_t bufferSize) {
QByteArray val = source.toUtf8();
if (val.length() < (int) bufferSize)
bufferSize = val.length() + 1;
class ReParserException: public ReException {
public:
ReParserException(const QString& message) :
- ReException(),
- m_message(message) {
+ ReException(),
+ m_message(message) {
}
public:
QString m_message;
* example: "kibyte:1024;kbyte:1000;mibyte:1048576;mbyte:1000000"
*/
ReUnitParser::ReUnitParser(const QString& expr, const char* unitList,
- bool parseAtOnce) :
- m_result(0),
- m_expr(expr),
- m_message(),
- m_unitList(unitList) {
+ bool parseAtOnce) :
+ m_result(0),
+ m_expr(expr),
+ m_message(),
+ m_unitList(unitList) {
normalize();
if (parseAtOnce)
parse();
// This makes the syntax easier to parse: only one sum operator ('+').
for (int ii = m_expr.length() - 1; ii > 0; ii--) {
if (m_expr[ii] == '-' && m_expr[ii - 1] != '+'
- && m_expr[ii - 1] != '*') {
+ && m_expr[ii - 1] != '*') {
m_expr.insert(ii, '+');
}
}
QStringList powerOperands = it2->split("^");
if (powerOperands.count() > 2)
throw ReParserException(
- QObject::tr(
- "more than 2 power operators, e.g. '2^3^4'"));
+ QObject::tr(
+ "more than 2 power operators, e.g. '2^3^4'"));
QStringList::const_iterator it3 = powerOperands.begin();
QString op = *it3;
bool isNeg = op.startsWith("-");
uint64_t exponent = valueOf(*++it3);
if (qLn(value) * qLn(exponent) >= qLn(qPow(2.0, 64)))
throw ReParserException(
- QObject::tr(
- "number overflow while power operation"));
+ QObject::tr(
+ "number overflow while power operation"));
for (int ii = 1; ii < (int) exponent; ii++)
value = value * fac;
}
QStringList pair = it->split(":");
if (pair.count() == 0)
throw ReParserException(
- QObject::tr(
- "missing ':' in unit definition, e.g. 'k:1000': ")
- + *it);
+ QObject::tr(
+ "missing ':' in unit definition, e.g. 'k:1000': ")
+ + *it);
if (pair.count() > 2)
throw ReParserException(
- QObject::tr("too many ':' in unit definition: ") + *it);
+ QObject::tr("too many ':' in unit definition: ") + *it);
bool ok = false;
QString unit2 = *pair.begin();
QString factor = *++pair.begin();
}
if (!found)
throw ReParserException(
- QObject::tr("unknown unit '$1'. Allowed: ").arg(unit)
- + QString(m_unitList));
+ QObject::tr("unknown unit '$1'. Allowed: ").arg(unit)
+ + QString(m_unitList));
}
return rc;
}
* @param expr an expression, e.g. "10*1024kByte+5MiByte"
*/
ReSizeParser::ReSizeParser(const QString& expr) :
- ReUnitParser(expr, "byte:1;kbyte:1000;kibyte:1024;"
- "mbyte:1000000;mibyte:1048576;"
- "gbyte:1000000000;gibyte:1073741824;"
- "tbyte:1000000000000;tibyte:1099511627776") {
+ ReUnitParser(expr, "byte:1;kbyte:1000;kibyte:1024;"
+ "mbyte:1000000;mibyte:1048576;"
+ "gbyte:1000000000;gibyte:1073741824;"
+ "tbyte:1000000000000;tibyte:1099511627776") {
}
/**
* Constructor.
* @param expr an expression, e.g. "3*3days-5min+3weeks"
*/
ReDateTimeParser::ReDateTimeParser(const QString& expr) :
- ReUnitParser("", "minutes:60;hours:3600;days:86400;weeks:604800", false) {
+ ReUnitParser("", "minutes:60;hours:3600;days:86400;weeks:604800", false) {
parseDateTime(expr);
}
if (m_expr.startsWith("now", Qt::CaseInsensitive)) {
m_expr.remove(0, 3);
} else if ((length2 = ReQStringUtils::lengthOfDateTime(m_expr, 0, true,
- true, &dateTime)) > 0) {
+ true, &dateTime)) > 0) {
rc = dateTime;
m_expr.remove(0, length2);
} else {
}
}
rc.setMSecsSinceEpoch(
- isValid() ? rc.toMSecsSinceEpoch() + 1000 * relativeSeconds : 0);
+ isValid() ? rc.toMSecsSinceEpoch() + 1000 * relativeSeconds : 0);
m_dateTime = rc;
return rc;
}
/**
* Constructor.
*
- * @param pattern a pattern with wildcards '*' (any string)
- * @param anchored <code>true<code>: the pattern starts at the strings start<br>
- * <code>false<code>: the pattern can start anywhere in the string<br>
+ * @param pattern a pattern with wildcards '*' (any string)
+ * @param caseSensitivity caseSensitive or caseInsensitive
+ * @param anchored <code>true<code>: the pattern starts at the strings
+ * start<br>
+ * <code>false<code>: the pattern can start anywhere in
+ * the string
*/
ReMatcher::ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensivity,
- bool anchored) :
- m_needles(),
- m_restLengths(),
- m_anchored(anchored),
- m_caseSensivitiy(caseSensivity) {
+ bool anchored) :
+ m_needles(),
+ m_restLengths(),
+ m_anchored(anchored),
+ m_caseSensivitiy(caseSensivity) {
setPattern(pattern);
}
bool found = m_needles.size() == 0;
if (!found) {
found =
- m_anchored ?
- text.startsWith(m_needles.at(0), m_caseSensivitiy) : true;
+ 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;
found = text.size() - textIndex >= m_restLengths.at(ix);
if (found)
found = (textIndex = text.indexOf(m_needles.at(ix),
- textIndex, m_caseSensivitiy)) >= 0;
+ textIndex, m_caseSensivitiy)) >= 0;
}
}
}
}
+/**
+ * Constructor.
+ *
+ * @param patterns a list of patterns with wildcards '*' (any string)
+ * @param caseSensitivity caseSensitive or caseInsensitive
+ * @param anchored <code>true<code>: the pattern starts at the strings
+ * start<br>
+ * <code>false<code>: the pattern can start anywhere in
+ * the string
+ */
+ReListMatcher::ReListMatcher(const QStringList& patterns,
+ Qt::CaseSensitivity caseSensitivty, bool anchored) :
+ m_patternList(patterns.size())
+{
+ QStringList::const_iterator it;
+ for (it = patterns.constBegin(); it != patterns.cend(); ++it){
+ m_list.append(new ReMatcher(*it, caseSensitivty, anchored));
+ }
+}
+/**
+ * Destructor.
+ */
+ReListMatcher::~ReListMatcher(){
+ QList<ReMatcher*>::const_iterator it;
+ for (it = m_list.constBegin(); it != patterns.cend(); ++it){
+ delete *it;
+ }
+ m_list.clear();
+}
+/**
+ * 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>
+ * <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 != patterns.cend(); ++it){
+ rc = it->matches(text);
+ }
+ return rc;
+}
+
+/**
+ * Constructor.
+ *
+ * @param includes a list of include patterns
+ * @param excludes a list of exclude patterns
+ * @param caseSensitivity caseSensitive or caseInsensitive
+ * @param anchored <code>true<code>: the pattern starts at the strings
+ * start<br>
+ * <code>false<code>: the pattern can start anywhere in
+ * the string
+ */
+ReIncludeExcludeMatcher::ReIncludeExcludeMatcher(const QStringList& includes,
+ const QStringList& excludes, Qt::CaseSensitivity caseSensitivty,
+ bool anchored) :
+ m_includes(includes, caseSensitivty, anchored),
+ m_excludes(excludes, caseSensitivty, anchored)
+{
+}
+
+/**
+ * Tests whether a text matches the include patterns and does not match the
+ * exclude patterns.
+ *
+ * @param text text to test
+ * @param excludeToo <code>true</code>: the exclude patterns will be tested
+ * @return <code>true</code>: at least one of the include patterns
+ * matches and none of the exclude patterns matches
+ */
+bool ReIncludeExcludeMatcher::matches(const QString& text, bool excludeToo)
+{
+ bool rc = m_includes.matches(text);
+ if (rc && excludeToo && m_excludes.size() > 0)
+ rc = ! m_excludes.matches(text);
+ return rc;
+}
#ifndef RPLQSTRING_HPP
#define RPLQSTRING_HPP
+/**
+ * Some useful static functions handling <code>QString</code> instances.
+ */
class ReQStringUtils {
public:
static ReString chomp(const ReString& text);
static QString& ensureLastChar(QString& value, QChar lastChar);
static ReString extensionOf(const ReString& filename);
static int lengthOfDate(const ReString& text, int start = 0, QDate* value =
- NULL);
+ NULL);
static int lengthOfDateTime(const ReString& text, int start = 0,
- bool allowDateOnly = true, bool allowTimeOnly = true, QDateTime* value =
- NULL);
+ bool allowDateOnly = true, bool allowTimeOnly = true, QDateTime* value =
+ NULL);
static int lengthOfReal(const ReString& text, int start = 0, qreal* value =
- NULL);
+ NULL);
static int lengthOfTime(const ReString& text, int start = 0, QTime* value =
- NULL);
+ NULL);
static int lengthOfUInt64(const ReString& text, int start = 0, int radix =
- 10, uint64_t* value = NULL);
+ 10, uint64_t* value = NULL);
static int lengthOfUInt(const ReString& text, int start, int radix,
- uint* pValue);
+ uint* pValue);
static bool match(const QString& heap, const QStringList& needles);
/**
* Returns the path with native path separators.
static QString pathAppend(const QString& base, const QString& path);
static QString replaceExtension(const QString& path, const QString& ext);
static bool replacePlaceholders(QString& text,
- const QMap<QString, QString>& placeholders, QString* error);
+ const QMap<QString, QString>& placeholders, QString* error);
static void skipExpected(const ReString& text, QChar expected, int& index,
- int& length);
+ int& length);
/**
* @brief Returns the value of a hexadecimal digit.
*
*/
inline static int valueOfHexDigit(int digit) {
return digit >= '0' && digit <= '9' ? digit - '0' :
- digit >= 'A' && digit <= 'F' ? digit - 'A' + 10 :
- digit >= 'a' && digit <= 'f' ? digit - 'a' + 10 : -1;
+ digit >= 'A' && digit <= 'F' ? digit - 'A' + 10 :
+ digit >= 'a' && digit <= 'f' ? digit - 'a' + 10 : -1;
}
static char* utf8(const ReString& source, char buffer[], size_t bufferSize);
};
+/**
+ * Calculates expressions with simple arithmetic and units.
+ *
+ * Allowed operators are '+', '-', '*', '/' and '^'.
+ * Parenthesis are not allowed.
+ *
+ * Example: 3*7k+8 means 21008
+ */
class ReUnitParser {
public:
ReUnitParser(const QString& expr, const char* unitList, bool parseAtOnce =
- true);
+ true);
public:
bool isValid() const;
const QString& errorMessage() const;
ReSizeParser(const QString& expr);
};
+/**
+ * Calculates time expressions.
+ *
+ * Syntax: { "now" | <date> [<time>] | <time> } [ { '+' | '-' } <second expr>]
+ * | <second expr>
+ * Example: now+3weeks-5*30days
+ */
class ReDateTimeParser: public ReUnitParser {
public:
ReDateTimeParser(const QString& expr);
QDateTime m_dateTime;
};
+/**
+ * Processor for efficient test whether a text matches a pattern ('*' for any string).
+ */
class ReMatcher {
public:
ReMatcher(const QString& pattern, Qt::CaseSensitivity caseSensitivty =
- Qt::CaseSensitive, bool anchored = false);
+ Qt::CaseSensitive, bool anchored = false);
public:
bool matches(const QString& text);
void setPattern(const QString& pattern);
Qt::CaseSensitivity m_caseSensivitiy;
};
+/**
+ * Processor for efficient test whether a text matches a list of patterns.
+ */
+class ReListMatcher {
+public:
+ ReListMatcher(const QStringList& patterns, Qt::CaseSensitivity caseSensitivty =
+ Qt::CaseSensitive, bool anchored = false);
+ ~ReListMatcher();
+public:
+ bool matches(const QString& text);
+protected:
+ QList<ReMatcher*> m_list;
+};
+
+/**
+ * Processor for efficient test whether a text matches an include pattern list
+ * and not an exclude pattern list.
+ */
+class ReIncludeExcludeMatcher{
+public:
+ ReIncludeExcludeMatcher(const QStringList& includes, const QStringList& excludes,
+ Qt::CaseSensitivity caseSensitivty = Qt::CaseSensitive,
+ bool anchored = false);
+public:
+ bool matches(const QString& text, bool excludeToo = true);
+protected:
+ ReListMatcher m_includes;
+ ReListMatcher m_excludes;
+};
+
#endif // RPLQSTRING_HPP
}
-bool ReFileSystem::getWriteable() const
+/**
+ * Returns whether the filesystem is writeable.
+ *
+ * @return <code>true</code>: modification in the filesystem are possible
+ * <code>false</code>: read only filesystem
+ */
+bool ReFileSystem::writeable() const
{
return m_writeable;
}
+/**
+ * Sets the filesystem to writeable or readonly.
+ *
+ * @param writeable <code>true</code>: the filesystem is writeable
+ */
void ReFileSystem::setWriteable(bool writeable)
{
m_writeable = writeable;
}
+/**
+ * Tests whether a node matches at least one entry of a pattern list.
+ * @param patterns the list of patterns to test
+ * @param node the filename to test
+ * @return <code>true</code>: at least one entry pattern matches
+ */
+bool ReFileSystem::match(const QStringList& patterns, const QString& node)
+{
+ QStringUtils::
+}
+
/**
* Constructor.
*/
* Can contain wildcard '*' (for any string)
* @return a list of the files matching the patterns
*/
-QList<ReFileMetaData*> ReLinuxFS::listInfos(const QString& pattern)
+QList<ReFileMetaData*> ReLinuxFS::listInfos(const QString& pattern,
+ const QStringList& excludePatterns)
{
QList<ReFileMetaData*> rc;
- m_dir.setNameFilters(patterns);
- QFileInfoList list = m_dir.entryInfoList();
- QFileInfoList::const_iterator it;
+ QStringList list = pattern.size() == 0 ? m_dir.entryList()
+ : m_dir.entryList(pattern);
+ 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++){
- const QFileInfo& info = *it;
- ReFileMetaData* meta = new ReFileMetaData(info.fileName());
-
+ 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);
+ }
}
+ return rc;
}