From 6d933a82518c8a8759dd4f97d0238c624d3cefb6 Mon Sep 17 00:00:00 2001 From: hama Date: Mon, 16 Mar 2015 00:24:57 +0100 Subject: [PATCH] ReThread improvements, refactoring, reformatting --- base/ReAppenders.cpp | 33 ++- base/ReAppenders.hpp | 6 +- base/ReBaseUtils.cpp | 11 + base/ReBaseUtils.hpp | 49 ++++ base/ReByteBuffer.cpp | 24 +- base/ReCString.cpp | 6 +- base/ReDirectory.cpp | 27 +- base/ReLogger.cpp | 19 +- base/ReLogger.hpp | 23 +- base/ReMutex.cpp | 10 +- base/ReMutex.hpp | 10 +- base/ReProgramArgs.cpp | 533 ++++++++++++++++++++------------------ base/ReProgramArgs.hpp | 23 +- base/ReSeqArray.hpp | 8 +- base/ReTestUnit.cpp | 22 +- base/ReThread.cpp | 309 +++++++++++++++++++--- base/ReThread.hpp | 52 +++- base/ReVarArgs.cpp | 8 + base/ReVarArgs.hpp | 6 +- base/rebase.hpp | 25 +- cunit/cuReByteBuffer.cpp | 2 +- cunit/cuReDirTools.cpp | 71 +++-- cunit/cuReException.cpp | 2 +- cunit/cuReLogger.cpp | 6 +- cunit/cuReProgramArgs.cpp | 18 +- cunit/cuReTCP.cpp | 139 ++++++---- cunit/cuReTraverser.cpp | 6 +- cunit/testall.cpp | 6 +- math/ReMD5.cpp | 46 ++-- math/ReMD5.hpp | 8 +- math/ReRPD64.cpp | 2 +- math/ReRPD64.hpp | 2 +- math/ReRandomizer.cpp | 8 +- net/ReTCP.cpp | 140 ++++++---- net/ReTCP.hpp | 57 ++-- net/ReUdpConnection.cpp | 167 ++++++------ net/ReUdpConnection.hpp | 20 +- os/ReDirTools.cpp | 417 +++++++++++++++-------------- os/ReDirTools.hpp | 15 +- os/ReTraverser.cpp | 56 ++-- os/ReTraverser.hpp | 9 +- os/reos.hpp | 6 +- string/ReMatcher.cpp | 11 +- 43 files changed, 1443 insertions(+), 975 deletions(-) create mode 100644 base/ReBaseUtils.cpp create mode 100644 base/ReBaseUtils.hpp diff --git a/base/ReAppenders.cpp b/base/ReAppenders.cpp index ddabf97..f483299 100644 --- a/base/ReAppenders.cpp +++ b/base/ReAppenders.cpp @@ -5,7 +5,7 @@ * Do what you want. * No warranties and disclaimer of any damages. * The latest sources: https://github.com/republib -*/ + */ #include "base/rebase.hpp" /** @@ -14,15 +14,14 @@ * @param maxLines if more lines are availabe, the oldest will be deleted */ ReMemoryAppender::ReMemoryAppender(int maxLines) : - ReAppender(), - ReSeqArray(), - m_maxLines(maxLines) -{ + ReAppender(), + ReSeqArray(), + m_maxLines(maxLines) { setCapacity(maxLines, maxLines * 80); // no tag, content < 2**24 Byte - setSizes(0, maxLines < 100*1000 ? 3 : 4); + setSizes(0, maxLines < 100 * 1000 ? 3 : 4); } -ReMemoryAppender::~ReMemoryAppender(){ +ReMemoryAppender::~ReMemoryAppender() { } /** @@ -32,11 +31,11 @@ ReMemoryAppender::~ReMemoryAppender(){ * @param append truethe buffer will not truncated before storage * @return buffer (for chaining) */ -ReByteBuffer& ReMemoryAppender::join(ReByteBuffer& buffer, bool append){ +ReByteBuffer& ReMemoryAppender::join(ReByteBuffer& buffer, bool append) { ReByteBuffer current; - if (! append) + if (!append) buffer.setLength(0); - for (int ix = count() - 1; ix >= 0; ix--){ + for (int ix = count() - 1; ix >= 0; ix--) { get(ix, current); buffer.append(current).appendChar('\n'); } @@ -48,7 +47,7 @@ ReByteBuffer& ReMemoryAppender::join(ReByteBuffer& buffer, bool append){ * @param logger the caller * @param message the logging message to store */ -void ReMemoryAppender::say(ReLogger* logger, const char* message){ +void ReMemoryAppender::say(ReLogger* logger, const char* message) { int theCount = count(); if (theCount >= m_maxLines) remove(theCount - 1); @@ -65,13 +64,13 @@ void ReMemoryAppender::say(ReLogger* logger, const char* message){ * to distinct the threads in the log */ ReSlaveAppender::ReSlaveAppender(ReLogger* masterLogger, char charPrefix) : - m_masterLogger(masterLogger), - m_charPrefix(charPrefix) { + m_masterLogger(masterLogger), + m_charPrefix(charPrefix) { } /** * Destructor. */ -ReSlaveAppender::~ReSlaveAppender(){ +ReSlaveAppender::~ReSlaveAppender() { } /** * Writes the message to the master logger. @@ -79,9 +78,9 @@ ReSlaveAppender::~ReSlaveAppender(){ * @param logger the caller * @param message the logging message to store */ -void ReSlaveAppender::say(ReLogger* logger, const char* message){ +void ReSlaveAppender::say(ReLogger* logger, const char* message) { ReByteBuffer buffer(logger->standardPrefix(m_charPrefix)); buffer.append(message == NULL ? logger->asCString() : message); - m_masterLogger->say(logger->currentMode(), - logger->currentLocation(), buffer.str()); + m_masterLogger->say(logger->currentMode(), logger->currentLocation(), + buffer.str()); } diff --git a/base/ReAppenders.hpp b/base/ReAppenders.hpp index 783ce6c..5e58cfe 100644 --- a/base/ReAppenders.hpp +++ b/base/ReAppenders.hpp @@ -9,7 +9,7 @@ * These classes are separated from ReLogger.hpp because of the serialization * of classes (or include files): * ReLogger depends on few classes, but many classes are depending on ReLogger. -*/ + */ #ifndef BASE_REAPPENDERS_HPP_ #define BASE_REAPPENDERS_HPP_ @@ -43,7 +43,7 @@ protected: * (say().arg().end() it is not possible to protect the argument * preparation in a thread safe manner. */ -class ReSlaveAppender : public ReAppender { +class ReSlaveAppender: public ReAppender { public: ReSlaveAppender(ReLogger* masterLogger, char charPrefix = '\0'); virtual ~ReSlaveAppender(); @@ -52,7 +52,7 @@ public: /** Sets the master logger. * @param logger the master logger */ - void setMasterLogger(ReLogger* logger){ + void setMasterLogger(ReLogger* logger) { m_masterLogger = logger; } private: diff --git a/base/ReBaseUtils.cpp b/base/ReBaseUtils.cpp new file mode 100644 index 0000000..772fac3 --- /dev/null +++ b/base/ReBaseUtils.cpp @@ -0,0 +1,11 @@ +/* + * ReBaseUtils.cpp + * + * License: Public domain + * Do what you want. + * No warranties and disclaimer of any damages. + * The latest sources: https://github.com/republib + */ + +#include "base/rebase.hpp" + diff --git a/base/ReBaseUtils.hpp b/base/ReBaseUtils.hpp new file mode 100644 index 0000000..f028701 --- /dev/null +++ b/base/ReBaseUtils.hpp @@ -0,0 +1,49 @@ +/* + * ReBaseUtils.hpp + * + * License: Public domain + * Do what you want. + * No warranties and disclaimer of any damages. + * The latest sources: https://github.com/republib + */ + +#ifndef BASE_REBASEUTILS_HPP_ +#define BASE_REBASEUTILS_HPP_ + +/** + * Common static methods. + */ +class ReBaseUtils { +public: + /** Calculates the time since a given start. + * + *
int64_t start = ReBaseUtils::timer();
+	 * ...
+	 * int duration = ReBaseUtils::milliSecSince(start);
+	 * 
+ * + * @return a time usable for for runtime measurement + */ + static inline int milliSecSince(int64_t start) { +# if defined __linux__ || defined __WIN32__ + int64_t diff = clock() - start; + return int(diff * 1000 / CLOCKS_PER_SEC); +# endif + } + /** Returns a time value usable for runtime measurement. + * + * Note: The value is platform dependent. Use with milliSecSince(). + *
int64_t start = test.timer();
+	 * ...
+	 * int duration = test.milliSecSince(start);
+	 * 
+ * @return a time usable for for runtime measurement + */ + static inline int64_t timer() { +# if defined __linux__ || defined __WIN32__ + return clock(); +# endif + } +}; + +#endif /* BASE_REBASEUTILS_HPP_ */ diff --git a/base/ReByteBuffer.cpp b/base/ReByteBuffer.cpp index 9477746..2447077 100644 --- a/base/ReByteBuffer.cpp +++ b/base/ReByteBuffer.cpp @@ -10,10 +10,10 @@ #include "base/rebase.hpp" #ifdef __linux__ -extern void* memcpy (void* dest, const void* src, size_t n); -extern void* memmove (void* dest, const void* src, size_t n); +extern void* memcpy(void* dest, const void* src, size_t n); +extern void* memmove(void* dest, const void* src, size_t n); extern int _memcmp (const void* s1, const void* s2, size_t n); -extern int _snprintf (char* s, size_t maxlen, const char* format, ...); +extern int _snprintf(char* s, size_t maxlen, const char* format, ...); #endif /** @brief Constructor. @@ -113,12 +113,14 @@ ReByteBuffer& ReByteBuffer::operator =(const ReByteBuffer& source) { * @return *this (for chaining) */ ReByteBuffer& ReByteBuffer::append(const Byte* source, size_t length) { - if (length == (size_t) -1) - length = strlen(source); - ensureSize(m_length + length); - memcpy((void*) (m_buffer + m_length), source, length); - m_length += length; - m_buffer[m_length] = '\0'; + if (source != NULL) { + if (length == (size_t) -1) + length = strlen(source); + ensureSize(m_length + length); + memcpy((void*) (m_buffer + m_length), source, length); + m_length += length; + m_buffer[m_length] = '\0'; + } return *this; } /** @brief Appends the content of another ReByteBuffer instance at the end of the buffer. @@ -674,8 +676,8 @@ int ReByteBuffer::rindexOf(const Byte* toFind, size_t toFindLength, int start, int current = end - toFindLength; while (current >= start) { if (ignoreCase ? - _strnicmp(toFind, m_buffer + current, toFindLength) != 0 : - _memcmp(toFind, m_buffer + current, toFindLength) != 0) + _strnicmp(toFind, m_buffer + current, toFindLength) != 0 : + _memcmp(toFind, m_buffer + current, toFindLength) != 0) current--; else { rc = current; diff --git a/base/ReCString.cpp b/base/ReCString.cpp index 28e7b01..63725f8 100644 --- a/base/ReCString.cpp +++ b/base/ReCString.cpp @@ -54,8 +54,7 @@ void replaceSubstring(char* start, size_t bufferSize, size_t lengthReplaced, * < 0: region1 is alphabetically less than region2
* > 0: region1 is alphabetically greater than region2 */ -int _memicmp(const void* region1, const void* region2, int size) -{ +int _memicmp(const void* region1, const void* region2, int size) { unsigned char* ptr1 = (unsigned char*) region1; unsigned char* ptr2 = (unsigned char*) region2; int rc = 0; @@ -63,8 +62,7 @@ int _memicmp(const void* region1, const void* region2, int size) unsigned char cc1 = *ptr1++; unsigned char cc2 = *ptr2++; int diff = tolower(cc1) - tolower(cc2); - if (diff != 0) - { + if (diff != 0) { rc = diff; break; } diff --git a/base/ReDirectory.cpp b/base/ReDirectory.cpp index 83411c2..ab27440 100644 --- a/base/ReDirectory.cpp +++ b/base/ReDirectory.cpp @@ -66,7 +66,7 @@ void ReDirectory::close() { m_valid = false; } if (m_regExprIsInitialized) - regfree(&m_regExpr); + regfree(&m_regExpr); #elif defined __WIN32__ if (m_handle != INVALID_HANDLE_VALUE) { FindClose(m_handle); @@ -105,8 +105,7 @@ void ReDirectory::deleteTree(const char* base, bool deleteBaseToo) { struct stat info; const char* node = dir.currentFile(); if ((!(node[0] == '.' - && (node[1] == '\0' - || (node[1] == '.' && node[2] == '\0')))) + && (node[1] == '\0' || (node[1] == '.' && node[2] == '\0')))) && stat(dir.fullpath(full).str(), &info) == 0) { if (S_ISDIR(info.st_mode)) deleteTree(full.str(), true); @@ -145,7 +144,7 @@ bool ReDirectory::findFirst(const char* pattern, bool isRegExpr) { m_isRegExpr = isRegExpr; if (isRegExpr) { if (m_regExprIsInitialized) - regfree(&m_regExpr); + regfree(&m_regExpr); int rc2 = regcomp(&m_regExpr, pattern, m_regExprFlags); m_regExprIsInitialized = true; @@ -179,15 +178,16 @@ bool ReDirectory::findNext() { bool rc = false; if (m_valid) { #if defined __linux__ - while (! rc && (m_entry = readdir(m_dir)) != NULL) { + while (!rc && (m_entry = readdir(m_dir)) != NULL) { if (m_isRegExpr) { regmatch_t match[10]; - int rc2 = regexec (&m_regExpr, m_entry->d_name, sizeof match / sizeof match[0], match, 0); + int rc2 = regexec(&m_regExpr, m_entry->d_name, + sizeof match / sizeof match[0], match, 0); if (rc2 == 0) - rc = true; + rc = true; } else { if (fnmatch(m_pattern.str(), m_entry->d_name, 0) == 0) - rc = true; + rc = true; } } #elif defined __WIN32__ @@ -211,8 +211,7 @@ bool ReDirectory::findYoungest(ReByteBuffer& filename) { ReByteBuffer fullname; #if defined __linux__ - if (m_entry != NULL) - { + if (m_entry != NULL) { fullname.append(m_path); size_t length = fullname.length(); struct stat info; @@ -222,15 +221,15 @@ bool ReDirectory::findYoungest(ReByteBuffer& filename) { fullname.setLength(length); fullname.append(m_entry->d_name, -1); if (stat(fullname.str(), &info) == 0 - && (info.st_mtim.tv_sec > youngest.tv_sec - || (info.st_mtim.tv_sec == youngest.tv_sec - && info.st_mtim.tv_nsec > youngest.tv_nsec))) { + && (info.st_mtim.tv_sec > youngest.tv_sec + || (info.st_mtim.tv_sec == youngest.tv_sec + && info.st_mtim.tv_nsec > youngest.tv_nsec))) { youngest = info.st_mtim; filename.set(m_entry->d_name, -1); rc = true; } - }while(findNext()); + } while (findNext()); } #elif defined __WIN32__ FILETIME youngest; diff --git a/base/ReLogger.cpp b/base/ReLogger.cpp index 07f37fc..7294b47 100644 --- a/base/ReLogger.cpp +++ b/base/ReLogger.cpp @@ -13,7 +13,8 @@ enum RELOC_SEQARRAY { LC_LOGGER_1 = LC_LOGGER + 1, // 50701 }; #ifdef __linux__ -extern size_t strftime (char* s, size_t maxsize, const char* format, const struct tm* tp); +extern size_t strftime(char* s, size_t maxsize, const char* format, + const struct tm* tp); #endif ReLogger* ReLogger::m_globalLogger = NULL; @@ -301,7 +302,7 @@ ReLogger::~ReLogger() { */ bool ReLogger::say(ReClassCategoryGranularity mode, ReLogLocation location, const char* message) { - m_mutex.wait(); + m_mutex.lock(); m_mode = mode; m_location = location; m_standardPrefix[0] = '\0'; @@ -311,7 +312,7 @@ bool ReLogger::say(ReClassCategoryGranularity mode, ReLogLocation location, if (app->accept(mode)) app->say(this, message); } - m_mutex.release(); + m_mutex.unlock(); return true; } /** @brief Issues a log message. @@ -326,8 +327,8 @@ bool ReLogger::say(ReClassCategoryGranularity mode, ReLogLocation location, * @return true */ bool ReLogger::say(char prefix, ReClassCategoryGranularity mode, - ReLogLocation location, const char* message) { - m_mutex.wait(); + ReLogLocation location, const char* message) { + m_mutex.lock(); char safePrefix = m_charPrefix; m_charPrefix = prefix; m_mode = mode; @@ -340,7 +341,7 @@ bool ReLogger::say(char prefix, ReClassCategoryGranularity mode, app->say(this, message); } m_charPrefix = safePrefix; - m_mutex.release(); + m_mutex.unlock(); return true; } @@ -358,8 +359,8 @@ bool ReLogger::say(char prefix, ReClassCategoryGranularity mode, * @return true */ ReVarArgs& ReLogger::sayF(ReClassCategoryGranularity mode, - ReLogLocation location, const char* format) { - m_mutex.wait(); + ReLogLocation location, const char* format) { + m_mutex.lock(); if (m_locationOfOpenSayF != 0) { char message[128]; _snprintf(message, sizeof message, @@ -371,7 +372,7 @@ ReVarArgs& ReLogger::sayF(ReClassCategoryGranularity mode, m_location = location; m_standardPrefix[0] = '\0'; reset(format); - m_mutex.release(); + m_mutex.unlock(); return *this; } /** Adds an appender to the appender list. diff --git a/base/ReLogger.hpp b/base/ReLogger.hpp index d7e112a..607abee 100644 --- a/base/ReLogger.hpp +++ b/base/ReLogger.hpp @@ -153,20 +153,20 @@ public: virtual void end(void); bool say(ReClassCategoryGranularity mode, ReLogLocation location, const char* message); - bool say(char prefix, ReClassCategoryGranularity mode, ReLogLocation location, - const char* message); + bool say(char prefix, ReClassCategoryGranularity mode, + ReLogLocation location, const char* message); ReVarArgs& sayF(ReClassCategoryGranularity mode, ReLogLocation location, const char* format); /** Returns the current mode of the logging call. * @return the current mode (class, category and granularity) */ - inline ReClassCategoryGranularity currentMode(void) const{ + inline ReClassCategoryGranularity currentMode(void) const { return m_mode; } /** Returns the current location of the logging call. * @return the current location */ - inline ReLogLocation currentLocation(void) const{ + inline ReLogLocation currentLocation(void) const { return m_location; } const char* standardPrefix(char prefix = '\0'); @@ -186,6 +186,21 @@ private: }; +/** + * Connect classes with multiple base classes to use only one logger. + */ +class ReLoggerOwner { +public: + virtual ~ReLoggerOwner() { + } +public: + virtual ReLogger* logger() = 0; +}; +/** + * Returns the global logger. + * + * @param the global logger + */ inline ReLogger* globalLogger() { return ReLogger::globalLogger(); } diff --git a/base/ReMutex.cpp b/base/ReMutex.cpp index 1d16294..dae5259 100644 --- a/base/ReMutex.cpp +++ b/base/ReMutex.cpp @@ -16,13 +16,13 @@ */ ReMutex::ReMutex(int location, int maxWaitSec) : #if defined __linux__ - m_mutex(), + m_mutex(), #elif defined __WIN32__ - m_mutex(0), + m_mutex(0), #endif - m_maxWaitSec(maxWaitSec){ + m_maxWaitSec(maxWaitSec) { #if defined __linux__ - sem_init(&m_mutex, 0, 0); + sem_init(&m_mutex, 0, 1); #elif defined __WIN32__ m_mutex = CreateMutex(NULL, FALSE, NULL); #endif @@ -39,7 +39,7 @@ ReMutex::~ReMutex() { #endif } -bool ReMutex::timedWait(int sec){ +bool ReMutex::timedLock(int sec) { bool rc = true; #if defined __linux__ struct timespec time; diff --git a/base/ReMutex.hpp b/base/ReMutex.hpp index f851887..138a05b 100644 --- a/base/ReMutex.hpp +++ b/base/ReMutex.hpp @@ -15,17 +15,17 @@ public: ReMutex(int location, int maxWaitSec = -1); virtual ~ReMutex(); public: - inline void release(){ + bool timedLock(int sec = -1); + inline void lock() { #if defined __linux__ - sem_post(&m_mutex); + sem_wait(&m_mutex); #elif defined __WIN32__ #error "mutex in ReMutex missed" #endif } - bool timedWait(int sec = -1); - inline void wait(){ + inline void unlock() { #if defined __linux__ - sem_wait(&m_mutex); + sem_post(&m_mutex); #elif defined __WIN32__ #error "mutex in ReMutex missed" #endif diff --git a/base/ReProgramArgs.cpp b/base/ReProgramArgs.cpp index 637caf9..2cc0779 100644 --- a/base/ReProgramArgs.cpp +++ b/base/ReProgramArgs.cpp @@ -48,6 +48,7 @@ ReProgramArgs::ReProgramArgs(const char* usageList[], const char* examples[]) : m_values(), m_args(NULL), m_argCount(0), + m_program(NULL), m_lastError() { m_properties.setCapacity(64, 64 * 8, 64 * 1024); ReByteBuffer line; @@ -155,38 +156,38 @@ static const int IxLong = 2; static const int IxType = 3; static const int IxDefault = 4; -/** @brief Adds an option with an integer value. +/** @brief Adds an option with a boolean value. * - * @param name The name of the option. Used in the methods getInt(). + * @param name The name of the option. Used in the methods getBool(). * @param description A short description of the option. Used in the user messages. * @param shortOpt The one character option identifier. Used in the arguments. Must be preceded by '-'. * @param longOpt The multi character option identifier. Used in the arguments. Must be preceded by '--'. * @param defaultValue The default value of the option. * - * * @see getInt() + * @see getBool() */ -void ReProgramArgs::addInt(const char* name, const char* description, - char shortOpt, const char* longOpt, int defaultVal) { - ReByteBuffer number; - number.appendInt(defaultVal); - addProperties(name, description, shortOpt, longOpt, DT_INT, number.str(), - number.length()); +void ReProgramArgs::addBool(const char* name, const char* description, + char shortOpt, const char* longOpt, bool defaultVal) { + addProperties(name, description, shortOpt, longOpt, DT_BOOL, + defaultVal ? "t" : "f", 1); } -/** @brief Adds an option with a boolean value. +/** @brief Adds an option with an integer value. * - * @param name The name of the option. Used in the methods getBool(). + * @param name The name of the option. Used in the methods getInt(). * @param description A short description of the option. Used in the user messages. * @param shortOpt The one character option identifier. Used in the arguments. Must be preceded by '-'. * @param longOpt The multi character option identifier. Used in the arguments. Must be preceded by '--'. * @param defaultValue The default value of the option. * - * @see getBool() + * * @see getInt() */ -void ReProgramArgs::addBool(const char* name, const char* description, - char shortOpt, const char* longOpt, bool defaultVal) { - addProperties(name, description, shortOpt, longOpt, DT_BOOL, - defaultVal ? "t" : "f", 1); +void ReProgramArgs::addInt(const char* name, const char* description, + char shortOpt, const char* longOpt, int defaultVal) { + ReByteBuffer number; + number.appendInt(defaultVal); + addProperties(name, description, shortOpt, longOpt, DT_INT, number.str(), + number.length()); } /** @brief Adds an option with a string value. @@ -207,184 +208,67 @@ void ReProgramArgs::addString(const char* name, const char* description, defaultVal == NULL ? 0 : strlen(defaultVal)); } -/** @brief Returns the value of a boolean option. - * - * @param name Name of the option. - * - * @return The value of the option set in the programs arguments or the default value. - * - * @throws ReOptionException Unknown name or wrong type. - */ -bool ReProgramArgs::getBool(const char* name) { - ReStringList properties(512, 1024, 2, 2); - ReByteBuffer buffer; - ReVarArgs args; - if (!m_properties.get(name, -1, buffer)) - throw ReOptionException(this, i18n("$1 is not an option name"), name); - - properties.split(buffer.str(), '\1'); - if (properties.strOf(IxType)[0] != 'b') - throw ReOptionException(this, - i18n("$1 is not an boolean option. Type is $2"), name, - properties.strOf(IxType)); - - m_values.get(name, -1, buffer); - bool rc = buffer.at(1) == 't'; - return rc; -} - -/** @brief Returns the value of an integer option. - * - * @param name Name of the option. - * - * @return The value of the option set in the programs arguments or the default value. - * - * @throws ReOptionException Unknown name or wrong type. - */ -int ReProgramArgs::getInt(const char* name) { - ReStringList properties(512, 1024, 2, 2); - ReByteBuffer buffer; - ReVarArgs args; - if (!m_properties.get(name, -1, buffer)) - throw ReOptionException(this, i18n("$1 is not an option name"), name); - - properties.split(buffer.str(), '\1'); - if (properties.strOf(IxType)[0] != DT_INT) - throw ReOptionException(this, - i18n("$1 is not an integer option. Type is $2"), name, - properties.strOf(IxType)); - - m_values.get(name, -1, buffer); - int rc = buffer.atoi(1); - return rc; -} - -/** @brief Returns the value of a string option. +/** @brief Analyses a long name option. * - * @param name Name of the option. + * The syntax of an long name option is --name or --name=value * - * @return The value of the option set in the programs arguments or the default value. + * @param opt The option string without --. * - * @throws ReOptionException Unknown name or wrong type. */ -const char* ReProgramArgs::getString(const char* name, ReByteBuffer& buffer) { +void ReProgramArgs::analyseLong(const char* opt) { ReStringList properties(512, 1024, 2, 2); - ReVarArgs args; - if (!m_properties.get(name, strlen(name), buffer)) - throw ReOptionException(this, i18n("$1 is not an option name"), name); - - properties.split(buffer.str(), '\1'); - DataType dataType = (DataType) properties.strOf(IxType)[0]; - if (dataType != DT_STRING && dataType != DT_STRING_EMPTY) - throw ReOptionException(this, - i18n("$1 is not a string option. Type is $2"), name, - properties.strOf(IxType)); - - m_values.get(name, -1, buffer); - buffer.remove(0, 1); - const char* rc = buffer.buffer(); - return rc; -} - -/** @brief Returns the count of arguments (without options). - * - * @return The count of arguments. - */ -int ReProgramArgs::getArgCount() const { - return m_argCount; -} - -/** @brief Returns a not option argument given by an index. - * - * @param index The index of the wanted program argument which is not an option. - * - * @return NULL: Wrong index. Otherwise: The wanted argument. - */ -const char* ReProgramArgs::getArg(size_t index) const { - const char* rc = NULL; + ReByteBuffer name; + search('\0', opt, name, properties); - if (index < (size_t) m_argCount) - rc = m_args[index]; - return rc; -} -/** @brief Returns the program name. - * - * @return The name of the application. - */ -const char* ReProgramArgs::getProgramName() const { - return m_program; -} + const char* nameStr = name.str(); + const char* dataType = properties.strOf(IxType); + const char* value = strchr(opt, '='); + if (value != NULL) + value++; -/** @brief Search the property string of an option. - * - * @param shortName The option`s short name. Not relevant if longName != NULL. - * @param LongName The option`s long name. Not relevant if longName == NULL. - * @param name Out: The name of the option. - * @param list Out: The properties are returned in this list. - * - * @throws ReOptionException Unknown option. - */ -void ReProgramArgs::search(char shortName, const char* longName, - ReByteBuffer& name, ReStringList& list) { - ReArrayPosition position; - ReByteBuffer properties; - bool found = false; - size_t lengthLongName = 0; - if (longName != NULL) { - const char* ptr; - if ((ptr = strchr(longName, '=')) != NULL) - lengthLongName = ptr - longName; - else - lengthLongName = strlen(longName); - } - while (!found && m_properties.next(position, &name, &properties)) { - list.split(properties.str(), '\1'); - if (longName == NULL && list.count() > IxShort - && shortName == list.strOf(IxShort)[0]) - found = true; - else if (lengthLongName > 0 && list.count() > IxLong - && list.sizeOf(IxLong) == lengthLongName + 1 - && strncmp(longName, list.strOf(IxLong), lengthLongName) == 0) - found = true; - } - if (!found) { - if (longName == NULL) - name.set(&shortName, 1); - else - name.set(longName, lengthLongName); - throw ReOptionException(this, i18n("Unknown option: $1"), name.str()); - } -} -/** @brief Sets the option value. - * - * @param name The option's name. - * @param value The option's value. - * @param dataType Theo option's data type. - */ -void ReProgramArgs::setValue(const char* name, const char* value, - const char* dataType) { switch (dataType[0]) { case DT_INT: - if (strspn(value, "01234567890") != strlen(value)) + if (value == NULL) throw ReOptionException(this, - i18n("Option $1 expect an integer as parameter, not $2"), name, - value); + i18n("Option $1: parameter expected. Use --$2=number"), nameStr, + nameStr); + else + setValue(nameStr, value, dataType); break; case DT_STRING: - if (value[0] == '\0') + if (value == NULL) throw ReOptionException(this, - i18n("Option $1: Empty parameter is not allowed"), name); + i18n("Option $1: parameter expected. Use --$2=string"), nameStr, + nameStr); + setValue(nameStr, value, dataType); break; case DT_STRING_EMPTY: - case DT_BOOL: + if (value == NULL) + value = ""; + setValue(nameStr, value, dataType); + break; + case DT_BOOL: { + const char* boolValue = "f"; + if (value == NULL + || ReStringUtils::isInList(value, ReConfigFile::m_trueValues, true, + ReStringUtils::AUTO_SEPARATOR)) + boolValue = "t"; + else if (!ReStringUtils::isInList(value, ReConfigFile::m_falseValues, + true, ReStringUtils::AUTO_SEPARATOR)) + throw ReOptionException(this, + i18n("Option $1: Not a boolean value: $2. Use true or false"), + nameStr, value); + // Invert the default value: + if (properties.strOf(IxDefault)[0] == 't') + boolValue = boolValue[0] == 't' ? "f" : "t"; + setValue(nameStr, boolValue, dataType); + break; + } default: break; } - ReByteBuffer buffer; - // First character says: defined. - buffer.appendChar(' ').append(value, -1); - m_values.put(name, buffer.str()); } + /** @brief Analyses one or more short name options. * * Multiple short name options can be written in one word: @@ -457,102 +341,115 @@ bool ReProgramArgs::analyseShort(const char* opt, const char* nextArg) { } while (again); return rc; } -/** @brief Analyses a long name option. - * - * The syntax of an long name option is --name or --name=value + +/** @brief Returns a not option argument given by an index. * - * @param opt The option string without --. + * @param index The index of the wanted program argument which is not an option. * + * @return NULL: Wrong index. Otherwise: The wanted argument. */ -void ReProgramArgs::analyseLong(const char* opt) { - ReStringList properties(512, 1024, 2, 2); - ReByteBuffer name; - search('\0', opt, name, properties); +const char* ReProgramArgs::arg(size_t index) const { + const char* rc = NULL; - const char* nameStr = name.str(); - const char* dataType = properties.strOf(IxType); - const char* value = strchr(opt, '='); - if (value != NULL) - value++; + if (index < (size_t) m_argCount) + rc = m_args[index]; + return rc; +} - switch (dataType[0]) { - case DT_INT: - if (value == NULL) - throw ReOptionException(this, - i18n("Option $1: parameter expected. Use --$2=number"), nameStr, - nameStr); - else - setValue(nameStr, value, dataType); - break; - case DT_STRING: - if (value == NULL) - throw ReOptionException(this, - i18n("Option $1: parameter expected. Use --$2=string"), nameStr, - nameStr); - setValue(nameStr, value, dataType); - break; - case DT_STRING_EMPTY: - if (value == NULL) - value = ""; - setValue(nameStr, value, dataType); - break; - case DT_BOOL: { - const char* boolValue = "f"; - if (value == NULL - || ReStringUtils::isInList(value, ReConfigFile::m_trueValues, true, - ReStringUtils::AUTO_SEPARATOR)) - boolValue = "t"; - else if (!ReStringUtils::isInList(value, ReConfigFile::m_falseValues, - true, ReStringUtils::AUTO_SEPARATOR)) - throw ReOptionException(this, - i18n("Option $1: Not a boolean value: $2. Use true or false"), - nameStr, value); - // Invert the default value: - if (properties.strOf(IxDefault)[0] == 't') - boolValue = boolValue[0] == 't' ? "f" : "t"; - setValue(nameStr, boolValue, dataType); - break; - } - default: - break; - } +/** @brief Returns the count of arguments (without options). + * + * @return The count of arguments. + */ +int ReProgramArgs::argCount() const { + return m_argCount; } -/** @brief Initializes the options from the program arguments. + +/** @brief Returns the value of a boolean option. * - * While arguments are preceded by an '-' they will be treated as options. - * The rest of arguments are stored for retrieving with getArg(). + * @param name Name of the option. * - * @param argc The count of program arguments (inclusive options). - * @param argv The argument vector. + * @return The value of the option set in the programs arguments or the default value. * - * @throws ReException + * @throws ReOptionException Unknown name or wrong type. */ -void ReProgramArgs::init(int argc, const char* argv[]) { - m_program = argv[0]; - argv++; - argc--; +bool ReProgramArgs::getBool(const char* name) { + ReStringList properties(512, 1024, 2, 2); + ReByteBuffer buffer; + ReVarArgs args; + if (!m_properties.get(name, -1, buffer)) + throw ReOptionException(this, i18n("$1 is not an option name"), name); - while (argc > 0 && argv[0][0] == '-') { - if (argv[0][1] == '-') - analyseLong(argv[0] + 2); - else { - if (analyseShort(argv[0] + 1, argc <= 1 ? NULL : argv[1])) - argc--, argv++; - } - argc--; - argv++; - } - m_argCount = argc; - m_args = (const char**) argv; + properties.split(buffer.str(), '\1'); + if (properties.strOf(IxType)[0] != 'b') + throw ReOptionException(this, + i18n("$1 is not an boolean option. Type is $2"), name, + properties.strOf(IxType)); + + m_values.get(name, -1, buffer); + bool rc = buffer.at(1) == 't'; + return rc; } -/** @brief Sets the last error message. + +/** @brief Returns the value of an integer option. * - * @param message The error message. + * @param name Name of the option. + * + * @return The value of the option set in the programs arguments or the default value. + * + * @throws ReOptionException Unknown name or wrong type. */ -void ReProgramArgs::setLastError(const char* message) { - m_lastError.set(message, -1); +int ReProgramArgs::getInt(const char* name) { + ReStringList properties(512, 1024, 2, 2); + ReByteBuffer buffer; + ReVarArgs args; + if (!m_properties.get(name, -1, buffer)) + throw ReOptionException(this, i18n("$1 is not an option name"), name); + + properties.split(buffer.str(), '\1'); + if (properties.strOf(IxType)[0] != DT_INT) + throw ReOptionException(this, + i18n("$1 is not an integer option. Type is $2"), name, + properties.strOf(IxType)); + + m_values.get(name, -1, buffer); + int rc = buffer.atoi(1); + return rc; +} + +/** @brief Returns the value of a string option. + * + * @param name Name of the option. + * + * @return The value of the option set in the programs arguments or the default value. + * + * @throws ReOptionException Unknown name or wrong type. + */ +const char* ReProgramArgs::getString(const char* name, ReByteBuffer& buffer) { + ReStringList properties(512, 1024, 2, 2); + ReVarArgs args; + if (!m_properties.get(name, strlen(name), buffer)) + throw ReOptionException(this, i18n("$1 is not an option name"), name); + + properties.split(buffer.str(), '\1'); + DataType dataType = (DataType) properties.strOf(IxType)[0]; + if (dataType != DT_STRING && dataType != DT_STRING_EMPTY) + throw ReOptionException(this, + i18n("$1 is not a string option. Type is $2"), name, + properties.strOf(IxType)); + + m_values.get(name, -1, buffer); + buffer.remove(0, 1); + const char* rc = buffer.buffer(); + return rc; } +/** + * Issues a help message. + * + * @param message message to show + * @param issueLastError true: the last OS error will be shown + * @param lines OUT: a stringlist for the help message + */ void ReProgramArgs::help(const char* message, bool issueLastError, ReStringList& lines) const { lines.append(m_usage); @@ -623,7 +520,13 @@ void ReProgramArgs::help(const char* message, bool issueLastError, lines.append(line.str()); } } - +/** + * Issues a help message. + * + * @param message message to show + * @param issueLastError true: the last OS error will be shown + * @param stream OUT: output stream, e.g. stderr + */ void ReProgramArgs::help(const char* message, bool issueLastError, FILE* stream) const { ReStringList lines(512, 1024, 8, 2); @@ -633,3 +536,121 @@ void ReProgramArgs::help(const char* message, bool issueLastError, fputc('\n', stream); } } + +/** @brief Initializes the options from the program arguments. + * + * While arguments are preceded by an '-' they will be treated as options. + * The rest of arguments are stored for retrieving with getArg(). + * + * @param argc The count of program arguments (inclusive options). + * @param argv The argument vector. + * + * @throws ReException + */ +void ReProgramArgs::init(int argc, const char* argv[]) { + m_program = argv[0]; + argv++; + argc--; + + while (argc > 0 && argv[0][0] == '-') { + if (argv[0][1] == '-') + analyseLong(argv[0] + 2); + else { + if (analyseShort(argv[0] + 1, argc <= 1 ? NULL : argv[1])) + argc--, argv++; + } + argc--; + argv++; + } + m_argCount = argc; + m_args = (const char**) argv; +} + +/** @brief Returns the program name. + * + * @return The name of the application. + */ +const char* ReProgramArgs::programName() const { + return m_program; +} + +/** @brief Search the property string of an option. + * + * @param shortName The option`s short name. Not relevant if longName != NULL. + * @param LongName The option`s long name. Not relevant if longName == NULL. + * @param name Out: The name of the option. + * @param list Out: The properties are returned in this list. + * + * @throws ReOptionException Unknown option. + */ +void ReProgramArgs::search(char shortName, const char* longName, + ReByteBuffer& name, ReStringList& list) { + ReArrayPosition position; + ReByteBuffer properties; + bool found = false; + size_t lengthLongName = 0; + if (longName != NULL) { + const char* ptr; + if ((ptr = strchr(longName, '=')) != NULL) + lengthLongName = ptr - longName; + else + lengthLongName = strlen(longName); + } + while (!found && m_properties.next(position, &name, &properties)) { + list.split(properties.str(), '\1'); + if (longName == NULL && list.count() > IxShort + && shortName == list.strOf(IxShort)[0]) + found = true; + else if (lengthLongName > 0 && list.count() > IxLong + && list.sizeOf(IxLong) == lengthLongName + 1 + && strncmp(longName, list.strOf(IxLong), lengthLongName) == 0) + found = true; + } + if (!found) { + if (longName == NULL) + name.set(&shortName, 1); + else + name.set(longName, lengthLongName); + throw ReOptionException(this, i18n("Unknown option: $1"), name.str()); + } +} + +/** @brief Sets the last error message. + * + * @param message The error message. + */ +void ReProgramArgs::setLastError(const char* message) { + m_lastError.set(message, -1); +} + +/** @brief Sets the option value. + * + * @param name The option's name. + * @param value The option's value. + * @param dataType Theo option's data type. + */ +void ReProgramArgs::setValue(const char* name, const char* value, + const char* dataType) { + switch (dataType[0]) { + case DT_INT: + if (strspn(value, "01234567890") != strlen(value)) + throw ReOptionException(this, + i18n("Option $1 expect an integer as parameter, not $2"), name, + value); + break; + case DT_STRING: + if (value[0] == '\0') + throw ReOptionException(this, + i18n("Option $1: Empty parameter is not allowed"), name); + break; + case DT_STRING_EMPTY: + case DT_BOOL: + default: + break; + } + ReByteBuffer buffer; + // First character says: defined. + buffer.appendChar(' ').append(value, -1); + m_values.put(name, buffer.str()); +} + diff --git a/base/ReProgramArgs.hpp b/base/ReProgramArgs.hpp index 72836b1..c52408e 100644 --- a/base/ReProgramArgs.hpp +++ b/base/ReProgramArgs.hpp @@ -54,38 +54,33 @@ public: ReProgramArgs(const char* usageString, const char* examples = NULL); virtual ~ReProgramArgs(); public: - void addInt(const char* name, const char* description, char shortOpt, - const char* longOpt, int defaultVal); void addBool(const char* name, const char* description, char shortOpt, const char* longOpt, bool defaultVal); + void addInt(const char* name, const char* description, char shortOpt, + const char* longOpt, int defaultVal); void addString(const char* name, const char* description, char shortOpt, const char* longOpt, bool mayBeEmpty, const char* defaultVal); - + int argCount() const; + const char* arg(size_t index) const; bool getBool(const char* name); int getInt(const char* name); const char* getString(const char* name, ReByteBuffer& buffer); - - int getArgCount() const; - const char* getArg(size_t index) const; - const char* getProgramName() const; - - void init(int argc, const char* argv[]); - - void setLastError(const char* message); void help(const char* message, bool issueLastError, ReStringList& lines) const; void help(const char* message, bool issueLastError, FILE* stream) const; + void init(int argc, const char* argv[]); + const char* programName() const; + void setLastError(const char* message); void setUsage(const char* usage[]); - private: void addProperties(const char*name, const char* description, char shortOpt, const char* longOpt, DataType dataType, const char* defaultValue, size_t lengthValue); + void analyseLong(const char* opt); + bool analyseShort(const char* opt, const char* nextArg); void search(char shortName, const char* longName, ReByteBuffer& name, ReStringList& list); void setValue(const char* name, const char* value, const char* dataType); - bool analyseShort(const char* opt, const char* nextArg); - void analyseLong(const char* opt); protected: ReStringList m_usage; ReStringList m_examples; diff --git a/base/ReSeqArray.hpp b/base/ReSeqArray.hpp index 7505d79..a3b5cf2 100644 --- a/base/ReSeqArray.hpp +++ b/base/ReSeqArray.hpp @@ -38,8 +38,8 @@ public: ReSeqArray(const ReSeqArray& source); ReSeqArray& operator =(const ReSeqArray& source); public: - Index add(Index index, const Byte* source, size_t sourceLength = (size_t)-1, - Tag tag = 0); + Index add(Index index, const Byte* source, + size_t sourceLength = (size_t) -1, Tag tag = 0); bool binarySearch(const Byte* toFind, int length, Index& index, Tag* tag = NULL) const; void clear(); @@ -68,10 +68,10 @@ public: } void remove(Index index); void set(Index index, const Byte* source, size_t sourceLength = -1, - Tag tag = 0); + Tag tag = 0); void setCapacity(int maxIndices, int maxStringSpace); void setSizes(int sizeOfTag, int sizeOfLength, size_t constantLength = - INDIVIDUAL_SIZE); + INDIVIDUAL_SIZE); void setSorted(bool onNotOff); void setIgnoreCase(bool onNotOff); void sort(); diff --git a/base/ReTestUnit.cpp b/base/ReTestUnit.cpp index bfd881c..27a4079 100644 --- a/base/ReTestUnit.cpp +++ b/base/ReTestUnit.cpp @@ -22,7 +22,7 @@ ReTestUnit::ReTestUnit(const char* name, const char* sourceFile) : m_sourceFile(sourceFile), m_buffer(), m_memoryAppender(new ReMemoryAppender(1024)), - m_silentLogger(){ + m_silentLogger() { m_silentLogger.addAppender(m_memoryAppender); int ix = m_sourceFile.rindexOf(OS_SEPARATOR, 1); if (ix >= 0) @@ -282,12 +282,7 @@ void ReTestUnit::createTestDir() { * @return a time usable for for runtime measurement */ int ReTestUnit::milliSecSince(int64_t start) { -#if defined __linux__ || defined __WIN32__ - int64_t diff = clock() - start; - return int(diff * 1000 / CLOCKS_PER_SEC); -#else -# error "timer not defined" -#endif + return ReBaseUtils::milliSecSince(start); } /** @@ -301,18 +296,7 @@ int ReTestUnit::milliSecSince(int64_t start) { * @return a time usable for for runtime measurement */ int64_t ReTestUnit::timer() { -#if defined __linux__ - return clock(); -#elif defined __WIN32__ - return clock(); -#if 0 - FILETIME timeBuffer; - GetSystemTimeAsFileTime(&timeBuffer); - return (int64_t) (((uint64_t) timeBuffer.dwHighDateTime << 32) + timeBuffer.dwLowDateTime); -#endif -#else -# error "timer not defined" -#endif + return ReBaseUtils::timer(); } /** @brief Returns the temporary directory. diff --git a/base/ReThread.cpp b/base/ReThread.cpp index bf8facf..0fcc6cd 100644 --- a/base/ReThread.cpp +++ b/base/ReThread.cpp @@ -12,10 +12,12 @@ enum RELOC_HASHLIST { LC_PREPARE_TO_RUN_1 = LC_THREAD + 1, // 50601 LC_START_THREAD_1, // 50602 - LC_NE_1, // 50603 + LC_INSERT_THREAD_1, // 50603 + LC_KILL_ALL_THREADS_1, // 50604 + LC_KILL_ALL_THREADS_2, // 50605 + LC_MUTEX_THREADS, // 50606 }; - /** * Constructor. * @@ -23,18 +25,18 @@ enum RELOC_HASHLIST { * deletes the instance when it is stopped */ ReThread::ReThread(bool autoDelete) : - m_threadId(-1), - m_threadLogger(false), - m_appender(NULL), - m_starter(NULL), + m_threadId(-1), + m_threadLogger(false), + m_appender(NULL), + m_starter(NULL), #if defined __linux__ - m_threadInfo(), + m_threadInfo(), #elif defined __WIN32__ - m_threadInfo(UNDEF_HANDLE), + m_threadInfo(UNDEF_HANDLE), #endif - m_shouldStop(false), - m_isStopped(false), - m_autoDelete(autoDelete){ + m_shouldStop(false), + m_isStopped(false), + m_autoDelete(autoDelete) { #if defined __linux__ memset(&m_threadInfo, 0, sizeof m_threadInfo); #endif @@ -42,9 +44,34 @@ ReThread::ReThread(bool autoDelete) : /** * Destructor. */ -ReThread::~ReThread(){ +ReThread::~ReThread() { + delete m_appender; + m_appender = NULL; } +/** + * Returns the logger. + * + * @return the logger + */ +ReLogger* ReThread::logger() { + return &m_threadLogger; +} + +/** + * Kills the thread. + * + * Note: This is very oppressive! + * The thread starter uses that only if setShouldStop(true) + * has no success. + */ +void ReThread::kill() { +#if defined __linux__ + pthread_kill(m_threadInfo, SIGKILL); +#elif defined __WIN32__ + KillThread(m_threadInfo); +#endif +} /** * Prepares the thread for running. * @@ -55,17 +82,56 @@ ReThread::~ReThread(){ * @param starter the instance which has started the thread */ bool ReThread::prepareToRun(int id, ReLogger* masterLogger, - ReThreadStarter* starter){ + ReThreadPool* starter) { bool rc = false; - if (m_starter != NULL){ + if (m_starter != NULL) { globalLogger()->say(LOG_ERROR | CAT_LIB, LC_PREPARE_TO_RUN_1, - i18n("setMasterLogger() is called multiple times")); + i18n("setMasterLogger() is called multiple times")); } else { m_threadId = id; - m_appender->setMasterLogger(masterLogger); + if (m_appender == NULL) + m_appender = new ReSlaveAppender(masterLogger, + '0' + (id % ('z' - '0' + 1))); + else + m_appender->setMasterLogger(masterLogger); m_starter = starter; rc = true; } + return rc; +} +/** + * Runs the task and exits the thread. + */ +void ReThread::runAndFinish() { + run(); +#if defined __linux__ + pthread_exit(NULL); +#elif defined __WIN32__ + StopThread(m_threadInfo); +#endif + m_isStopped = true; +} + +/** + * Constructor. + * + * @param processor the instance that performs the actual task + */ +ReSimpleThread::ReSimpleThread(ReProcessor* processor) : + ReThread(true), + m_processor(processor) { +} +/** + * Destructor. + */ +ReSimpleThread::~ReSimpleThread() { +} +/** + * This method does the actual task. + */ +void ReSimpleThread::run() { + m_processor->process(); + m_isStopped = true; } /** @@ -74,17 +140,129 @@ bool ReThread::prepareToRun(int id, ReLogger* masterLogger, * @param maxThreads the maximal number of threads * @param logger the (master) logger for error handling */ -ReThreadStarter::ReThreadStarter(int maxThreads, ReLogger* logger) : - m_nextId(0), - m_logger(logger), - m_maxThreads(maxThreads){ +ReThreadPool::ReThreadPool(int maxThreads, ReLogger* logger) : + m_nextId(0), + m_logger(logger), + m_maxThreads(maxThreads), + m_maxKillTimeSec(3), + m_mutexThreads(LC_MUTEX_THREADS) { m_threads = new ReThread*[maxThreads]; memset(m_threads, 0, maxThreads * sizeof *m_threads); } + /** * Destructor. */ -ReThreadStarter::~ReThreadStarter(){ +ReThreadPool::~ReThreadPool() { + killAllThreads(); +} + +/** + * Inserts a thread into the thread list. + * + * @param thread thread to insert + * @return true: success
+ * false: too much threads (no space in list) + */ +bool ReThreadPool::insertThread(ReThread* thread) { + bool found = false; + m_mutexThreads.lock(); + for (int ii = 0; ii < m_maxThreads; ii++) { + ReThread* current = m_threads[ii]; + if (current == NULL) { + m_threads[ii] = thread; + found = true; + break; + } else if (current->m_isStopped) { + if (current->m_autoDelete) + delete current; + m_threads[ii] = thread; + found = true; + } + } + m_mutexThreads.unlock(); + if (!found) + m_logger->sayF(LOG_ERROR | CAT_PROCESS, LC_INSERT_THREAD_1, + i18n("too much threads: $1")).arg(m_maxThreads).end(); + + return found; +} +/** + * Stopps all running threads. + */ +void ReThreadPool::killAllThreads() { + // Orders stop for all threads: + int countWaiting = 0; + m_mutexThreads.lock(); + for (int ii = 0; ii < m_maxThreads; ii++) { + ReThread* current = m_threads[ii]; + if (current != NULL && !current->m_isStopped) { + countWaiting++; + current->setShouldStop(true); + } + } + m_mutexThreads.unlock(); + if (countWaiting > 0) + m_logger->sayF(LOG_INFO | CAT_PROCESS, LC_KILL_ALL_THREADS_1, + i18n("$1 thread(s) still running")).arg(countWaiting).end(); + + // we observe the thread stopping: + for (int wait = 0; countWaiting > 0 && wait <= m_maxKillTimeSec; wait++) { + m_mutexThreads.lock(); + for (int ii = 0; ii < m_maxThreads; ii++) { + ReThread* current = m_threads[ii]; + if (current != NULL && current->m_isStopped) { + countWaiting--; + } + } + m_mutexThreads.unlock(); + if (countWaiting > 0) + sleep(1); + } + // now we kill: + countWaiting = 0; + for (int ii = 0; ii < m_maxThreads; ii++) { + m_mutexThreads.lock(); + ReThread* current = m_threads[ii]; + if (current == NULL || current->m_isStopped) + m_mutexThreads.unlock(); + else { + current->kill(); + int id = current->m_threadId; + m_mutexThreads.unlock(); + m_logger->sayF(LOG_WARNING | CAT_PROCESS, LC_KILL_ALL_THREADS_2, + i18n("thread $1 must be killed")).arg(id).end(); + countWaiting++; + } + } + if (countWaiting > 0) + // wait 1 msec for end of kill: + usleep(1000); + // we destroy all threads marked with auto delete: + m_mutexThreads.lock(); + for (int ii = 0; ii < m_maxThreads; ii++) { + ReThread* current = m_threads[ii]; + if (current != NULL && current->m_autoDelete) { + delete current; + m_threads[ii] = NULL; + } + } + m_mutexThreads.unlock(); +} + +/** + * Starts a thread with very few prerequisites. + * + * Note: this method is threadsafe. + * + * @param processor the instance doing the actual task + * @return true: successful + */ +bool ReThreadPool::startSimpleThread(ReProcessor& processor) { + // auto delete: the thread starter frees the instance + ReSimpleThread* thread = new ReSimpleThread(&processor); + bool rc = startThread(thread); + return rc; } #if defined __linux__ @@ -95,40 +273,95 @@ ReThreadStarter::~ReThreadStarter(){ * * @param pConnection a void* pointer to the ReThread instance * */ -static void* starterFunction(void *pConnection) { +void* globalThreadStarterFunction(void *pConnection) { ReThread* thread = reinterpret_cast(pConnection); - thread->run(); + thread->runAndFinish(); + return NULL; } #elif defined __WIN32__ -DWORD WINAPI starterFunction(_In_ LPVOID pParameter){ +DWORD WINAPI globalThreadStarterFunction(_In_ LPVOID pParameter) { ReThread* thread = reinterpret_cast(pConnection); - thread->run(); + thread->runAndFinish(); return 0; } #endif + /** * Starts a new thread. * + * Note: this method is threadsafe. + * * @param thread the */ -bool ReThreadStarter::startThread(ReThread& thread){ +bool ReThreadPool::startThread(ReThread* thread) { bool ok = false; - if (thread.prepareToRun(++m_nextId, m_logger, this)){ + if (!insertThread(thread)) { + if (thread->m_autoDelete) { + delete thread; + } + } else { + if (thread->prepareToRun(++m_nextId, m_logger, this)) { #if defined __linux__ - pthread_t sniffer_thread; - ok = pthread_create(&sniffer_thread, NULL, starterFunction, - reinterpret_cast(&thread)) >= 0; + ok = pthread_create(&thread->m_threadInfo, NULL, + globalThreadStarterFunction, reinterpret_cast(thread)) + >= 0; #elif defined __WIN32__ - HANDLE threadHandle; - ok = (threadHandle = CreateThread(NULL, 0, starterFunction, - &thread, 0)) != NULL; + HANDLE threadHandle; + ok = (threadHandle = CreateThread(NULL, 0, globalThreadStarterFunction, + &thread, 0)) != NULL; #endif - if (! ok) - m_logger->sayF(LOG_ERROR | CAT_PROCESS, - LC_START_THREAD_1, - i18n("cannot create a thread: $1")).arg( - getLastOSError()).end(); + if (!ok) + m_logger->sayF(LOG_ERROR | CAT_PROCESS, LC_START_THREAD_1, + i18n("cannot create a thread: $1")).arg(getLastOSError()) + .end(); + } } return ok; } + +/** + * Waits for the end of all threads. + * + * Note: this method is threadsafe. + * + * @param timeoutSec maximal time for waiting + * @return true: all threads are finished
+ * false: timeout reached + */ +bool ReThreadPool::waitForAlmostAll(int mayResist, int timeoutSec) { + bool rc = false; + time_t start = time(NULL); + time_t now; + do { + int countWaiting = 0; + m_mutexThreads.lock(); + for (int ii = 0; ii < m_maxThreads; ii++) { + ReThread* current = m_threads[ii]; + if (current != NULL && !current->m_isStopped) { + countWaiting++; + } + } + m_mutexThreads.unlock(); + if (countWaiting <= mayResist) { + rc = true; + break; + } + usleep(200 * 1000); + now = time(NULL); + } while (now < start + timeoutSec); + return rc; +} +/** + * Waits for the end of all threads. + * + * Note: this method is threadsafe. + * + * @param timeoutSec maximal time for waiting + * @return true: all threads are finished
+ * false: timeout reached + */ +bool ReThreadPool::waitForDone(int timeoutSec) { + bool rc = waitForAlmostAll(0, timeoutSec); + return rc; +} diff --git a/base/ReThread.hpp b/base/ReThread.hpp index d6aafbf..de73c0e 100644 --- a/base/ReThread.hpp +++ b/base/ReThread.hpp @@ -10,40 +10,51 @@ #ifndef BASE_RETHREAD_HPP_ #define BASE_RETHREAD_HPP_ -class ReThreadStarter; +class ReThreadPool; class ReSlaveAppender; /** * Abstract base class for threads * * Starting is done with a ReThreadStarter. */ -class ReThread { +class ReThread: public ReLoggerOwner { public: ReThread(bool autoDelete); virtual ~ReThread(); -private: - friend class ReThreadStarter; - bool prepareToRun(int id, ReLogger* masterLogger, - ReThreadStarter* starter); public: + /** Does the actual task. + * This method must do a m_isStopped = true; at the end! + */ virtual void run() = 0; /** Returns if the thread is stopped. * @return truethe thread is stopped */ - inline bool isStopped() const{ + inline bool isStopped() const { return m_isStopped; } + virtual ReLogger* logger(); /** Sets the wish for stopping the thread. * @param value true: the thread should stop as soon as possible */ - inline bool setShouldStop(bool value){ + inline void setShouldStop(bool value) { m_shouldStop = value; } +private: +private: + friend class ReThreadPool; + void kill(); + bool prepareToRun(int id, ReLogger* masterLogger, ReThreadPool* starter); +#if defined __linux__ + friend void* globalThreadStarterFunction(void *pConnection); +#elif defined __WIN32__ + friend DWORD WINAPI globalThreadStarterFunction(_In_ LPVOID pParameter); +#endif + void runAndFinish(); protected: int m_threadId; ReLogger m_threadLogger; ReSlaveAppender* m_appender; - ReThreadStarter* m_starter; + ReThreadPool* m_starter; #if defined __linux__ pthread_t m_threadInfo; #elif defined __WIN32__ @@ -54,15 +65,28 @@ protected: bool m_autoDelete; }; +class ReSimpleThread: public ReThread { +public: + ReSimpleThread(ReProcessor* processor); + virtual ~ReSimpleThread(); +public: + virtual void run(); +private: + ReProcessor* m_processor; +}; /** * Offers a portable way to start threads. */ -class ReThreadStarter { +class ReThreadPool { public: - ReThreadStarter(int maxThreads, ReLogger* logger); - virtual ~ReThreadStarter(); + ReThreadPool(int maxThreads, ReLogger* logger); + virtual ~ReThreadPool(); public: - bool startThread(ReThread& thread); + void killAllThreads(); + bool startSimpleThread(ReProcessor& processor); + bool startThread(ReThread* thread); + bool waitForAlmostAll(int mayResist, int timeoutSec); + bool waitForDone(int timeoutSec); private: bool insertThread(ReThread* thread); private: @@ -70,5 +94,7 @@ private: ReLogger* m_logger; int m_maxThreads; ReThread** m_threads; + int m_maxKillTimeSec; + ReMutex m_mutexThreads; }; #endif /* BASE_RETHREAD_HPP_ */ diff --git a/base/ReVarArgs.cpp b/base/ReVarArgs.cpp index f616d5b..2c05595 100644 --- a/base/ReVarArgs.cpp +++ b/base/ReVarArgs.cpp @@ -26,6 +26,7 @@ typedef ReByteBuffer::Byte Byte; */ ReVarArgs::ReVarArgs(void) : m_argNo(0), + m_maxArgNo(0), m_format(), m_argBuffer(), // m_args @@ -40,6 +41,7 @@ ReVarArgs::ReVarArgs(void) : */ ReVarArgs::ReVarArgs(const char* format) : m_argNo(0), + m_maxArgNo(0), m_format(), m_argBuffer(), // m_args @@ -47,6 +49,12 @@ ReVarArgs::ReVarArgs(const char* format) : m_trigger(NULL) { reset(format); } + +/** + * Destructor. + */ +ReVarArgs::~ReVarArgs() { +} /** @brief Resets the instance. * * Sets a new format and waits for the arguments. diff --git a/base/ReVarArgs.hpp b/base/ReVarArgs.hpp index 8658ff0..2341a3f 100644 --- a/base/ReVarArgs.hpp +++ b/base/ReVarArgs.hpp @@ -13,6 +13,9 @@ /** This class will be used as callback method for ReVarArgs. */ class ReVarArgTrigger { +public: + virtual ~ReVarArgTrigger() { + } public: /** @brief This method will be called when a new ReVarArg::log() call was done. * The call was done after the insertion of the argument into the internal structures. @@ -35,6 +38,7 @@ private: public: ReVarArgs(); ReVarArgs(const char* format); + virtual ~ReVarArgs(); private: void initialize(size_t size); void replacePlaceholder(); @@ -55,7 +59,7 @@ public: * @param alignRight true: padding is done at the start */ inline ReVarArgs& arg(const ReByteBuffer& value, int minWidth = 0, - int maxWidth = 1024, bool alignRight = false){ + int maxWidth = 1024, bool alignRight = false) { return arg(value.str(), minWidth, maxWidth, alignRight); } ReVarArgs& arg(double arg, const char* format = "%f"); diff --git a/base/rebase.hpp b/base/rebase.hpp index 1183324..dd2c61b 100644 --- a/base/rebase.hpp +++ b/base/rebase.hpp @@ -36,6 +36,7 @@ # include #include #include +#include typedef u_int64_t uint64_t; typedef u_int8_t uint8_t; typedef __off_t ReFileSize_t; @@ -77,7 +78,24 @@ inline int getLastOSError() { } #endif -#define RE_TESTUNIT +typedef int ReErrNo_t; +/** + * This base class allows to define classes with very common tasks. + * + * Example (a thread starter): + * the class realizing the task is a sub class of ReProcessor. + * The thread starter gets an instance of this task class and calls the + * method process() inside the new thread. + */ +class ReProcessor { +public: + /** Destructor. + */ + virtual ~ReProcessor() { + } +public: + virtual void process() = 0; +}; #include "base/ReMutex.hpp" #include "base/ReByteBuffer.hpp" #include "base/ReVarArgs.hpp" @@ -95,8 +113,7 @@ inline int getLastOSError() { #include "base/ReConfigFile.hpp" #include "base/ReI18N.hpp" #include "base/ReProgramArgs.hpp" +#include "base/ReBaseUtils.hpp" -typedef unsigned char byte_t; -typedef int ReErrNo_t; -#include "../base/baselocations.hpp" +#include "base/baselocations.hpp" #endif /* REBASE_HPP_ */ diff --git a/cunit/cuReByteBuffer.cpp b/cunit/cuReByteBuffer.cpp index c73393e..aa10b29 100644 --- a/cunit/cuReByteBuffer.cpp +++ b/cunit/cuReByteBuffer.cpp @@ -58,7 +58,7 @@ private: checkEqu("12*56ab.g", buffer); // given separator with more than one char / no separator buffer.appendFix("ABCDEF", -1, 5, 5, "...").appendFix("xyz", -1, 2, 0, - NULL); + NULL); checkEqu("12*56ab.gA...Fxz", buffer); buffer = "x"; diff --git a/cunit/cuReDirTools.cpp b/cunit/cuReDirTools.cpp index 9eacdfd..4f7ecd2 100644 --- a/cunit/cuReDirTools.cpp +++ b/cunit/cuReDirTools.cpp @@ -15,18 +15,18 @@ static const char* s_empty[] = { NULL }; const int tenYear = (365 * 10 + 2) * 24 * 3600; const char* s_allFiles[] = { // - " 1.txt", // - "*dir1", // - "*dir2", // - "*dir1/cache", // - "*dir1/dir1_1", // - "*dir1/dir1_2", // - "*dir1/dir1_2/dir1_2_1", // - " dir1/dir1_2/dir1_2_1/x1.txt", // - " dir1/dir1_2/dir1_2_1/x2.txt", // - " dir2/2.x", // - " dir1/cache/cache.txt", // - NULL }; + " 1.txt", // + "*dir1", // + "*dir2", // + "*dir1/cache", // + "*dir1/dir1_1", // + "*dir1/dir1_2", // + "*dir1/dir1_2/dir1_2_1", // + " dir1/dir1_2/dir1_2_1/x1.txt", // + " dir1/dir1_2/dir1_2_1/x2.txt", // + " dir2/2.x", // + " dir1/cache/cache.txt", // + NULL }; class TestReDirTools: public ReTestUnit { public: @@ -71,9 +71,9 @@ private: testRandom(); } } - void testRandom(){ + void testRandom() { const char* argv[] = { "random", "-l20", "-s", "40", "50", - NULL }; + NULL }; ReDirRandom(m_logger).run(-1, argv); } void testDelete() { @@ -85,33 +85,32 @@ private: const char* argv[] = { "delete", "-p;x*.txt", optOutput.str(), m_base .str(), NULL }; const char* existing[] = { // - " 1.txt", // - "*dir1", // - "*dir2", // - "*dir1/cache", // - "*dir1/dir1_1", // - "*dir1/dir1_2", // - "*dir1/dir1_2/dir1_2_1", // - " dir2/2.x", // - " dir1/cache/cache.txt", // - NULL }; + " 1.txt", // + "*dir1", // + "*dir2", // + "*dir1/cache", // + "*dir1/dir1_1", // + "*dir1/dir1_2", // + "*dir1/dir1_2/dir1_2_1", // + " dir2/2.x", // + " dir1/cache/cache.txt", // + NULL }; const char* notExisting[] = { // - " dir1/dir1_2/dir1_2_1/x1.txt", // - " dir1/dir1_2/dir1_2_1/x2.txt", // - NULL }; + " dir1/dir1_2/dir1_2_1/x1.txt", // + " dir1/dir1_2/dir1_2_1/x2.txt", // + NULL }; ReDirDelete(m_logger).run(-1, argv); mustExist(existing); mayNotExist(notExisting); - const char* argv2[] = { "delete", optOutput.str(), m_base - .str(), NULL }; + const char* argv2[] = { "delete", optOutput.str(), m_base.str(), NULL }; ReDirDelete(m_logger).run(-1, argv2); mayNotExist(s_allFiles); } - void mustExist(const char** names){ + void mustExist(const char** names) { ReByteBuffer name; struct stat info; - for (int ix = 0; names[ix] != NULL; ix++){ + for (int ix = 0; names[ix] != NULL; ix++) { const char* arg = names[ix]; name = m_base; name.ensureLastChar(OS_SEPARATOR_CHAR); @@ -120,16 +119,16 @@ private: if (stat(name.str(), &info) != 0) checkEqu("missing", name); bool isDir = arg[0] == '*'; - if (isDir && ! S_ISDIR(info.st_mode)) + if (isDir && !S_ISDIR(info.st_mode)) checkEqu("file not dir", name); - if (! isDir && S_ISDIR(info.st_mode)) + if (!isDir && S_ISDIR(info.st_mode)) checkEqu("dir not file", name); } } - void mayNotExist(const char** names){ + void mayNotExist(const char** names) { ReByteBuffer name; struct stat info; - for (int ix = 0; names[ix] != NULL; ix++){ + for (int ix = 0; names[ix] != NULL; ix++) { const char* arg = names[ix]; name = m_base; name.ensureLastChar(OS_SEPARATOR_CHAR); @@ -168,7 +167,7 @@ private: } } void initTree() { - for (int ix = 0; s_allFiles[ix] != 0; ix++){ + for (int ix = 0; s_allFiles[ix] != 0; ix++) { const char* name = s_allFiles[ix]; if (name[0] == '*') makeDir(name + 1); diff --git a/cunit/cuReException.cpp b/cunit/cuReException.cpp index d0ec904..cb67b8a 100644 --- a/cunit/cuReException.cpp +++ b/cunit/cuReException.cpp @@ -42,7 +42,7 @@ private: } try { throw ReFormatException("ReFormatException", "format", __FILE__, - __LINE__); + __LINE__); checkT(false); } catch (ReException& e) { log(false, e.getMessage()); diff --git a/cunit/cuReLogger.cpp b/cunit/cuReLogger.cpp index e024cc3..b4e19f0 100644 --- a/cunit/cuReLogger.cpp +++ b/cunit/cuReLogger.cpp @@ -20,7 +20,7 @@ private: testMemoryAppender(); testBase(); } - void testBase(){ + void testBase() { ReStreamAppender app1(stdout); app1.setMode(CAT_ALL, CAT_ALL, CAT_ALL, GRAN_ALL); @@ -36,7 +36,7 @@ private: .end(); globalLogger()->say(CAT_LIB, __LINE__, "globalLogger()"); } - void testMemoryAppender(){ + void testMemoryAppender() { ReLogger logger(false); ReMemoryAppender appender(3); logger.addAppender(&appender); @@ -62,7 +62,7 @@ private: ReByteBuffer all; checkEqu(3, appender.join(all).count("\n")); } - void testSlaveAppender(){ + void testSlaveAppender() { ReLogger masterLogger(false); ReMemoryAppender memoryAppender(10); masterLogger.addAppender(&memoryAppender); diff --git a/cunit/cuReProgramArgs.cpp b/cunit/cuReProgramArgs.cpp index 98faf92..e6bd316 100644 --- a/cunit/cuReProgramArgs.cpp +++ b/cunit/cuReProgramArgs.cpp @@ -95,7 +95,7 @@ private: "-s", "2nd string", "arg1", "arg2" }; args.init(sizeof vector / sizeof vector[0], vector); - checkEqu("testprog", args.getProgramName()); + checkEqu("testprog", args.programName()); checkT(args.getBool("boolarg")); checkF(args.getBool("boolarg2")); checkF(args.getBool("boolarg3")); @@ -106,10 +106,10 @@ private: checkEqu("2nd string", args.getString("stringarg", buffer)); checkEqu("undef", args.getString("stringarg2", buffer)); checkEqu("undef2", args.getString("estringarg2", buffer)); - checkEqu("testprog", args.getProgramName()); - checkEqu("arg1", args.getArg(0)); - checkEqu("arg2", args.getArg(1)); - checkEqu(2, args.getArgCount()); + checkEqu("testprog", args.programName()); + checkEqu("arg1", args.arg(0)); + checkEqu("arg2", args.arg(1)); + checkEqu(2, args.argCount()); ReByteBuffer fn; FILE* fp = fopen(buildFilename("help.tmp.txt", fn), "w"); checkF(fp == NULL); @@ -195,7 +195,7 @@ private: "--estring=", "--estring2=not empty", "arg1", "arg2" }; args.init(sizeof vector / sizeof vector[0], vector); - checkEqu("testprog", args.getProgramName()); + checkEqu("testprog", args.programName()); checkT(args.getBool("boolarg")); checkF(args.getBool("boolarg2")); checkF(args.getBool("boolarg3")); @@ -204,9 +204,9 @@ private: checkEqu("x y", args.getString("stringarg", buffer)); checkEqu("", args.getString("estringarg", buffer)); checkEqu("not empty", args.getString("estringarg2", buffer)); - checkEqu("arg1", args.getArg(0)); - checkEqu("arg2", args.getArg(1)); - checkEqu(2, args.getArgCount()); + checkEqu("arg1", args.arg(0)); + checkEqu("arg2", args.arg(1)); + checkEqu(2, args.argCount()); ReByteBuffer fn; FILE* fp = fopen(buildFilename("help.tmp.txt", fn), "w"); checkT(fp != NULL); diff --git a/cunit/cuReTCP.cpp b/cunit/cuReTCP.cpp index 222edd2..83f46ca 100644 --- a/cunit/cuReTCP.cpp +++ b/cunit/cuReTCP.cpp @@ -9,71 +9,110 @@ #include "base/rebase.hpp" #include "net/renet.hpp" - -static void* serverThread(void *pDummy) { - printf("starting server..."); - ReLogger logger(false); - ReTCPEchoServer server(58111, &logger); - server.listenForAll(); - printf("server stopped\n"); -} - -class TestReTCP: public ReTestUnit { +static int s_port = 58111; +class TCPThread: public ReThread { public: - TestReTCP() : - ReTestUnit("ReTCP", __FILE__) { - run(); + TCPThread(const char* task) : + ReThread(999), + m_task(task) { } -private: - void run() { - testServer(); - //testClient(); - testSpeed(); - } - void testServer() { - pthread_t thread; - if (pthread_create(&thread, NULL, serverThread, NULL) < 0) { - logF(true, "cannot create the server thread: %d", getLastOSError()); +public: + virtual void run() { + ReLogger* theLogger = logger(); + int location = 999; + if (strcmp(m_task, "server") == 0) { + theLogger->say(LOG_INFO | CAT_LIB, location, "starting server..."); + ReLogger logger(false); + ReTCPEchoServer server(s_port, theLogger); + server.listenForAll(); + theLogger->say(LOG_INFO | CAT_LIB, location, "server stopped"); + } else if (strcmp(m_task, "echo") == 0) { + theLogger->say(LOG_INFO | CAT_LIB, location, + "starting echo client..."); + ReTCPClient client(theLogger); + client.connect("localhost", s_port); + client.send("echo", "Hello world"); + ReByteBuffer command, data; + client.receive(command, data); + if (!command.equals("Echo ")) { + theLogger->sayF(LOG_ERROR | CAT_TEST, location, + "unexpected answer: '$1' / '$2'").arg("Echo ").arg( + command).end(); + } + if (!data.equals("Hello world")) { + theLogger->sayF(LOG_ERROR | CAT_TEST, location, + "unexpected data: '$1' / '$2'").arg("Hello world").arg(data) + .end(); + } + client.close(); + theLogger->say(LOG_INFO | CAT_LIB, location, "echo client stopped"); + } else if (strcmp(m_task, "upload") == 0) { + speedTest(theLogger, true); + } else { // download + speedTest(theLogger, false); } } - void testClient() { - ReLogger logger(false); - ReTCPClient client(&logger); - client.connect("localhost", 58111); - client.send("echo", "Hello world"); - ReByteBuffer command, data; - client.receive(command, data); - checkEqu("Echo ", command); - checkEqu("Hello world", data); - client.close(); - } - void testSpeed() { - ReLogger logger(false); - ReTCPClient client(&logger); - if (client.connect("localhost", 58111)){ + void speedTest(ReLogger* logger, bool upload) { + int location = 998; + const char* direction = upload ? "upload" : "download"; + logger->sayF(LOG_INFO | CAT_LIB, location, "$1 client started..").arg( + direction).end(); + ReTCPClient client(logger); + if (client.connect("localhost", s_port)) { ReByteBuffer data, command, answer; - int size = 1024*1024*10; - data.appendChar('x', size); + int size = 1024 * 1024 * 10; + const char* request; + if (upload) { + data.appendChar('x', size); + request = "strlen"; + } else { + data.appendInt(size); + request = "filldata"; + } time_t start2 = time(NULL); - int64_t start = timer(); + int64_t start = ReBaseUtils::timer(); int count = 100; - for (int ii = 0; ii < count; ii++){ - client.send("strlen", data.str(), data.length()); + for (int ii = 0; ii < count; ii++) { + client.send(request, data.str(), data.length()); client.receive(command, answer); } - int64_t duration = milliSecSince(start); + int64_t duration = ReBaseUtils::milliSecSince(start); int duration2 = time(NULL) - start2; if (duration2 == 0) duration2 = 1; char msg[256]; - int miByte = count * (size / (1024*1024)); - snprintf(msg, sizeof msg, "%d MiByte in %s/%d sec: %.3f (%.3f) MiByte/sec\n", - miByte, ReByteBuffer("").appendMilliSec(duration).str(), - duration2, miByte * 1000.0 / (double) duration, - miByte/(double) duration2); - printf(msg); + int miByte = count * (size / (1024 * 1024)); + snprintf(msg, sizeof msg, + "%s: %d MiByte in %s/%d sec: %.3f (%.3f) MiByte/sec", direction, + miByte, ReByteBuffer("").appendMilliSec(duration).str(), + duration2, miByte * 1000.0 / (double) duration, + miByte / (double) duration2); + logger->say(LOG_INFO | CAT_LIB, location, msg); } } + +private: + const char* m_task; +}; +class TestReTCP: public ReTestUnit { +public: + TestReTCP() : + ReTestUnit("ReTCP", __FILE__) { + run(); + } +private: + void run() { + ReLogger logger(false); + logger.addStandardAppenders(true, NULL, 0, 0); + ReThreadPool threadStarter(1, &logger); + threadStarter.startThread(new TCPThread("server")); + threadStarter.startThread(new TCPThread("echo")); + threadStarter.startThread(new TCPThread("upload")); + threadStarter.startThread(new TCPThread("download")); + threadStarter.waitForAlmostAll(1, 20); + ReTCPStopClient stopper(&logger); + stopper.stopServer(s_port); + } }; extern void testReTCP(void); diff --git a/cunit/cuReTraverser.cpp b/cunit/cuReTraverser.cpp index db5b713..74e8c14 100644 --- a/cunit/cuReTraverser.cpp +++ b/cunit/cuReTraverser.cpp @@ -82,7 +82,7 @@ private: ReByteBuffer buffer; buffer.ensureSize(5); ReDirSync::copyFile(src.str(), NULL, trg.str(), buffer, - ReLogger::globalLogger()); + ReLogger::globalLogger()); checkFileEqu(src.str(), trg.str()); #else log(false, "testCopyFile not implemented"); @@ -123,8 +123,8 @@ private: hashPath.put(ReByteBuffer(node, -1), entry->m_path); if (traverser.hasChangedPath(state)) listChanged.add(-1, node); - logF(false, "%d: %-12s %2d %s", level, node, - int(entry->fileSize()), entry->m_path.str()); + logF(false, "%d: %-12s %2d %s", level, node, int(entry->fileSize()), + entry->m_path.str()); } checkOneFile("x1.txt", "dir1_2_1", hashPath); checkOneFile("x2.txt", "dir1_2_1", hashPath); diff --git a/cunit/testall.cpp b/cunit/testall.cpp index 33f6409..f23ee46 100644 --- a/cunit/testall.cpp +++ b/cunit/testall.cpp @@ -60,8 +60,8 @@ void testString() { void testOs() { void testReDirTools(); testReDirTools(); - void testReTraverser(); - testReTraverser(); + void testReTraverser(); + testReTraverser(); if (s_testAll) { void testReTraverser(); @@ -93,7 +93,7 @@ void testAll() { //testNet(); testBase(); } - } catch (ReException e) { + } catch (ReException& e) { fprintf(stderr, "testBase.cpp: unexpected exception: %s\n", e.getMessage()); } diff --git a/math/ReMD5.cpp b/math/ReMD5.cpp index 9c05b7c..5149a77 100644 --- a/math/ReMD5.cpp +++ b/math/ReMD5.cpp @@ -8,26 +8,23 @@ #include "base/rebase.hpp" #include "math/remath.hpp" -const int ReMD5::m_s[RE_DIGEST_CHUNK_SIZE] = { - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, - 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, - 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, - 21, 6, 10, 15, 21, 6, 10, 15, 21 }; -static int s_ix = 0; +const int ReMD5::m_s[RE_DIGEST_CHUNK_SIZE] = { 7, 12, 17, 22, 7, 12, 17, 22, 7, + 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, + 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, + 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 }; // for x in [1..64] : int(2**32 * sin(x)) -const uint32_t ReMD5::m_K[RE_DIGEST_CHUNK_SIZE] = { - 0xd76aa478, 0xe8c7b756, 0x242070db, - 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, - 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, - 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, - 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, - 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, - 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, - 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, - 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, - 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, - 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, - 0xeb86d391 }; +const uint32_t ReMD5::m_K[RE_DIGEST_CHUNK_SIZE] = { 0xd76aa478, 0xe8c7b756, + 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, + 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, + 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, + 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, + 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, + 0x2ad7d2bb, 0xeb86d391 }; /** * Constructor. @@ -39,7 +36,7 @@ const uint32_t ReMD5::m_K[RE_DIGEST_CHUNK_SIZE] = { * @param chunkSize the length of one full input block */ ReDigest::ReDigest(uint8_t* digest, size_t digestSize, uint8_t* waiting, - size_t chunkSize) : + size_t chunkSize) : m_digest(digest), m_digestSize(digestSize), // m_waitingBuffer[RE_DIGEST_CHUNK_SIZE]; @@ -53,7 +50,7 @@ ReDigest::ReDigest(uint8_t* digest, size_t digestSize, uint8_t* waiting, /** * Destructor. */ -ReDigest::~ReDigest(){ +ReDigest::~ReDigest() { } /** * Returns the binary digest value. @@ -130,7 +127,7 @@ void ReDigest::update(const uint8_t* block, int blockLength) { * * @param salt the salt to set */ -void ReDigest::setSalt(uint64_t salt){ +void ReDigest::setSalt(uint64_t salt) { m_salt = salt; } /** @@ -300,9 +297,12 @@ void ReMD5::processChunk2(const uint8_t block[RE_DIGEST_CHUNK_SIZE]) { inline void rotate_left_and_add(uint32_t& rc, uint32_t data, int shift, uint32_t term) { rc = ((data << shift) | (data >> (32-shift))) + term; } +//#define TRACE_MD5 +#if defined TRACE_MD5 +static int s_ix = 0; +#endif inline void X1(uint32_t &var, uint32_t x, uint32_t y, uint32_t z, uint32_t data, uint32_t aConst, uint32_t shift) { -//#define TRACE_MD5 #if defined TRACE_MD5 printf("%2d: A: %08x B: %08x C: %08x D%08x\n", s_ix++ % 16, var, x, y, z); printf(" K[%2d]: %08x M[?]: %08x shift: %02d\n", diff --git a/math/ReMD5.hpp b/math/ReMD5.hpp index 1a3695e..de857f0 100644 --- a/math/ReMD5.hpp +++ b/math/ReMD5.hpp @@ -14,7 +14,7 @@ typedef uint8_t ReMD5Digest_t[16]; class ReDigest { public: ReDigest(uint8_t* buffer, size_t bufferSize, uint8_t* waiting = NULL, - size_t blocksize = RE_DIGEST_CHUNK_SIZE); + size_t blocksize = RE_DIGEST_CHUNK_SIZE); virtual ~ReDigest(); public: const uint8_t* digest(); @@ -25,7 +25,7 @@ public: */ inline void update(const ReByteBuffer& block) { update(reinterpret_cast(block.str()), - (int) block.length()); + (int) block.length()); } virtual void processChunk(const uint8_t* block) = 0; virtual void reset() = 0; @@ -38,7 +38,7 @@ protected: ReByteBuffer m_hexDigest; // normally only the first chunk is used (64 byte), but while finalization // a 2nd chunk may be needed. - uint8_t m_waitingBuffer[2 *RE_DIGEST_CHUNK_SIZE]; + uint8_t m_waitingBuffer[2 * RE_DIGEST_CHUNK_SIZE]; uint8_t* m_waiting; int m_lengthWaiting; int m_chunkSize; @@ -53,7 +53,7 @@ protected: * * The algorithm is described in http://en.wikipedia.org/wiki/MD5. */ -class ReMD5 : public ReDigest { +class ReMD5: public ReDigest { public: ReMD5(); virtual ~ReMD5(); diff --git a/math/ReRPD64.cpp b/math/ReRPD64.cpp index 6d613b3..601feab 100644 --- a/math/ReRPD64.cpp +++ b/math/ReRPD64.cpp @@ -12,7 +12,7 @@ * Constructor. */ ReRPD64::ReRPD64() : - ReDigest(m_digest, sizeof m_digest), + ReDigest(m_digest, sizeof m_digest), //m_digest m_a0(0), m_b0(0), diff --git a/math/ReRPD64.hpp b/math/ReRPD64.hpp index e237228..08211b5 100644 --- a/math/ReRPD64.hpp +++ b/math/ReRPD64.hpp @@ -14,7 +14,7 @@ typedef uint8_t ReRPD64Digest[16]; * * The algorithm is similar to MD5, but calculation is done in 64-bit. */ -class ReRPD64 : public ReDigest { +class ReRPD64: public ReDigest { public: ReRPD64(); virtual ~ReRPD64(); diff --git a/math/ReRandomizer.cpp b/math/ReRandomizer.cpp index c2e2a12..7a83974 100644 --- a/math/ReRandomizer.cpp +++ b/math/ReRandomizer.cpp @@ -23,7 +23,9 @@ ReRandomizer::~ReRandomizer() { } #if defined __linux__ -inline int abs(int x) {return x < 0 ? -x : x;} +inline int abs(int x) { + return x < 0 ? -x : x; +} #endif /** * @brief Returns the next random character. @@ -51,11 +53,11 @@ ReRandomizer::seed_t ReRandomizer::nearTrueRandom() { + (-random ^ 0x20111958) ^ (seed_t(dummy2)); #if defined __linux__ int fh = open("/dev/urandom", O_RDONLY); - char buffer[sizeof (seed_t)]; + char buffer[sizeof(seed_t)]; size_t length = 0; if (read(fh, buffer, sizeof buffer) > 0) - rc ^= *(seed_t*) buffer; + rc ^= *(seed_t*) buffer; close(fh); #elif defined __WIN32__ #else diff --git a/net/ReTCP.cpp b/net/ReTCP.cpp index 8191fb6..4d9fc2f 100644 --- a/net/ReTCP.cpp +++ b/net/ReTCP.cpp @@ -38,11 +38,11 @@ bool ReTCPConnection::isGlobalInitialized = false; * * @param logger the logger for error handling */ -ReSocketAddress::ReSocketAddress(ReLogger* logger) : +ReSocketAddress::ReSocketAddress(ReLoggerOwner* loggerOwner) : m_preferredFamily(AF_INET), m_family(-1), m_port(0), - m_logger(logger), + m_loggerOwner(loggerOwner), // m_ip m_name() { memset(&m_ip, 0, sizeof m_ip); @@ -74,8 +74,9 @@ void ReSocketAddress::setAddress(const char* ip, int port) { hints.ai_socktype = SOCK_STREAM; if ((status = getaddrinfo(ip, NULL, &hints, &infoList)) != 0) { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_SOCKET_ADDR_SET_1, - i18n("getaddrinfo($1) failed: $2")).arg(ip).arg(errno).end(); + m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, + LC_SOCKET_ADDR_SET_1, i18n("getaddrinfo($1) failed: $2")).arg(ip) + .arg(errno).end(); } struct addrinfo* ptr; @@ -112,7 +113,8 @@ void ReSocketAddress::setAddress(const char* ip, int port) { * @param logger logger for the error handling */ ReTCPClient::ReTCPClient(ReLogger* logger) : - ReTCPConnection(-1, logger) { + ReTCPConnection(-1, this), + m_logger(logger) { } /** * Destructor. @@ -142,43 +144,51 @@ bool ReTCPClient::connect(const char* ip, int port) { addressToString(*addr, m_ip, sizeof m_ip); m_peerName.set(m_ip).appendChar(':').appendInt(port); m_port = port; - if ( (m_handleSocket = socket(addr->ai_family, addr->ai_socktype, + if ((m_handleSocket = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol)) < 0) m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_CONNECT_2, - i18n("socket() failed ($1): $2")).arg(errno) - .arg(m_peerName).end(); - else if (::connect(m_handleSocket, addr->ai_addr, addr->ai_addrlen) != 0) + i18n("socket() failed ($1): $2")).arg(errno).arg(m_peerName).end(); + else if (::connect(m_handleSocket, addr->ai_addr, addr->ai_addrlen) + != 0) m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_CONNECT_3, - i18n("connect() failed ($1): $2")).arg(errno) - .arg(m_peerName).end(); + i18n("connect() failed ($1): $2")).arg(errno).arg(m_peerName) + .end(); else rc = true; } return rc; } +/** + * Returns the logger. + * + * @param the logger for error handling + */ +ReLogger* ReTCPClient::logger() { + return m_logger; +} + /** * Constructor. * * @param id an identifier for logging * @param logger the logger for error handling */ -ReTCPConnection::ReTCPConnection(int id, ReLogger* logger) : - ReSocketAddress(logger), +ReTCPConnection::ReTCPConnection(int id, ReLoggerOwner* loggerOwner) : + ReSocketAddress(loggerOwner), m_peerName(), m_received(), - m_logger(logger), m_handleSocket(-1), m_id(id), m_noSent(0), m_noReceived(0) { #if defined __WIN32__ WSADATA wsaData; - if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0){ - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_TCP_CONNECTION_1, - i18n("WSAStartup() failed: $1")).arg(errno).arg(getLastOSError()).end(); - throw ReException("WSAStartup() failed"); - } + if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { + m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_TCP_CONNECTION_1, + i18n("WSAStartup() failed: $1")).arg(errno).arg(getLastOSError()).end(); + throw ReException("WSAStartup() failed"); + } #endif } @@ -201,7 +211,7 @@ void ReTCPConnection::close() { /** * Frees the global resources. */ -void ReTCPConnection::globalClose(){ +void ReTCPConnection::globalClose() { #if defined __WIN32__ WSACleanup(); #endif @@ -229,7 +239,7 @@ void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& data) { command.setLength(8); int received = recv(m_handleSocket, command.buffer(), 8, 0); if (received != 8) { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_1, + m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_1, i18n("cannot receive ($1): $2 [$3]")).arg(errno).arg(received).arg( m_peerName).end(); } else { @@ -238,7 +248,7 @@ void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& data) { int found; if ((found = sscanf(command.str(), "%8x", &length)) != 1 || (flags = (length >> 24)) > 256 || (length &= 0xffffff) < 8) { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_2, + m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_2, i18n("wrong format: $1 [$2]")).arg(command).arg(m_peerName).end(); } else { data.setLength(length); @@ -257,18 +267,18 @@ void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& data) { data.setLength(readBytes); break; } else { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_3, - i18n("cannot receive ($1): $2 [$3]")).arg(errno).arg( - received).arg(m_peerName).end(); + m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, + LC_RECEIVE_3, i18n("cannot receive ($1): $2 [$3]")).arg( + errno).arg(received).arg(m_peerName).end(); break; } } if (rounds) rounds += 0; if (readBytes < length) { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_RECEIVE_4, - i18n("too few bytes read: $1/$2 [$3]")).arg(readBytes).arg( - received).arg(m_peerName).end(); + m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, + LC_RECEIVE_4, i18n("too few bytes read: $1/$2 [$3]")).arg( + readBytes).arg(received).arg(m_peerName).end(); } command.setLength(0); if (readBytes >= 8) { @@ -285,7 +295,9 @@ void ReTCPConnection::receive(ReByteBuffer& command, ReByteBuffer& data) { * @param data the data to send */ void ReTCPConnection::send(const char* command, const char* data, int length) { - if (length < 0) + if (data == NULL) + length = 0; + else if (length < 0) length = strlen(data); m_toSend.ensureSize(length + 16); ++m_noSent; @@ -304,7 +316,7 @@ void ReTCPConnection::send(const char* command, const char* data, int length) { buf += sent; rest -= sent; } else { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_WRITE_1, + m_loggerOwner->logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_WRITE_1, i18n("cannot send ($1): $2")).arg(errno).arg(m_peerName).end(); break; } @@ -318,11 +330,9 @@ void ReTCPConnection::send(const char* command, const char* data, int length) { * @param logger the logger for error handling */ ReTCPServerConnection::ReTCPServerConnection(int id, ReTCPServer* server) : - ReTCPConnection(id, new ReLogger(false)), + ReTCPConnection(id, this), ReThread(true), - m_server(server), - m_slaveAppender(NULL, '0' + id % ('z' - '0' + 1)) { - ReTCPConnection::m_logger->addAppender(&m_slaveAppender); + m_server(server) { } /** @@ -341,7 +351,7 @@ void ReTCPServerConnection::run() { receive(command, m_received); rc = m_server->handler().handleNetCommand(command, m_received, this); if (rc == ReNetCommandHandler::PS_UNKNOWN) { - m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_HANDLE_CONNECTION_1, + logger()->sayF(LOG_ERROR | CAT_NETWORK, LC_HANDLE_CONNECTION_1, i18n("unknown command: $1 length: $2")).arg(command).arg( m_received.length()).end(); } @@ -361,11 +371,12 @@ void ReTCPServerConnection::run() { */ ReTCPServer::ReTCPServer(int port, class ReNetCommandHandler& commandHandler, ReLogger* logger, int maxConnections) : - ReTCPConnection(0, logger), + ReTCPConnection(0, this), m_maxConnections(maxConnections), m_countConnections(0), m_connections(new ReTCPServerConnection*[maxConnections]), - m_handler(commandHandler) { + m_handler(commandHandler), + m_logger(logger) { m_port = port; memset(m_connections, 0, maxConnections * sizeof *m_connections); } @@ -423,7 +434,7 @@ bool ReTCPServer::listenForAll() { bool rc = false; struct addrinfo hints; struct addrinfo* addrInfo; - ReThreadStarter threadStarter(m_maxConnections + 1, m_logger); + ReThreadPool threadStarter(m_maxConnections + 1, m_logger); // first, load up address structs with getaddrinfo(): memset(&hints, 0, sizeof hints); @@ -446,9 +457,8 @@ bool ReTCPServer::listenForAll() { int yes = 1; // Avoid the "Address already in use" error message of finished processes // that are still waiting for the release by the kernel: - if (setsockopt(m_handleSocket, SOL_SOCKET, SO_REUSEADDR, - reinterpret_cast(&yes), - sizeof(int)) == -1) { + if (setsockopt(m_handleSocket, SOL_SOCKET, SO_REUSEADDR, + reinterpret_cast(&yes), sizeof(int)) == -1) { m_logger->sayF(LOG_WARNING | CAT_NETWORK, LC_LISTEN_FOR_ALL_7, i18n("setsockopt() failed: $1")).arg(errno).end(); // this error is not fatal, continue! @@ -483,10 +493,10 @@ bool ReTCPServer::listenForAll() { reCloseSocket(clientSocket); } else { pthread_t sniffer_thread; - ReTCPServerConnection* connection = createConnection(nextId++, - clientSocket, addrClient); + ReTCPServerConnection* connection = createConnection( + nextId++, clientSocket, addrClient); - if (! threadStarter.startThread(*connection)) { + if (!threadStarter.startThread(connection)) { m_logger->sayF(LOG_ERROR | CAT_PROCESS, LC_LISTEN_FOR_ALL_6, i18n("cannot create a thread: $1")).arg( @@ -509,6 +519,15 @@ bool ReTCPServer::listenForAll() { return rc; } +/** + * Returns the logger. + * + * @param the logger for error handling + */ +ReLogger* ReTCPServer::logger() { + return m_logger; +} + /** * Constructor. */ @@ -554,15 +573,20 @@ ReTCPEchoServer::~ReTCPEchoServer() { * PS_ABORT: connection should be finished */ ReNetCommandHandler::ProcessingState ReTCPEchoServer::handleNetCommand( - ReByteBuffer& command, ReByteBuffer& data, ReTCPConnection* connection) { - ReByteBuffer answer; + ReByteBuffer& command, ReByteBuffer& data, ReTCPConnection* connection) { ProcessingState rc = PS_UNDEF; if (command.equals("echo ")) { - connection->send("Echo ", data.str(), data.length()); + connection->send("Echo", data.str(), data.length()); rc = PS_PROCESSED; } else if (command.equals("strlen ")) { - answer.setLength(0).appendInt(data.length()); - connection->send("Strlen ", answer.str(), answer.length()); + m_toSend.setLength(0).appendInt(data.length()); + connection->send("Strlen ", m_toSend.str(), m_toSend.length()); + rc = PS_PROCESSED; + } else if (command.equals("filldata")) { + int length = atol(data.str()); + if (m_toSend.length() != length || !m_toSend.startsWith("xxxxx")) + m_toSend.setLength(0).appendChar('x', length); + connection->send("Filldata", m_toSend.str(), m_toSend.length()); rc = PS_PROCESSED; } else if (command.equals("localtim")) { time_t now2 = time(NULL); @@ -580,4 +604,20 @@ ReNetCommandHandler::ProcessingState ReTCPEchoServer::handleNetCommand( } return rc; } -; + +/** + * Constructor. + */ +ReTCPStopClient::ReTCPStopClient(ReLogger* logger) : + ReTCPClient(logger) { +} +/** + * Destructor. + */ +ReTCPStopClient::~ReTCPStopClient() { +} + +void ReTCPStopClient::stopServer(int port, const char* ip) { + connect(ip, port); + send("stop", NULL); +} diff --git a/net/ReTCP.hpp b/net/ReTCP.hpp index 22f3683..b9e620f 100644 --- a/net/ReTCP.hpp +++ b/net/ReTCP.hpp @@ -20,7 +20,7 @@ */ class ReSocketAddress { public: - ReSocketAddress(ReLogger* logger); + ReSocketAddress(ReLoggerOwner* loggerOwner); virtual ~ReSocketAddress(); public: /** @@ -58,7 +58,7 @@ protected: //@ AF_INET (for IP4) or AF_INET6 (for IP6) int m_family; int m_port; - ReLogger* m_logger; + ReLoggerOwner* m_loggerOwner; char m_ip[INET6_ADDRSTRLEN + 1]; ReByteBuffer m_name; }; @@ -68,7 +68,7 @@ protected: */ class ReTCPConnection: public ReSocketAddress { public: - ReTCPConnection(int id, ReLogger* logger); + ReTCPConnection(int id, ReLoggerOwner* loggerOwner); virtual ~ReTCPConnection(); public: void close(); @@ -98,7 +98,6 @@ protected: ReByteBuffer m_peerName; ReByteBuffer m_received; ReByteBuffer m_toSend; - ReLogger* m_logger; int m_handleSocket; int m_id; uint32_t m_noSent; @@ -113,12 +112,15 @@ public: /** * Implements a TCP client. */ -class ReTCPClient: public ReTCPConnection { +class ReTCPClient: public ReTCPConnection, public ReLoggerOwner { public: ReTCPClient(ReLogger* logger); virtual ~ReTCPClient(); public: bool connect(const char* ip, int port); + virtual ReLogger* logger(); +private: + ReLogger* m_logger; }; class ReTCPServer; @@ -133,34 +135,35 @@ public: virtual void run(); private: ReTCPServer* m_server; - ReSlaveAppender m_slaveAppender; }; class ReNetCommandHandler; /** * Implements a multithreaded TCP server. */ -class ReTCPServer: public ReTCPConnection { +class ReTCPServer: public ReTCPConnection, public ReLoggerOwner { public: ReTCPServer(int port, class ReNetCommandHandler& commandHandler, - ReLogger* logger, int maxConnections = 16); + ReLogger* logger, int maxConnections = 16); virtual ~ReTCPServer(); public: /** Returns the command handler. - * @return the handler for the incoming messages - */ - inline ReNetCommandHandler& handler(){ + * @return the handler for the incoming messages + */ + inline ReNetCommandHandler& handler() { return m_handler; } bool listenForAll(); + virtual ReLogger* logger(); private: ReTCPServerConnection* createConnection(int id, int handleSocket, - const struct sockaddr& address); + const struct sockaddr& address); protected: int m_maxConnections; int m_countConnections; ReTCPServerConnection** m_connections; ReNetCommandHandler& m_handler; + ReLogger* m_logger; }; /** @@ -179,7 +182,7 @@ public: ReNetCommandHandler(); /** Destructor. */ - virtual ~ReNetCommandHandler(){ + virtual ~ReNetCommandHandler() { } public: void addHandler(ReNetCommandHandler* handler); @@ -193,18 +196,40 @@ public: * PS_ABORT: connection should be finished */ virtual ProcessingState handleNetCommand(ReByteBuffer& command, - ReByteBuffer& data, ReTCPConnection* connection) = 0; + ReByteBuffer& data, ReTCPConnection* connection) = 0; protected: ReNetCommandHandler* m_nextHandler; }; -class ReTCPEchoServer : public ReTCPServer, public ReNetCommandHandler { +/** + * Implements a TCP server which can serve basic simple commands. + * + * The served commands: + * "echo": returns the sent data
+ * "localtim": returns the local time
+ * "strlen": returns the length of the sent data (for upload bandwith meas.)
+ * "filldata": returns data of a requested length (for download bandwith m.)
+ * "stop": stops the server + */ +class ReTCPEchoServer: public ReTCPServer, public ReNetCommandHandler { public: ReTCPEchoServer(int port, ReLogger* logger); virtual ~ReTCPEchoServer(); public: virtual ProcessingState handleNetCommand(ReByteBuffer& command, - ReByteBuffer& data, ReTCPConnection* connection); + ReByteBuffer& data, ReTCPConnection* connection); +}; + +/** + * Implements a TCP client which can stop a TCP server like the echo server. + */ +class ReTCPStopClient: public ReTCPClient { +public: + ReTCPStopClient(ReLogger* logger); + virtual ~ReTCPStopClient(); +public: + void stopServer(int port, const char* ip = "localhost"); }; + #endif /* NET_RETCP_HPP_ */ diff --git a/net/ReUdpConnection.cpp b/net/ReUdpConnection.cpp index 8f4340f..77a2989 100644 --- a/net/ReUdpConnection.cpp +++ b/net/ReUdpConnection.cpp @@ -12,19 +12,20 @@ * param verbose TRUE: */ ReUdpConnection::ReUdpConnection(bool isServer, ReLogger* logger) : - m_socket(0), - //m_address - m_buffer(8096), - m_port(-1), - m_logger(logger), - m_isServer(isServer) -{ + m_socket(0), + //m_address + m_buffer(8096), + m_port(-1), + m_lastReceipt(0), + m_logger(logger), + m_isServer(isServer) { memset(&m_address, 0, sizeof m_address); - if ((m_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { - m_logger->sayF(LOG_ERROR|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_CONSTRUCT, - i18n("Cannot creat a socket: $1")).arg(strerror(errno)).end(); - exit(1); - } + if ((m_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + m_logger->sayF(LOG_ERROR | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_CONSTRUCT, i18n("Cannot create a socket: $1")).arg( + strerror(errno)).end(); + exit(1); + } } /** @brief Destructor. * @@ -58,13 +59,13 @@ const char* ReUdpConnection::address() const { * Otherwise: The length of the received message. * */ -int ReUdpConnection::receive(int timeout, ReByteBuffer* buffer, bool doLog){ +int ReUdpConnection::receive(int timeout, ReByteBuffer* buffer, bool doLog) { socklen_t addrLength = sizeof m_address; bool doRead = true; - if (buffer == NULL){ + if (buffer == NULL) { buffer = &m_buffer; } - if (timeout > 0){ + if (timeout > 0) { int maxfd = m_socket; fd_set rdset; bzero(&rdset, sizeof rdset); @@ -72,26 +73,24 @@ int ReUdpConnection::receive(int timeout, ReByteBuffer* buffer, bool doLog){ timeval timeval; timeval.tv_sec = timeout / 1000; timeval.tv_usec = timeout % 1000 * 1000; - select(maxfd+1, &rdset, NULL, NULL, &timeval); + select(maxfd + 1, &rdset, NULL, NULL, &timeval); doRead = FD_ISSET(m_socket, &rdset); } buffer->ensureSize(8096 + 1); size_t size = buffer->capacity(); buffer->setLength(size); if (!doRead) - m_logger->sayF(LOG_WARNING|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_RECEIVE_2, - i18n("Nothing received since $1 sec")).arg(timeout/1000.0, "%.3f").end(); + m_logger->sayF(LOG_WARNING | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_RECEIVE_2, i18n("Nothing received since $1 sec")) + .arg(timeout / 1000.0, "%.3f").end(); else { - int length = recvfrom( - m_socket, - buffer->buffer(), size - 1, 0, - (struct sockaddr *) &m_address, - &addrLength); + int length = recvfrom(m_socket, buffer->buffer(), size - 1, 0, + (struct sockaddr *) &m_address, &addrLength); buffer->setLength(length >= 0 ? length : 0); if (doLog) - m_logger->sayF(LOG_INFO|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_RECEIVE_1, - "$1:$2 $3").arg(address()).arg(m_port) - .arg(buffer->buffer()).end(); + m_logger->sayF(LOG_INFO | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_RECEIVE_1, "$1:$2 $3").arg(address()).arg( + m_port).arg(buffer->buffer()).end(); } return buffer->length(); } @@ -104,39 +103,40 @@ int ReUdpConnection::receive(int timeout, ReByteBuffer* buffer, bool doLog){ * Otherwise: The number of sent bytes. * */ -int ReUdpConnection::send(const char* buffer, int bufferLength){ - socklen_t size = sizeof (m_address); +int ReUdpConnection::send(const char* buffer, int bufferLength) { + socklen_t size = sizeof(m_address); if (bufferLength == -1) bufferLength = strlen(buffer); - int rc = sendto(m_socket, buffer, bufferLength, 0, - (sockaddr*)&m_address, size); + int rc = sendto(m_socket, buffer, bufferLength, 0, (sockaddr*) &m_address, + size); if (rc <= 0) - m_logger->sayF(LOG_ERROR|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_SEND_1, - i18n("Sending failed: $1:$2 $3")) - .arg(address()).arg(m_port).arg(strerror(errno)).end(); + m_logger->sayF(LOG_ERROR | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_SEND_1, i18n("Sending failed: $1:$2 $3")).arg( + address()).arg(m_port).arg(strerror(errno)).end(); else - m_logger->sayF(LOG_INFO|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_SEND_2, - i18n("$1 bytes sent")).arg(rc).end(); + m_logger->sayF(LOG_INFO | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_SEND_2, i18n("$1 bytes sent")).arg(rc).end(); return rc; } /** @brief Returns the internal receive buffer. * * @return The internal buffer. */ -ReByteBuffer& ReUdpConnection::buffer(){ +ReByteBuffer& ReUdpConnection::buffer() { return m_buffer; } /** @brief Closes the connection. */ -void ReUdpConnection::close(){ - if (m_socket != 0) - { - m_logger->sayF(LOG_INFO|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_CLOSE_1, - i18n("Connection has been closed: $1:$2")).arg(address()).arg(m_port).end(); +void ReUdpConnection::close() { + if (m_socket != 0) { + m_logger->sayF(LOG_INFO | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_CLOSE_1, i18n("Connection has been closed: $1:$2")) + .arg(address()).arg(m_port).end(); if (::close(m_socket) != 0) - m_logger->sayF(LOG_ERROR|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_CLOSE_2, - i18n("socket close failed: $1")).arg(strerror(errno)).end(); + m_logger->sayF(LOG_ERROR | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_CLOSE_2, i18n("socket close failed: $1")).arg( + strerror(errno)).end(); m_socket = 0; } } @@ -146,8 +146,7 @@ void ReUdpConnection::close(){ * @param logger Logger. */ ReUdpServer::ReUdpServer(ReLogger* logger) : - ReUdpConnection(true, logger) -{ + ReUdpConnection(true, logger) { } /** @brief Destructor. @@ -162,23 +161,23 @@ ReUdpServer::~ReUdpServer() { * @return true: Success. false: Connection failed. */ -bool ReUdpServer::connect(int port){ +bool ReUdpServer::connect(int port) { bool rc = true; - m_address.sin_family = AF_INET; - m_address.sin_port = htons(port); - m_address.sin_addr.s_addr = INADDR_ANY; - bzero(&(m_address.sin_zero), 8); + m_address.sin_family = AF_INET; + m_address.sin_port = htons(port); + m_address.sin_addr.s_addr = INADDR_ANY; + bzero(&(m_address.sin_zero), 8); - if (bind(m_socket,(struct sockaddr *)&m_address, - sizeof(struct sockaddr)) == -1) - { - m_logger->sayF(LOG_ERROR|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_CONNECT_1, - i18n("bind() failed on port $1: $2")).arg(port).arg(strerror(errno)).end(); - rc = false; - } - else - m_logger->sayF(LOG_INFO|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_CONNECT_2, - i18n("Waiting for client on port $1")).arg(port).end(); + if (bind(m_socket, (struct sockaddr *) &m_address, sizeof(struct sockaddr)) + == -1) { + m_logger->sayF(LOG_ERROR | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_CONNECT_1, i18n("bind() failed on port $1: $2")) + .arg(port).arg(strerror(errno)).end(); + rc = false; + } else + m_logger->sayF(LOG_INFO | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_CONNECT_2, i18n("Waiting for client on port $1")) + .arg(port).end(); m_port = port; return rc; @@ -188,7 +187,7 @@ bool ReUdpServer::connect(int port){ * @param logger Logger. */ ReUdpClient::ReUdpClient(ReLogger* logger) : - ReUdpConnection(false, logger){ + ReUdpConnection(false, logger) { } /** @brief Destructor. @@ -203,25 +202,26 @@ ReUdpClient::~ReUdpClient() { * * @param return true: Success. */ -bool ReUdpClient::connect(const char* ip, int port){ - struct hostent *host; - bool rc = false; - host= (struct hostent *) gethostbyname((char *) ip); +bool ReUdpClient::connect(const char* ip, int port) { + struct hostent *host; + bool rc = false; + host = (struct hostent *) gethostbyname((char *) ip); - if (host == NULL){ - m_logger->sayF(LOG_ERROR|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_CONNECT_1, - i18n("Invalid IP: $1")).arg(ip).end(); - } else { + if (host == NULL) { + m_logger->sayF(LOG_ERROR | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_CONNECT_1, i18n("Invalid IP: $1")).arg(ip).end(); + } else { m_address.sin_family = AF_INET; m_address.sin_port = htons(port); - m_address.sin_addr = *((struct in_addr *)host->h_addr); - bzero(&(m_address.sin_zero),8); + m_address.sin_addr = *((struct in_addr *) host->h_addr); + bzero(&(m_address.sin_zero), 8); - m_logger->sayF(LOG_INFO|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_CONNECT_2, - i18n("Connected to $1:$2")).arg(ip).arg(port).end(); + m_logger->sayF(LOG_INFO | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_CONNECT_2, i18n("Connected to $1:$2")).arg(ip).arg( + port).end(); m_port = port; rc = true; - } + } return rc; } @@ -231,14 +231,13 @@ bool ReUdpClient::connect(const char* ip, int port){ * @param logger Logger. */ ReUdpMaster::ReUdpMaster(int port, ReLogger* logger) : - ReUdpServer(logger) -{ + ReUdpServer(logger) { connect(port); } /** @brief Destructor. */ -ReUdpMaster::~ReUdpMaster(){ +ReUdpMaster::~ReUdpMaster() { } /** @brief Tests whether the message can be logged. * @@ -251,25 +250,25 @@ ReUdpMaster::~ReUdpMaster(){ * @return true: The message should be logged. * false: Otherwise. */ -bool ReUdpMaster::canLog(ReByteBuffer& message){ +bool ReUdpMaster::canLog(ReByteBuffer& message) { return true; } /** @brief Receives UDP messages and send answers. */ -void ReUdpMaster::run(){ +void ReUdpMaster::run() { ReByteBuffer answer; bool again = true; - while(again){ + while (again) { receive(0, NULL, false); answer.setLength(0); if (canLog(m_buffer)) - m_logger->sayF(LOG_INFO|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_RUN_1, - "$1:$2 $3").arg(address()).arg(m_port) - .arg(m_buffer.buffer()).end(); + m_logger->sayF(LOG_INFO | GRAN_USER | CAT_NETWORK, + LC_UDPCONNECTION_RUN_1, "$1:$2 $3").arg(address()).arg(m_port) + .arg(m_buffer.buffer()).end(); again = handlePage(m_buffer, answer, *this); - if (answer.length() > 0){ + if (answer.length() > 0) { send(answer.buffer(), answer.length()); } } diff --git a/net/ReUdpConnection.hpp b/net/ReUdpConnection.hpp index 36ae8a2..bc2787c 100644 --- a/net/ReUdpConnection.hpp +++ b/net/ReUdpConnection.hpp @@ -17,9 +17,11 @@ public: virtual ~ReUdpConnection(); public: const char* address() const; - int port() const - { return m_port; } - int receive(int timeout = 0, ReByteBuffer* buffer = NULL, bool doLog = true); + int port() const { + return m_port; + } + int receive(int timeout = 0, ReByteBuffer* buffer = NULL, + bool doLog = true); int send(const char* buffer, int bufferLength = -1); void close(); ReByteBuffer& buffer(); @@ -37,7 +39,7 @@ protected: * Implements the base functionality of a server * handling the UDP protocol. */ -class ReUdpServer : public ReUdpConnection { +class ReUdpServer: public ReUdpConnection { public: ReUdpServer(ReLogger* logger); virtual ~ReUdpServer(); @@ -51,8 +53,7 @@ public: * A real server must implement only the method * handlePage(). */ -class ReUdpMaster : public ReUdpServer -{ +class ReUdpMaster: public ReUdpServer { public: ReUdpMaster(int port, ReLogger* logger); virtual ~ReUdpMaster(); @@ -60,14 +61,14 @@ public: public: void run(); protected: - virtual bool handlePage(ReByteBuffer& buffer, - ReByteBuffer& answer, ReUdpMaster& server) = 0; + virtual bool handlePage(ReByteBuffer& buffer, ReByteBuffer& answer, + ReUdpMaster& server) = 0; }; /** * Implements a client handling the UDP protocol. */ -class ReUdpClient : public ReUdpConnection { +class ReUdpClient: public ReUdpConnection { public: ReUdpClient(ReLogger* logger); virtual ~ReUdpClient(); @@ -75,5 +76,4 @@ public: bool connect(const char* ip, int port); }; - #endif /* UDPSERVER_H_ */ diff --git a/os/ReDirTools.cpp b/os/ReDirTools.cpp index 51e0cab..d9f95ca 100644 --- a/os/ReDirTools.cpp +++ b/os/ReDirTools.cpp @@ -48,7 +48,7 @@ static const char* s_helpSummary[] = { "dirtool or dt ", "delete delete the selected files", "help shows info about the arguments/options", "list shows the meta data of the selected files", - "random displays random numbers", + "random displays random numbers", "statistic shows statistics about a direcctory tree", "synchronize copies only modified or new files from", " from a source directory tre to a target", @@ -87,28 +87,25 @@ const char* s_listExamples[] = "dirtool li --type=f -y7d --size=10M -p;*.cpp;*.hpp;Makefile*;-*~ /home/data", NULL }; -const char* s_checksumUsage[] = { - ": c(hecksum) [] [ ...]", - " shows a check sum of the given files or manages a checksum storage file in each directory for observing", - NULL }; +const char* s_checksumUsage[] = + { ": c(hecksum) [] [ ...]", + " shows a check sum of the given files or manages a checksum storage file in each directory for observing", + NULL }; const char* s_checksumExamples[] = { "dirtool ch --buffer-size=512 e:\\data", "dirtool check -cList -p;*.iso /home/iso /down/debian.iso", "dirtool checksum -cBuild -aMD5 /home", "dirtool checksum --command=Compare /home", "dirtool checksum -cUpdate -O/var/log/checksum.log /home", NULL }; -const char* s_randomUsage[] = { - ": r(andom) count until [from]", - " displays random numbers.", - " count of generated numbers", - " the maximum (including) value of the numbers", - " the minimum (including) value of the numbers. Default: 1", - NULL }; +const char* s_randomUsage[] = { ": r(andom) count until [from]", + " displays random numbers.", " count of generated numbers", + " the maximum (including) value of the numbers", + " the minimum (including) value of the numbers. Default: 1", + NULL }; const char* s_randomExamples[] = { "dirtool ra --multiple -w3 10 33", - "dirtool rand -s 6 49", - "dirtool rand --sort --width=1 5 50", - "dirtool rand --sort --width=1 2 10", - NULL }; + "dirtool rand -s 6 49", "dirtool rand --sort --width=1 5 50", + "dirtool rand --sort --width=1 2 10", + NULL }; static const char* s_statisticUsage[] = { ": st(atistic) [] [ ...] []", @@ -139,22 +136,17 @@ const char* s_syncExamples[] = { "dirtool sync --type=r --max-size=1G usr etc /media/backup", NULL }; -const char* s_tcpUsage[] = - { ": tcp [] [ ...]", - " test tool for network test", - ":", - " server", - " client [ []]", - " : URL of the server", - " : number of messages to send", - NULL }; -const char* s_tcpExamples[] = { - "dirtool tcp -p 5555 server", +const char* s_tcpUsage[] = { + ": tcp [] [ ...]", + " test tool for network test", ":", " server", + " client [ []]", + " : URL of the server", " : number of messages to send", + NULL }; +const char* s_tcpExamples[] = { "dirtool tcp -p 5555 server", "dirtool tcp -p 5555 client localhost 10000 10", "dirtool tcp -p 5555 --buffer-size=1024 client 192.168.7.3 10 25", NULL }; - const char* s_touchUsage[] = { ": touch [] [ ...]", " sets the filetimes (modification and/or access time) of the selected files", @@ -747,13 +739,13 @@ bool ReTool::trace(const char* currentFile) { */ void ReTool::run(int argc, const char** argv) { try { - if (argc < 0){ - for (argc = 0; argv[argc] != NULL; argc++){ + if (argc < 0) { + for (argc = 0; argv[argc] != NULL; argc++) { // nothing to do } } m_programArgs.init(argc, argv); - if (m_programArgs.getArgCount() < m_minArguments) + if (m_programArgs.argCount() < m_minArguments) m_programArgs.help(i18n("too few arguments"), false, stdout); if (m_hasStandardArgs) setFilterFromProgramArgs(m_filter); @@ -775,11 +767,11 @@ void ReTool::run(int argc, const char** argv) { * */ void ReTool::processFileArguments() { - int max = m_programArgs.getArgCount() - m_reservedLast; + int max = m_programArgs.argCount() - m_reservedLast; // Test whether the arguments are files or directories: ReByteBuffer arg; for (int ii = m_reservedFirst; ii < max; ii++) { - arg = m_programArgs.getArg(ii); + arg = m_programArgs.arg(ii); if (!exists(arg) != 0) m_programArgs.help( ReByteBuffer(i18n("not a file or a directory: ")).append(arg) @@ -787,7 +779,7 @@ void ReTool::processFileArguments() { } // process the files: for (int ii = m_reservedFirst; ii < max; ii++) { - const char* arg = m_programArgs.getArg(ii); + const char* arg = m_programArgs.arg(ii); if (S_ISDIR(m_statInfo.st_mode)) processTree(arg); else @@ -942,7 +934,9 @@ ReDirStatisticData& ReDirStatisticData::operator =( */ ReDirStatistic::ReDirStatistic(ReLogger* logger, int deltaList, int deltaBuffer) : ReTool(s_statisticUsage, s_statisticExamples, 2, 0, 1, false, logger), - m_list(deltaList, deltaBuffer) { + m_list(deltaList, deltaBuffer), + m_traceInterval(60), + m_lastTrace(0) { // standard short options: D d O o P p T t v y Z z m_programArgs.addBool("kbyte", i18n("output format is ' ' (like unix 'du' command)"), 'k', @@ -986,26 +980,25 @@ ReDirBatch::ReDirBatch(ReLogger* logger) : m_isExe(false) { // standard short options: D d O o P p T t v y Z z m_programArgs.addString("first", - i18n("defines the first line of the output"), - '1', "first-line", true, + i18n("defines the first line of the output"), '1', "first-line", true, #if defined __linux__ - "#! /bin/sh" + "#! /bin/sh" #elif defined __WIN32__ - "rem this batch is created by dirtool" + "rem this batch is created by dirtool" #endif - ); +) ; m_programArgs.addString("arguments", i18n("template for the output line.\n" - "Possible placeholders: (e.g. e:\\data\\sample.txt)\n" - " !full!: e:\\data\\sample.txt\n" - " !path!: e:\\data\\\n" - " !basename!: sample.txt\n" - " !name!: sample\n" - " !ext!: .txt\n" - "example: --arguments='echo !basename! in !path! found'"), 'a', - "arguments", false, NULL); + "Possible placeholders: (e.g. e:\\data\\sample.txt)\n" + " !full!: e:\\data\\sample.txt\n" + " !path!: e:\\data\\\n" + " !basename!: sample.txt\n" + " !name!: sample\n" + " !ext!: .txt\n" + "example: --arguments='echo !basename! in !path! found'"), 'a', + "arguments", false, NULL); m_programArgs.addString("script", - i18n("name of the script (starts each output line)"), 'c', "script", - false, NULL); + i18n("name of the script (starts each output line)"), 'c', "script", + false, NULL); #if defined __WIN32__ m_programArgs.addBool("isexe", i18n("supresses the starting 'call' of each output line" @@ -1083,7 +1076,7 @@ void ReDirBatch::doIt() { #elif defined __WIN32__ static const char* prefix = "rem "; #endif - printSummary (prefix); + printSummary(prefix); } /** @@ -1132,26 +1125,27 @@ ReDirChecksum::ReDirChecksum(ReLogger* logger) : m_digest(NULL), m_buffer() { // standard short options: D d O o P p T t v y Z z - m_programArgs.addString("algorithm", - i18n("algorithm: 'MD5' or 'RPD64'"), 'a', "--algorithm", false, "MD5"); + m_programArgs.addString("algorithm", i18n("algorithm: 'MD5' or 'RPD64'"), + 'a', "--algorithm", false, "MD5"); m_programArgs.addInt("buffersize", i18n("buffer size for file reading (in KiByte)"), 'b', "--buffer-size", 4 * 1024); m_programArgs.addString("command", - i18n("'build': builds in each directory a file '.dt.chksum' with sum and name\n" - "'compare': shows differences between the content of '.dt.chksum' and the current files\n" - "'list': shows checksum and filename\n" - "'update': like compare, but update the content of '.dt.chksum'"), - 'c', "--command", false, "list"); - m_programArgs.addInt("salt", - i18n("a number which change the checksum"), 's', "--salt", 0); + i18n( + "'build': builds in each directory a file '.dt.chksum' with sum and name\n" + "'compare': shows differences between the content of '.dt.chksum' and the current files\n" + "'list': shows checksum and filename\n" + "'update': like compare, but update the content of '.dt.chksum'"), + 'c', "--command", false, "list"); + m_programArgs.addInt("salt", i18n("a number which change the checksum"), + 's', "--salt", 0); addStandardFilterOptions(); } /** * Destructor. */ -ReDirChecksum::~ReDirChecksum(){ +ReDirChecksum::~ReDirChecksum() { delete m_digest; m_digest = NULL; } @@ -1160,7 +1154,7 @@ ReDirChecksum::~ReDirChecksum(){ * * @param path the directory to process */ -void ReDirChecksum::buildStorage(const char* path, const char* storageFile){ +void ReDirChecksum::buildStorage(const char* path, const char* storageFile) { ReTraverser traverser(path); traverser.setMaxLevel(0); ReDirStatus_t* entry; @@ -1168,18 +1162,18 @@ void ReDirChecksum::buildStorage(const char* path, const char* storageFile){ digest2.setSalt(0x2004199111121989ll); ReByteBuffer line; FILE* fp = fopen(storageFile, "w"); - if (fp == NULL){ + if (fp == NULL) { m_logger->sayF(LOG_ERROR | CAT_FILE, LC_BUILD_DIRECTORY_1, i18n("cannot open file: $1 (errno: $2)")).arg(storageFile).arg( - errno).end(); + errno).end(); } else { int level; while ((entry = traverser.nextFile(level, &m_filter)) != NULL) { line.setLength(0); - if (!entry->isDirectory()){ + if (!entry->isDirectory()) { calculateChecksum(entry->fullName(), *m_digest, m_buffer, - m_logger); + m_logger); line.append(m_digest->hexDigest()); } line.appendChar('\t').append(entry->node()); @@ -1187,8 +1181,8 @@ void ReDirChecksum::buildStorage(const char* path, const char* storageFile){ fprintf(fp, "%s\n", line.str()); if (m_verboseLevel >= V_NORMAL) fprintf(m_output, "%16s\t%s", - entry->isDirectory() ? "" : m_digest->hexDigest().str(), - entry->fullName()); + entry->isDirectory() ? "" : m_digest->hexDigest().str(), + entry->fullName()); } fprintf(fp, "%s\n", digest2.hexDigest().str()); fclose(fp); @@ -1202,11 +1196,11 @@ void ReDirChecksum::buildStorage(const char* path, const char* storageFile){ * @param storageFile the file with the checksums */ void ReDirChecksum::compareDir(const char* path, ReStringList& names, - const char* storageFile){ + const char* storageFile) { // forget the last line (checksum): int count = names.count() - 1; names.remove(count); - for (int ii = 0; ii < count; ii++){ + for (int ii = 0; ii < count; ii++) { const char* name = names.strOf(ii); const char* ptr = strchr(name, '\t'); if (ptr != NULL) @@ -1222,10 +1216,10 @@ void ReDirChecksum::compareDir(const char* path, ReStringList& names, ReSeqArray::Index index; const char* node = entry->node(); // the stringlist stores the string with trailing '\0' - if (! names.binarySearch(node, strlen(node) + 1, index)){ + if (!names.binarySearch(node, strlen(node) + 1, index)) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_DIR_1, - i18n("missing file $1 in storage $2")).arg(entry->fullName()) - .arg(storageFile).end(); + i18n("missing file $1 in storage $2")).arg(entry->fullName()) + .arg(storageFile).end(); } } } @@ -1236,15 +1230,15 @@ void ReDirChecksum::compareDir(const char* path, ReStringList& names, * @param path the directory * @param storageFile the file with the checksums */ -void ReDirChecksum::compareStorage(const char* path, const char* storageFile){ +void ReDirChecksum::compareStorage(const char* path, const char* storageFile) { ReStringList storage; storage.readFromFile(storageFile); - if (storage.count() <= 0){ + if (storage.count() <= 0) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_STORAGE_1, - i18n("empty storage file: $1")).arg(storageFile).end(); - } else if (! isValid(storage)){ + i18n("empty storage file: $1")).arg(storageFile).end(); + } else if (!isValid(storage)) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_STORAGE_2, - i18n("corrupted storage file: $1")).arg(storageFile).end(); + i18n("corrupted storage file: $1")).arg(storageFile).end(); } else { ReStringList cols; ReByteBuffer fullname(path); @@ -1252,49 +1246,49 @@ void ReDirChecksum::compareStorage(const char* path, const char* storageFile){ int pathLength = fullname.length(); struct stat info; // test all files of the storage: - for (size_t ii = 0; ii < storage.count() - 1; ii++){ + for (size_t ii = 0; ii < storage.count() - 1; ii++) { cols.split(storage.strOf(ii), '\t'); int colCount = cols.count(); - if (colCount != 2){ + if (colCount != 2) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_STORAGE_3, - i18n("wrong format ($1) in storage file $2-$3")) - .arg(colCount).arg(storageFile).arg(ii+1).end(); + i18n("wrong format ($1) in storage file $2-$3")).arg( + colCount).arg(storageFile).arg(ii + 1).end(); break; } else { fullname.setLength(pathLength).append(cols.strOf(1)); - if (cols.strLengthOf(0) == 0){ + if (cols.strLengthOf(0) == 0) { // a directory: - if (stat(fullname.str(), &info) != 0){ + if (stat(fullname.str(), &info) != 0) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, - LC_COMPARE_STORAGE_4, - i18n("missing directory $1 ($2-$3)")) - .arg(fullname).arg(storageFile).arg(ii+1).end(); - } else if (! S_ISDIR(info.st_mode)){ + LC_COMPARE_STORAGE_4, + i18n("missing directory $1 ($2-$3)")).arg(fullname) + .arg(storageFile).arg(ii + 1).end(); + } else if (!S_ISDIR(info.st_mode)) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, - LC_COMPARE_STORAGE_5, - i18n("directory is now a file: $1 ($2-$3)")) - .arg(fullname).arg(storageFile).arg(ii+1).end(); + LC_COMPARE_STORAGE_5, + i18n("directory is now a file: $1 ($2-$3)")).arg( + fullname).arg(storageFile).arg(ii + 1).end(); } } else { // a directory: - if (stat(fullname.str(), &info) != 0){ + if (stat(fullname.str(), &info) != 0) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, - LC_COMPARE_STORAGE_6, - i18n("missing file $1 ($2-$3)")) - .arg(fullname).arg(storageFile).arg(ii+1).end(); - } else if (S_ISDIR(info.st_mode)){ + LC_COMPARE_STORAGE_6, + i18n("missing file $1 ($2-$3)")).arg(fullname).arg( + storageFile).arg(ii + 1).end(); + } else if (S_ISDIR(info.st_mode)) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, - LC_COMPARE_STORAGE_7, - i18n("file is now a directory: $1 ($2-$3)")) - .arg(fullname).arg(storageFile).arg(ii+1).end(); + LC_COMPARE_STORAGE_7, + i18n("file is now a directory: $1 ($2-$3)")).arg( + fullname).arg(storageFile).arg(ii + 1).end(); } else { calculateChecksum(fullname.str(), *m_digest, m_buffer, - m_logger); - if (! m_digest->hexDigest().equals(cols.strOf(0))){ + m_logger); + if (!m_digest->hexDigest().equals(cols.strOf(0))) { m_logger->sayF(LOG_ERROR | CAT_SECURITY, - LC_COMPARE_STORAGE_7, - i18n("checksum different: $1 ($2-$3)")) - .arg(fullname).arg(storageFile).arg(ii+1).end(); + LC_COMPARE_STORAGE_7, + i18n("checksum different: $1 ($2-$3)")).arg( + fullname).arg(storageFile).arg(ii + 1).end(); } } } @@ -1312,18 +1306,18 @@ void ReDirChecksum::compareStorage(const char* path, const char* storageFile){ * * @param storage the storage file as string list. */ -bool ReDirChecksum::isValid(const ReStringList& storage){ +bool ReDirChecksum::isValid(const ReStringList& storage) { int count = storage.count(); ReRPD64 digest2; digest2.setSalt(0x2004199111121989ll); - for (int ii = 0; ii < count - 1; ii++){ + for (int ii = 0; ii < count - 1; ii++) { const char* line = storage.strOf(ii); digest2.update(line); } bool rc = true; const char* hex = storage.strOf(count - 1); - if (! digest2.hexDigest().equals(hex)) + if (!digest2.hexDigest().equals(hex)) rc = false; return rc; } @@ -1345,7 +1339,7 @@ void ReDirChecksum::doIt() { m_command = CMD_UPDATE; else help(i18n("unknown command (expected: build compare list update): "), - value.str()); + value.str()); m_programArgs.getString("algorithm", value); if (value.equals("md5", -1, true)) @@ -1353,8 +1347,7 @@ void ReDirChecksum::doIt() { else if (value.equals("rpd64", -1, true)) m_digest = new ReRPD64(); else - help(i18n("unknown algorithm (expected: MD5 RPD64): "), - value.str()); + help(i18n("unknown algorithm (expected: MD5 RPD64): "), value.str()); int salt = m_programArgs.getInt("salt"); if (salt != 0) m_digest->setSalt(salt); @@ -1375,7 +1368,7 @@ void ReDirChecksum::processDir(ReDirStatus_t* entry) { storageFile.ensureLastChar(OS_SEPARATOR_CHAR); storageFile.append(".dt.chksum"); } - switch(m_command){ + switch (m_command) { case CMD_BUILD: buildStorage(entry->fullName(), storageFile.str()); break; @@ -1396,7 +1389,7 @@ void ReDirChecksum::processDir(ReDirStatus_t* entry) { */ void ReDirChecksum::processFile(ReDirStatus_t* entry) { const char* name = entry->fullName(); - switch(m_command){ + switch (m_command) { case CMD_LIST: calculateChecksum(name, *m_digest, m_buffer, m_logger); fprintf(m_output, "%s %s\n", m_digest->hexDigest().str(), name); @@ -1411,7 +1404,7 @@ void ReDirChecksum::processFile(ReDirStatus_t* entry) { * @param path the directory * @param storageFile the file with the checksums */ -void ReDirChecksum::updateStorage(const char* path, const char* storageFile){ +void ReDirChecksum::updateStorage(const char* path, const char* storageFile) { } @@ -1425,14 +1418,14 @@ void ReDirChecksum::updateStorage(const char* path, const char* storageFile){ * @param logger logger for error processing * @return digest (for chaining) */ -ReDigest& ReDirChecksum::calculateChecksum(const char* name, - ReDigest& digest, ReByteBuffer& buffer, ReLogger* logger){ +ReDigest& ReDirChecksum::calculateChecksum(const char* name, ReDigest& digest, + ReByteBuffer& buffer, ReLogger* logger) { FILE* fp = fopen(name, "rb"); if (fp == NULL) { if (logger != NULL) logger->sayF(LOG_ERROR | CAT_FILE, LC_CALCULATE_CHECKSUM_1, i18n("cannot open file: $1 (errno: $2)")).arg(name).arg( - errno).end(); + errno).end(); } else { ReMD5 digest; size_t readBytes; @@ -1481,12 +1474,12 @@ void ReDirDelete::processDir(ReDirStatus_t* entry) { */ void ReDirDelete::processFile(ReDirStatus_t* entry) { const char* name = entry->fullName(); - if (m_verboseLevel >= V_NORMAL){ + if (m_verboseLevel >= V_NORMAL) { fprintf(m_output, "%s\n", name); } if (_unlink(name) != 0) m_logger->sayF(LOG_ERROR | CAT_FILE, LC_DELETE_1, - i18n("cannot delete ($1): $2")).arg(errno).arg(name).end(); + i18n("cannot delete ($1): $2")).arg(errno).arg(name).end(); } /** @@ -1561,15 +1554,16 @@ void ReDirList::processFile(ReDirStatus_t* entry) { ReDirRandom::ReDirRandom(ReLogger* logger) : ReTool(s_randomUsage, s_randomExamples, 2, 0, 0, true, logger) { m_hasStandardArgs = false; - m_programArgs.addBool("multiple", i18n("result can contain a value multiple times"), - 'm', "--multiple", false); - m_programArgs.addInt("perline", i18n("number of values per line"), - 'l', "--values-per-line", 10); - m_programArgs.addBool("sort", i18n("the result is sorted"), - 's', "--sort", false); - m_programArgs.addInt("width", i18n("output format: minimum width of the numbers" - " 0: width of the maximum"), - 'w', "--min-width", 0); + m_programArgs.addBool("multiple", + i18n("result can contain a value multiple times"), 'm', "--multiple", + false); + m_programArgs.addInt("perline", i18n("number of values per line"), 'l', + "--values-per-line", 10); + m_programArgs.addBool("sort", i18n("the result is sorted"), 's', "--sort", + false); + m_programArgs.addInt("width", + i18n("output format: minimum width of the numbers" + " 0: width of the maximum"), 'w', "--min-width", 0); } /** @@ -1578,11 +1572,11 @@ ReDirRandom::ReDirRandom(ReLogger* logger) : void ReDirRandom::doIt() { bool multiple = m_programArgs.getBool("multiple"); bool sort = m_programArgs.getBool("sort"); - int count = atol(m_programArgs.getArg(0)); - int to = atol(m_programArgs.getArg(1)); + int count = atol(m_programArgs.arg(0)); + int to = atol(m_programArgs.arg(1)); int from = 1; - if (m_programArgs.getArgCount() > 2) - from = atol(m_programArgs.getArg(2)); + if (m_programArgs.argCount() > 2) + from = atol(m_programArgs.arg(2)); ReShiftRandom rand; rand.setSeed(rand.nearTrueRandom()); for (int ii = rand.nextInt(100); ii > 0; ii--) @@ -1597,29 +1591,31 @@ void ReDirRandom::doIt() { int found = 0; ReSeqArray values(count); ReByteBuffer value; - if (! multiple && count >= to - from + 1) - help(i18n("not realy random: all possible values requested. Do you mean '--multiple'?")); - while(found < count){ - value.setLength(0).appendInt(from + rand.nextInt((to - from + 1) * factor) / factor, "%010d"); + if (!multiple && count >= to - from + 1) + help( + i18n( + "not realy random: all possible values requested. Do you mean '--multiple'?")); + while (found < count) { + value.setLength(0).appendInt( + from + rand.nextInt((to - from + 1) * factor) / factor, "%010d"); int ix = (int) values.find(value.str()); - if (! multiple && ix != -1) + if (!multiple && ix != -1) continue; found++; values.add(-1, value.str()); } if (sort) values.sort(); - for (int ii = 0; ii < count; ii++){ + for (int ii = 0; ii < count; ii++) { values.get(ii, value); int val = atol(value.str()); printf(format.str(), val, - ii % numbersPerLine == numbersPerLine - 1 ? "\n" : " "); + ii % numbersPerLine == numbersPerLine - 1 ? "\n" : " "); } if (count % numbersPerLine != 0) printf("\n"); } - /** * Calculates the statistic of a directory tree. * @@ -1719,8 +1715,8 @@ const ReStringList& ReDirStatistic::calculate(const char* base, int level, */ void ReDirStatistic::doIt() { int depth = 1; - if (m_programArgs.getArgCount() > 1) { - const char* arg1 = m_programArgs.getArg(1); + if (m_programArgs.argCount() > 1) { + const char* arg1 = m_programArgs.arg(1); if (ReStringUtils::lengthOfUnsigned(arg1, -1, (unsigned *) &depth) == 0) m_programArgs.help("depth is not an integer", false, stdout); } @@ -1728,7 +1724,7 @@ void ReDirStatistic::doIt() { ReByteBuffer& line) = &formatWithSizeFilesAndDirs; if (m_programArgs.getBool("kbyte")) proc = &formatLikeDu; - const ReStringList& list = calculate(m_programArgs.getArg(0), depth, proc); + const ReStringList& list = calculate(m_programArgs.arg(0), depth, proc); ReByteBuffer buffer; for (size_t ix = 0; ix < list.count(); ix++) { buffer.set(list.strOf(ix), list.strLengthOf(ix)); @@ -1834,7 +1830,7 @@ void ReDirTouch::processDir(ReDirStatus_t* entry) { static bool isAbsoluteTime(ReFileTime_t& time) { #if defined __linux__ - static struct tm year1980 = {0, 0, 0, 1, 1 - 1, 1980-1900}; + static struct tm year1980 = { 0, 0, 0, 1, 1 - 1, 1980 - 1900 }; static time_t time1980 = mktime(&year1980); return time.tv_sec >= time1980; #elif defined __WIN32__ @@ -1846,8 +1842,8 @@ static bool isAbsoluteTime(ReFileTime_t& time) { static void addRelativeTime(ReFileTime_t& absTime, const ReFileTime_t& relTime) { #if defined __linux__ - if ( (absTime.tv_nsec += relTime.tv_nsec) >= 1000*1000*1000) { - absTime.tv_nsec -= 1000*1000*1000; + if ((absTime.tv_nsec += relTime.tv_nsec) >= 1000 * 1000 * 1000) { + absTime.tv_nsec -= 1000 * 1000 * 1000; absTime.tv_sec += 1; } absTime.tv_sec += relTime.tv_sec; @@ -1916,9 +1912,8 @@ void ReDirTouch::processFile(ReDirStatus_t* entry) { filetimeIsUndefined(m_modified) ? &m_accessed : &m_modified, bufferTime); fprintf(m_output, "%s -> %s %s\n", - ReDirStatus_t::filetimeToString(entry->modified(), - bufferTime2), - bufferTime.str(), (char*) name); + ReDirStatus_t::filetimeToString(entry->modified(), + bufferTime2), bufferTime.str(), (char*) name); } } } @@ -1957,7 +1952,7 @@ ReErrNo_t ReDirTouch::touch(const char* filename, const ReFileTime_t& modified, if (rc != 0 && logger != NULL) logger->sayF(LOG_ERROR | CAT_FILE, LC_TOUCH_1, i18n("cannot change filetime: $1 (errno: $2)")).arg(filename).arg( - errno).end(); + errno).end(); return rc; } @@ -2079,47 +2074,47 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties, struct stat info; if (properties == NULL) { if (stat(source, &info) == 0) - properties = &info; + properties = &info; else { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1, - i18n("could not find: $1 (errno: $2)")).arg(source) - .arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1, + i18n("could not find: $1 (errno: $2)")).arg(source).arg( + errno).end(); } } FILE* fpSource = fopen(source, "rb"); if (fpSource == NULL) { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2, - i18n("cannot open $1 (errno: $2)")) - .arg(source).arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2, + i18n("cannot open $1 (errno: $2)")).arg(source).arg(errno).end(); } else { - ReFileSize_t size = properties == NULL ? 0x7fffffff : properties->st_size; + ReFileSize_t size = + properties == NULL ? 0x7fffffff : properties->st_size; FILE* fpTarget = fopen(target, "w"); if (fpTarget == NULL) { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3, - i18n("cannot open $1 (errno: $2)")) - .arg(target).arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3, + i18n("cannot open $1 (errno: $2)")).arg(target).arg(errno) + .end(); } else { - while(size > 0) { + while (size > 0) { size_t blockSize = buffer.capacity(); if ((int) blockSize > size) - blockSize = size; + blockSize = size; if (fread(buffer.buffer(), blockSize, 1, fpSource) != 1) { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5, - i18n("cannot read $1 (errno: $2)")) - .arg(source).arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5, + i18n("cannot read $1 (errno: $2)")).arg(source).arg( + errno).end(); break; } size_t written; - if ((written = fwrite(buffer.buffer(), 1, blockSize, - fpTarget)) != blockSize) { + if ((written = fwrite(buffer.buffer(), 1, blockSize, fpTarget)) + != blockSize) { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6, - i18n("cannot write $1 [$2] (errno: $3)")) - .arg(target).arg(written).arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6, + i18n("cannot write $1 [$2] (errno: $3)")).arg( + target).arg(written).arg(errno).end(); break; } size -= blockSize; @@ -2127,7 +2122,7 @@ bool ReDirSync::copyFile(const char* source, ReFileProperties_t* properties, rc = size == 0ll; fclose(fpTarget); if (properties != NULL) - setProperties(target, properties, logger); + setProperties(target, properties, logger); } fclose(fpSource); } @@ -2160,24 +2155,24 @@ bool ReDirSync::setProperties(const char* fullName, times[1].tv_usec = properties->st_mtim.tv_nsec / 1000; if (utimes(fullName, times) != 0) { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1, - i18n("cannot change file times: $1 (errno: $2)")) - .arg(fullName).arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1, + i18n("cannot change file times: $1 (errno: $2)")).arg(fullName) + .arg(errno).end(); rc = false; } int rights = properties->st_mode & (S_IRWXO | S_IRWXG | S_IRWXU); if (chmod(fullName, rights) != 0) { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2, - i18n("cannot change file modes: $1 (errno: $2)")) - .arg(fullName).arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2, + i18n("cannot change file modes: $1 (errno: $2)")).arg(fullName) + .arg(errno).end(); rc = false; } if (chown(fullName, properties->st_uid, properties->st_gid) != 0) { if (logger != NULL) - logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3, - i18n("cannot change file owner: $1 (errno: $2)")) - .arg(fullName).arg(errno).end(); + logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3, + i18n("cannot change file owner: $1 (errno: $2)")).arg(fullName) + .arg(errno).end(); rc = false; } #endif @@ -2246,7 +2241,7 @@ void ReDirSync::doIt() { ReDirEntryFilter_t filter; const char* sep = OS_SEPARATOR; ReByteBuffer buffer; - ReByteBuffer target(m_programArgs.getArg(m_programArgs.getArgCount() - 1)); + ReByteBuffer target(m_programArgs.arg(m_programArgs.argCount() - 1)); target.removeLastChar(OS_SEPARATOR_CHAR); if (!exists(target)) help(i18n("target does not exist: $1"), target.str()); @@ -2265,8 +2260,8 @@ void ReDirSync::doIt() { int treeDirs = 0; int64_t treeSumSizes = 0ll; ReByteBuffer source, targetFile; - for (int ix = 0; ix < m_programArgs.getArgCount() - 1; ix++) { - source.set(m_programArgs.getArg(ix), -1); + for (int ix = 0; ix < m_programArgs.argCount() - 1; ix++) { + source.set(m_programArgs.arg(ix), -1); target.setLength(lengthTargetBase); bool endsWithSlash = source.endsWith(sep, 1); if (endsWithSlash) @@ -2324,8 +2319,7 @@ void ReDirSync::doIt() { int diff = int( m_statInfo.st_mtime - entry->filetimeToTime(entry->modified())); - if (!ignoreDate - && diff <= maxFileTimeDiff) { + if (!ignoreDate && diff <= maxFileTimeDiff) { if (m_verboseLevel >= V_CHATTER) fprintf(m_output, "=ignored: %s same time\n", targetRelativePath); @@ -2364,10 +2358,11 @@ void ReDirSync::doIt() { ReDirTCP::ReDirTCP(ReLogger* logger) : ReTool(s_tcpUsage, s_tcpExamples, 1, 0, 0, true, logger) { m_hasStandardArgs = false; - m_programArgs.addInt("size", i18n("size of the message to send/receive (in KiByte)"), - 'b', "--buffer-size", 64); - m_programArgs.addInt("port", i18n("port of the server/client"), - 'p', "--port", 58111); + m_programArgs.addInt("size", + i18n("size of the message to send/receive (in KiByte)"), 'b', + "--buffer-size", 64); + m_programArgs.addInt("port", i18n("port of the server/client"), 'p', + "--port", 58111); } /** @@ -2377,20 +2372,20 @@ void ReDirTCP::doIt() { int port = m_programArgs.getInt("port"); int bufferSize = m_programArgs.getInt("size") * 1024; - const char* command = m_programArgs.getArg(0); - if (_stricmp(command, "server") == 0){ + const char* command = m_programArgs.arg(0); + if (_stricmp(command, "server") == 0) { ReTCPEchoServer server(port, m_logger); server.listenForAll(); - } else if (_stricmp(command, "client") == 0){ - const char* ip = m_programArgs.getArg(1); + } else if (_stricmp(command, "client") == 0) { + const char* ip = m_programArgs.arg(1); int rounds = 10; int interval = 5; - if (m_programArgs.getArgCount() > 2) - rounds = atoi(m_programArgs.getArg(2)); - if (m_programArgs.getArgCount() > 3) - interval = atoi(m_programArgs.getArg(3)); + if (m_programArgs.argCount() > 2) + rounds = atoi(m_programArgs.arg(2)); + if (m_programArgs.argCount() > 3) + interval = atoi(m_programArgs.arg(3)); ReTCPClient client(m_logger); - if (client.connect(ip, port)){ + if (client.connect(ip, port)) { time_t start = time(NULL); int64_t millisec; ReByteBuffer message; @@ -2398,22 +2393,22 @@ void ReDirTCP::doIt() { time_t lastPrint = start; int64_t size = 0; int duration = 0; - for (int ii = 0; ii < rounds; ii++){ + for (int ii = 0; ii < rounds; ii++) { client.send("strlen", message.str(), message.length()); size += message.length(); time_t now = time(NULL); - if (now >= lastPrint + interval){ + if (now >= lastPrint + interval) { duration = int(now - start); printf("%2d: %9.3f MiByte %8.3f kiByte/sec\n", ii, - size / 1024.0 / 1024, (double) size / duration / 1024); + size / 1024.0 / 1024, (double) size / duration / 1024); lastPrint = now; } } duration = int(time(NULL) - start); if (duration == 0) duration = 1; - printf("%2d: %9.3f MiByte %8.3f kiByte/sec\n", rounds, size / 1024.0 / 1024, - (double) size / duration / 1024); + printf("%2d: %9.3f MiByte %8.3f kiByte/sec\n", rounds, + size / 1024.0 / 1024, (double) size / duration / 1024); } } else @@ -2421,7 +2416,6 @@ void ReDirTCP::doIt() { } - /** * Constructor. * @@ -2436,14 +2430,13 @@ ReDirWhich::ReDirWhich(ReLogger* logger) : i18n("a path list (separator see option 'separator'"), 'l', "list", false, NULL); m_programArgs.addString("separator", - i18n("separator between the path elements"), - 's', "separator", false, + i18n("separator between the path elements"), 's', "separator", false, #if defined __linux__ - ":" + ":" #elif defined __WIN32__ - ";" + ";" #endif - ); +) ; m_programArgs.addString("variable", i18n("variable with the path list"), 'v', "variable", false, "PATH"); m_hasStandardArgs = false; @@ -2470,10 +2463,10 @@ void ReDirWhich::doIt() { items.split(path.str(), sep); struct stat info; ReByteBuffer full; - for (int ix = 0; ix < m_programArgs.getArgCount(); ix++) { + for (int ix = 0; ix < m_programArgs.argCount(); ix++) { bool found = false; - ReByteBuffer arg(m_programArgs.getArg(ix)); + ReByteBuffer arg(m_programArgs.arg(ix)); for (size_t ixItem = 0; ixItem < items.count(); ixItem++) { full.set(items.strOf(ixItem)); if (arg.indexOf('*') < 0) { @@ -2568,7 +2561,7 @@ void ReDirTools::run(int argc, const char* argv[], ReTool& tool) { */ int ReDirTools::main(int argc, char* orgArgv[]) { ReDirTools tools; - if (argc < 0){ + if (argc < 0) { argc = 0; for (int ix = 0; orgArgv[ix] != NULL; ix++) argc++; diff --git a/os/ReDirTools.hpp b/os/ReDirTools.hpp index 4b83720..0b52e5c 100644 --- a/os/ReDirTools.hpp +++ b/os/ReDirTools.hpp @@ -72,7 +72,7 @@ typedef struct { FILETIME m_modified; FILETIME m_accessed; ReFileSize_t m_size; -} ReFileProperties_t; +}ReFileProperties_t; #endif /** @@ -171,13 +171,13 @@ protected: private: void buildStorage(const char* path, const char* storageFile); void compareDir(const char* path, ReStringList& names, - const char* storageFile); + const char* storageFile); void compareStorage(const char* path, const char* storageFile); bool isValid(const ReStringList& storage); void updateStorage(const char* path, const char* storageFile); public: - static ReDigest& calculateChecksum(const char* name, - ReDigest& digest, ReByteBuffer& buffer, ReLogger* logger); + static ReDigest& calculateChecksum(const char* name, ReDigest& digest, + ReByteBuffer& buffer, ReLogger* logger); protected: Command m_command; ReDigest* m_digest; @@ -292,7 +292,6 @@ protected: virtual void doIt(); }; - /** * Changes the filetime of files. */ @@ -323,7 +322,11 @@ protected: }; class ReDirTools { - +public: + /** Destructor. + */ + virtual ~ReDirTools() { + } public: virtual void usage(const char* msg, const char* msg2 = NULL); void help(int argc, const char* argv[]); diff --git a/os/ReTraverser.cpp b/os/ReTraverser.cpp index ada7afa..02a95ed 100644 --- a/os/ReTraverser.cpp +++ b/os/ReTraverser.cpp @@ -30,13 +30,13 @@ enum RELOC_TRAVERSER { * Constructor. */ ReDirStatus_t::ReDirStatus_t(ReLogger* logger) : -m_path(), -m_fullName(), -m_passNo(0), -m_logger(logger), + m_path(), + m_fullName(), + m_passNo(0), + m_logger(logger), #ifdef __linux__ -m_handle(NULL), -m_data(NULL) + m_handle(NULL), + m_data(NULL) //m_status; #elif defined WIN32 m_handle(INVALID_HANDLE_VALUE), @@ -136,7 +136,7 @@ bool ReDirStatus_t::findFirst() { bool rc = false; #if defined __linux__ if (m_handle != NULL) - closedir(m_handle); + closedir(m_handle); m_handle = opendir(m_path.str()); rc = m_handle != NULL && (m_data = readdir(m_handle)) != NULL; m_status.st_ino = 0; @@ -283,7 +283,7 @@ bool ReDirStatus_t::getPrivilege(const char* privilege, ReLogger* logger) { bool ReDirStatus_t::isDirectory() { #ifdef __linux__ return m_data->d_type == DT_DIR - || (m_data->d_type == DT_UNKNOWN && S_ISDIR(getStatus()->st_mode)); + || (m_data->d_type == DT_UNKNOWN && S_ISDIR(getStatus()->st_mode)); #elif defined __WIN32__ return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); #endif @@ -296,8 +296,10 @@ bool ReDirStatus_t::isDirectory() { */ bool ReDirStatus_t::isDotDir() const { #ifdef __linux__ - bool rc = m_data == NULL || (m_data->d_name[0] == '.' && (m_data->d_name[1] == '\0' - || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0'))); + bool rc = m_data == NULL + || (m_data->d_name[0] == '.' + && (m_data->d_name[1] == '\0' + || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0'))); #elif defined __WIN32__ bool rc = m_data.cFileName[0] == '.' && (m_data.cFileName[1] == '\0' || (m_data.cFileName[1] == '.' && m_data.cFileName[2] == '\0')); @@ -316,7 +318,7 @@ bool ReDirStatus_t::isLink() { bool rc; #ifdef __linux__ rc = m_data->d_type == DT_LNK - || (m_data->d_type == DT_UNKNOWN && S_ISLNK(getStatus()->st_mode)); + || (m_data->d_type == DT_UNKNOWN && S_ISLNK(getStatus()->st_mode)); #elif defined __WIN32__ rc = 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT); #endif @@ -330,7 +332,7 @@ bool ReDirStatus_t::isLink() { bool ReDirStatus_t::isRegular() { #ifdef __linux__ return m_data->d_type == DT_REG - || (m_data->d_type == DT_UNKNOWN && S_ISREG(getStatus()->st_mode)); + || (m_data->d_type == DT_UNKNOWN && S_ISREG(getStatus()->st_mode)); #elif defined __WIN32__ return 0 == (m_data.dwFileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)); #endif @@ -426,15 +428,15 @@ const char* ReDirStatus_t::rightsAsString(ReByteBuffer& buffer, bool numerical, buffer.appendChar(' '); struct passwd* passwd = getpwuid(getStatus()->st_uid); if (passwd == NULL) - buffer.appendInt(getStatus()->st_uid, "%4d"); + buffer.appendInt(getStatus()->st_uid, "%4d"); else - addId(passwd->pw_name, 5, buffer); + addId(passwd->pw_name, 5, buffer); buffer.appendChar(' '); struct group* group = getgrgid(getStatus()->st_gid); if (group == NULL) - buffer.appendInt(getStatus()->st_gid, "%4d"); + buffer.appendInt(getStatus()->st_gid, "%4d"); else - addId(group->gr_name, 5, buffer); + addId(group->gr_name, 5, buffer); buffer.appendChar(' '); } #elif defined __WIN32__ @@ -490,21 +492,21 @@ ReDirStatus_t::Type_t ReDirStatus_t::type() { #if defined __linux__ int flags = getStatus()->st_mode; if (S_ISDIR(flags)) - rc = TF_SUBDIR; + rc = TF_SUBDIR; else if (flags == 0 || S_ISREG(flags)) - rc = TF_REGULAR; + rc = TF_REGULAR; else if (S_ISLNK(flags)) - rc = TF_LINK; + rc = TF_LINK; else if (S_ISCHR(flags)) - rc = TF_CHAR; + rc = TF_CHAR; else if (S_ISBLK(flags)) - rc = TF_BLOCK; + rc = TF_BLOCK; else if (S_ISFIFO(flags)) - rc = TF_PIPE; + rc = TF_PIPE; else if (S_ISSOCK(flags)) - rc = TF_SOCKET; + rc = TF_SOCKET; else - rc = TF_OTHER; + rc = TF_OTHER; #elif defined __WIN32__ int flags = (m_data.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN @@ -579,7 +581,7 @@ ReDirEntryFilter_t::ReDirEntryFilter_t() : //m_maxAge(0), m_minDepth(0), m_maxDepth(512), - m_allDirectories(false){ + m_allDirectories(false) { setFiletimeUndef(m_minAge); setFiletimeUndef(m_maxAge); } @@ -595,7 +597,7 @@ ReDirEntryFilter_t::~ReDirEntryFilter_t() { bool ReDirEntryFilter_t::match(ReDirStatus_t& entry) { bool rc = false; do { - if (m_allDirectories && entry.isDirectory()){ + if (m_allDirectories && entry.isDirectory()) { rc = true; break; } @@ -628,7 +630,7 @@ bool ReDirEntryFilter_t::match(ReDirStatus_t& entry) { struct stat* ReDirStatus_t::getStatus() { if (m_status.st_ino == 0) { if (stat(fullName(), &m_status) != 0) - m_status.st_ino = 0; + m_status.st_ino = 0; } return &m_status; } diff --git a/os/ReTraverser.hpp b/os/ReTraverser.hpp index ba65297..80ca6e2 100644 --- a/os/ReTraverser.hpp +++ b/os/ReTraverser.hpp @@ -183,7 +183,7 @@ public: class ReTraverser: public ReDirTreeStatistic { public: ReTraverser(const char* base, ReTraceUnit* tracer = NULL, ReLogger* logger = - NULL); + NULL); virtual ~ReTraverser(); public: void changeBase(const char* base); @@ -206,8 +206,9 @@ public: * The value has no interest for the caller * @return true: the path has been changed */ - inline bool hasChangedPath(int& state){ - bool rc = m_directories > state; state = m_directories; + inline bool hasChangedPath(int& state) { + bool rc = m_directories > state; + state = m_directories; return rc; } ReDirStatus_t* rawNextFile(int& level); @@ -216,7 +217,7 @@ public: * @param depthFirst true: files of the subdirectories will * be returned earlier */ - void setDepthFirst(bool depthFirst){ + void setDepthFirst(bool depthFirst) { m_passNoForDirSearch = depthFirst ? 1 : 2; } /** Sets directory filter (pattern list). diff --git a/os/reos.hpp b/os/reos.hpp index ccc7b8a..0cbcae7 100644 --- a/os/reos.hpp +++ b/os/reos.hpp @@ -31,11 +31,11 @@ inline bool operator >(const ReFileTime_t& time1, const ReFileTime_t& time2) { #if defined __linux__ return time1.tv_sec > time2.tv_sec - || (time1.tv_sec == time2.tv_sec && time1.tv_nsec > time2.tv_nsec); + || (time1.tv_sec == time2.tv_sec && time1.tv_nsec > time2.tv_nsec); #else return time1.dwHighDateTime > time2.dwHighDateTime - || (time1.dwHighDateTime == time2.dwHighDateTime - && time1.dwLowDateTime > time2.dwLowDateTime); + || (time1.dwHighDateTime == time2.dwHighDateTime + && time1.dwLowDateTime > time2.dwLowDateTime); #endif } #include "os/ReTraverser.hpp" diff --git a/string/ReMatcher.cpp b/string/ReMatcher.cpp index 0e91816..2a68b87 100644 --- a/string/ReMatcher.cpp +++ b/string/ReMatcher.cpp @@ -10,7 +10,7 @@ #include "base/rebase.hpp" #include "string/ReMatcher.hpp" -#ifdef __linux__ +#if 0 // defined __linux__ extern int _strnicmp (const char* s1, const char* s2, size_t n); extern int strncmp (const char* s1, const char* s2, size_t n); extern void* memset (void *s, int c, size_t n); @@ -37,7 +37,8 @@ ReMatcher::~ReMatcher() { ReSimpleMatcher::ReSimpleMatcher() : ReMatcher(), m_pattern(), - m_tokens() { + m_tokens(), + m_ignoreCase(false) { } /** @@ -48,7 +49,8 @@ ReSimpleMatcher::ReSimpleMatcher() : ReSimpleMatcher::ReSimpleMatcher(const char* pattern) : ReMatcher(), m_pattern(), - m_tokens() { + m_tokens(), + m_ignoreCase(false) { compile(pattern); } /** @@ -223,7 +225,8 @@ const char* ReSimpleMatcher::status(ReByteBuffer& buffer, RePatternList::RePatternList() : m_patternString(), m_patterns(NULL), - m_count(0) { + m_count(0), + m_startNot(0) { } /** * Destructor. -- 2.39.5