* Do what you want.
* No warranties and disclaimer of any damages.
* The latest sources: https://github.com/republib
-*/
+ */
#include "base/rebase.hpp"
/**
* @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() {
}
/**
* @param append <code>true</code>the buffer will not truncated before storage
* @return <code>buffer</code> (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');
}
* @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);
* 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.
* @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());
}
* 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_
* (<code>say().arg().end()</code> 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();
/** Sets the master logger.
* @param logger the master logger
*/
- void setMasterLogger(ReLogger* logger){
+ void setMasterLogger(ReLogger* logger) {
m_masterLogger = logger;
}
private:
--- /dev/null
+/*
+ * 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"
+
--- /dev/null
+/*
+ * 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.
+ *
+ * <pre>int64_t start = ReBaseUtils::timer();
+ * ...
+ * int duration = ReBaseUtils::milliSecSince(start);
+ * </pre>
+ *
+ * @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 <code>milliSecSince()</code>.
+ * <pre>int64_t start = test.timer();
+ * ...
+ * int duration = test.milliSecSince(start);
+ * </pre>
+ * @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_ */
#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.
* @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 <code>ReByteBuffer</code> instance at the end of the buffer.
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;
* < 0: region1 is alphabetically less than region2<br>
* > 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;
unsigned char cc1 = *ptr1++;
unsigned char cc2 = *ptr2++;
int diff = tolower(cc1) - tolower(cc2);
- if (diff != 0)
- {
+ if (diff != 0) {
rc = diff;
break;
}
m_valid = false;
}
if (m_regExprIsInitialized)
- regfree(&m_regExpr);
+ regfree(&m_regExpr);
#elif defined __WIN32__
if (m_handle != INVALID_HANDLE_VALUE) {
FindClose(m_handle);
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);
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;
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__
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;
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;
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;
*/
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';
if (app->accept(mode))
app->say(this, message);
}
- m_mutex.release();
+ m_mutex.unlock();
return true;
}
/** @brief Issues a log message.
* @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;
app->say(this, message);
}
m_charPrefix = safePrefix;
- m_mutex.release();
+ m_mutex.unlock();
return true;
}
* @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,
m_location = location;
m_standardPrefix[0] = '\0';
reset(format);
- m_mutex.release();
+ m_mutex.unlock();
return *this;
}
/** Adds an appender to the appender list.
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');
};
+/**
+ * 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();
}
*/
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
#endif
}
-bool ReMutex::timedWait(int sec){
+bool ReMutex::timedLock(int sec) {
bool rc = true;
#if defined __linux__
struct timespec time;
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
m_values(),
m_args(NULL),
m_argCount(0),
+ m_program(NULL),
m_lastError() {
m_properties.setCapacity(64, 64 * 8, 64 * 1024);
ReByteBuffer line;
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 <code>getInt()</code>.
+ * @param name The name of the option. Used in the methods <code>getBool()</code>.
* @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 <code>getBool()</code>.
+ * @param name The name of the option. Used in the methods <code>getInt()</code>.
* @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.
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 <code>longName != NULL</code>.
- * @param LongName The option`s long name. Not relevant if <code>longName == NULL</code>.
- * @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:
} 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 <code>getArg()</code>.
+ * @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 <code>true</code>: 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);
lines.append(line.str());
}
}
-
+/**
+ * Issues a help message.
+ *
+ * @param message message to show
+ * @param issueLastError <code>true</code>: 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);
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 <code>getArg()</code>.
+ *
+ * @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 <code>longName != NULL</code>.
+ * @param LongName The option`s long name. Not relevant if <code>longName == NULL</code>.
+ * @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());
+}
+
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;
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();
}
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();
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)
* @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);
}
/**
* @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.
enum RELOC_HASHLIST {\r
LC_PREPARE_TO_RUN_1 = LC_THREAD + 1, // 50601\r
LC_START_THREAD_1, // 50602\r
- LC_NE_1, // 50603\r
+ LC_INSERT_THREAD_1, // 50603\r
+ LC_KILL_ALL_THREADS_1, // 50604\r
+ LC_KILL_ALL_THREADS_2, // 50605\r
+ LC_MUTEX_THREADS, // 50606\r
};\r
\r
-\r
/**\r
* Constructor.\r
*\r
* deletes the instance when it is stopped\r
*/\r
ReThread::ReThread(bool autoDelete) :\r
- m_threadId(-1),\r
- m_threadLogger(false),\r
- m_appender(NULL),\r
- m_starter(NULL),\r
+ m_threadId(-1),\r
+ m_threadLogger(false),\r
+ m_appender(NULL),\r
+ m_starter(NULL),\r
#if defined __linux__\r
- m_threadInfo(),\r
+ m_threadInfo(),\r
#elif defined __WIN32__\r
- m_threadInfo(UNDEF_HANDLE),\r
+ m_threadInfo(UNDEF_HANDLE),\r
#endif\r
- m_shouldStop(false),\r
- m_isStopped(false),\r
- m_autoDelete(autoDelete){\r
+ m_shouldStop(false),\r
+ m_isStopped(false),\r
+ m_autoDelete(autoDelete) {\r
#if defined __linux__\r
memset(&m_threadInfo, 0, sizeof m_threadInfo);\r
#endif\r
/**\r
* Destructor.\r
*/\r
-ReThread::~ReThread(){\r
+ReThread::~ReThread() {\r
+ delete m_appender;\r
+ m_appender = NULL;\r
}\r
\r
+/**\r
+ * Returns the logger.\r
+ *\r
+ * @return the logger\r
+ */\r
+ReLogger* ReThread::logger() {\r
+ return &m_threadLogger;\r
+}\r
+\r
+/**\r
+ * Kills the thread.\r
+ *\r
+ * Note: This is very oppressive!\r
+ * The thread starter uses that only if <code>setShouldStop(true)</code>\r
+ * has no success.\r
+ */\r
+void ReThread::kill() {\r
+#if defined __linux__\r
+ pthread_kill(m_threadInfo, SIGKILL);\r
+#elif defined __WIN32__\r
+ KillThread(m_threadInfo);\r
+#endif\r
+}\r
/**\r
* Prepares the thread for running.\r
*\r
* @param starter the instance which has started the thread\r
*/\r
bool ReThread::prepareToRun(int id, ReLogger* masterLogger,\r
- ReThreadStarter* starter){\r
+ ReThreadPool* starter) {\r
bool rc = false;\r
- if (m_starter != NULL){\r
+ if (m_starter != NULL) {\r
globalLogger()->say(LOG_ERROR | CAT_LIB, LC_PREPARE_TO_RUN_1,\r
- i18n("setMasterLogger() is called multiple times"));\r
+ i18n("setMasterLogger() is called multiple times"));\r
} else {\r
m_threadId = id;\r
- m_appender->setMasterLogger(masterLogger);\r
+ if (m_appender == NULL)\r
+ m_appender = new ReSlaveAppender(masterLogger,\r
+ '0' + (id % ('z' - '0' + 1)));\r
+ else\r
+ m_appender->setMasterLogger(masterLogger);\r
m_starter = starter;\r
rc = true;\r
}\r
+ return rc;\r
+}\r
+/**\r
+ * Runs the task and exits the thread.\r
+ */\r
+void ReThread::runAndFinish() {\r
+ run();\r
+#if defined __linux__\r
+ pthread_exit(NULL);\r
+#elif defined __WIN32__\r
+ StopThread(m_threadInfo);\r
+#endif\r
+ m_isStopped = true;\r
+}\r
+\r
+/**\r
+ * Constructor.\r
+ *\r
+ * @param processor the instance that performs the actual task\r
+ */\r
+ReSimpleThread::ReSimpleThread(ReProcessor* processor) :\r
+ ReThread(true),\r
+ m_processor(processor) {\r
+}\r
+/**\r
+ * Destructor.\r
+ */\r
+ReSimpleThread::~ReSimpleThread() {\r
+}\r
+/**\r
+ * This method does the actual task.\r
+ */\r
+void ReSimpleThread::run() {\r
+ m_processor->process();\r
+ m_isStopped = true;\r
}\r
\r
/**\r
* @param maxThreads the maximal number of threads\r
* @param logger the (master) logger for error handling\r
*/\r
-ReThreadStarter::ReThreadStarter(int maxThreads, ReLogger* logger) :\r
- m_nextId(0),\r
- m_logger(logger),\r
- m_maxThreads(maxThreads){\r
+ReThreadPool::ReThreadPool(int maxThreads, ReLogger* logger) :\r
+ m_nextId(0),\r
+ m_logger(logger),\r
+ m_maxThreads(maxThreads),\r
+ m_maxKillTimeSec(3),\r
+ m_mutexThreads(LC_MUTEX_THREADS) {\r
m_threads = new ReThread*[maxThreads];\r
memset(m_threads, 0, maxThreads * sizeof *m_threads);\r
}\r
+\r
/**\r
* Destructor.\r
*/\r
-ReThreadStarter::~ReThreadStarter(){\r
+ReThreadPool::~ReThreadPool() {\r
+ killAllThreads();\r
+}\r
+\r
+/**\r
+ * Inserts a thread into the thread list.\r
+ *\r
+ * @param thread thread to insert\r
+ * @return <code>true</code>: success<br>\r
+ * <code>false</code>: too much threads (no space in list)\r
+ */\r
+bool ReThreadPool::insertThread(ReThread* thread) {\r
+ bool found = false;\r
+ m_mutexThreads.lock();\r
+ for (int ii = 0; ii < m_maxThreads; ii++) {\r
+ ReThread* current = m_threads[ii];\r
+ if (current == NULL) {\r
+ m_threads[ii] = thread;\r
+ found = true;\r
+ break;\r
+ } else if (current->m_isStopped) {\r
+ if (current->m_autoDelete)\r
+ delete current;\r
+ m_threads[ii] = thread;\r
+ found = true;\r
+ }\r
+ }\r
+ m_mutexThreads.unlock();\r
+ if (!found)\r
+ m_logger->sayF(LOG_ERROR | CAT_PROCESS, LC_INSERT_THREAD_1,\r
+ i18n("too much threads: $1")).arg(m_maxThreads).end();\r
+\r
+ return found;\r
+}\r
+/**\r
+ * Stopps all running threads.\r
+ */\r
+void ReThreadPool::killAllThreads() {\r
+ // Orders stop for all threads:\r
+ int countWaiting = 0;\r
+ m_mutexThreads.lock();\r
+ for (int ii = 0; ii < m_maxThreads; ii++) {\r
+ ReThread* current = m_threads[ii];\r
+ if (current != NULL && !current->m_isStopped) {\r
+ countWaiting++;\r
+ current->setShouldStop(true);\r
+ }\r
+ }\r
+ m_mutexThreads.unlock();\r
+ if (countWaiting > 0)\r
+ m_logger->sayF(LOG_INFO | CAT_PROCESS, LC_KILL_ALL_THREADS_1,\r
+ i18n("$1 thread(s) still running")).arg(countWaiting).end();\r
+\r
+ // we observe the thread stopping:\r
+ for (int wait = 0; countWaiting > 0 && wait <= m_maxKillTimeSec; wait++) {\r
+ m_mutexThreads.lock();\r
+ for (int ii = 0; ii < m_maxThreads; ii++) {\r
+ ReThread* current = m_threads[ii];\r
+ if (current != NULL && current->m_isStopped) {\r
+ countWaiting--;\r
+ }\r
+ }\r
+ m_mutexThreads.unlock();\r
+ if (countWaiting > 0)\r
+ sleep(1);\r
+ }\r
+ // now we kill:\r
+ countWaiting = 0;\r
+ for (int ii = 0; ii < m_maxThreads; ii++) {\r
+ m_mutexThreads.lock();\r
+ ReThread* current = m_threads[ii];\r
+ if (current == NULL || current->m_isStopped)\r
+ m_mutexThreads.unlock();\r
+ else {\r
+ current->kill();\r
+ int id = current->m_threadId;\r
+ m_mutexThreads.unlock();\r
+ m_logger->sayF(LOG_WARNING | CAT_PROCESS, LC_KILL_ALL_THREADS_2,\r
+ i18n("thread $1 must be killed")).arg(id).end();\r
+ countWaiting++;\r
+ }\r
+ }\r
+ if (countWaiting > 0)\r
+ // wait 1 msec for end of kill:\r
+ usleep(1000);\r
+ // we destroy all threads marked with auto delete:\r
+ m_mutexThreads.lock();\r
+ for (int ii = 0; ii < m_maxThreads; ii++) {\r
+ ReThread* current = m_threads[ii];\r
+ if (current != NULL && current->m_autoDelete) {\r
+ delete current;\r
+ m_threads[ii] = NULL;\r
+ }\r
+ }\r
+ m_mutexThreads.unlock();\r
+}\r
+\r
+/**\r
+ * Starts a thread with very few prerequisites.\r
+ *\r
+ * Note: this method is threadsafe.\r
+ *\r
+ * @param processor the instance doing the actual task\r
+ * @return <code>true</code>: successful\r
+ */\r
+bool ReThreadPool::startSimpleThread(ReProcessor& processor) {\r
+ // auto delete: the thread starter frees the instance\r
+ ReSimpleThread* thread = new ReSimpleThread(&processor);\r
+ bool rc = startThread(thread);\r
+ return rc;\r
}\r
\r
#if defined __linux__\r
*\r
* @param pConnection a void* pointer to the <code>ReThread</code> instance\r
* */\r
-static void* starterFunction(void *pConnection) {\r
+void* globalThreadStarterFunction(void *pConnection) {\r
ReThread* thread = reinterpret_cast<ReThread*>(pConnection);\r
- thread->run();\r
+ thread->runAndFinish();\r
+ return NULL;\r
}\r
#elif defined __WIN32__\r
-DWORD WINAPI starterFunction(_In_ LPVOID pParameter){\r
+DWORD WINAPI globalThreadStarterFunction(_In_ LPVOID pParameter) {\r
ReThread* thread = reinterpret_cast<ReThread*>(pConnection);\r
- thread->run();\r
+ thread->runAndFinish();\r
return 0;\r
}\r
\r
#endif\r
+\r
/**\r
* Starts a new thread.\r
*\r
+ * Note: this method is threadsafe.\r
+ *\r
* @param thread the\r
*/\r
-bool ReThreadStarter::startThread(ReThread& thread){\r
+bool ReThreadPool::startThread(ReThread* thread) {\r
bool ok = false;\r
- if (thread.prepareToRun(++m_nextId, m_logger, this)){\r
+ if (!insertThread(thread)) {\r
+ if (thread->m_autoDelete) {\r
+ delete thread;\r
+ }\r
+ } else {\r
+ if (thread->prepareToRun(++m_nextId, m_logger, this)) {\r
#if defined __linux__\r
- pthread_t sniffer_thread;\r
- ok = pthread_create(&sniffer_thread, NULL, starterFunction,\r
- reinterpret_cast<void*>(&thread)) >= 0;\r
+ ok = pthread_create(&thread->m_threadInfo, NULL,\r
+ globalThreadStarterFunction, reinterpret_cast<void*>(thread))\r
+ >= 0;\r
#elif defined __WIN32__\r
- HANDLE threadHandle;\r
- ok = (threadHandle = CreateThread(NULL, 0, starterFunction,\r
- &thread, 0)) != NULL;\r
+ HANDLE threadHandle;\r
+ ok = (threadHandle = CreateThread(NULL, 0, globalThreadStarterFunction,\r
+ &thread, 0)) != NULL;\r
#endif\r
- if (! ok)\r
- m_logger->sayF(LOG_ERROR | CAT_PROCESS,\r
- LC_START_THREAD_1,\r
- i18n("cannot create a thread: $1")).arg(\r
- getLastOSError()).end();\r
+ if (!ok)\r
+ m_logger->sayF(LOG_ERROR | CAT_PROCESS, LC_START_THREAD_1,\r
+ i18n("cannot create a thread: $1")).arg(getLastOSError())\r
+ .end();\r
+ }\r
}\r
return ok;\r
}\r
+\r
+/**\r
+ * Waits for the end of all threads.\r
+ *\r
+ * Note: this method is threadsafe.\r
+ *\r
+ * @param timeoutSec maximal time for waiting\r
+ * @return <code>true</code>: all threads are finished<br>\r
+ * <code>false</code>: timeout reached\r
+ */\r
+bool ReThreadPool::waitForAlmostAll(int mayResist, int timeoutSec) {\r
+ bool rc = false;\r
+ time_t start = time(NULL);\r
+ time_t now;\r
+ do {\r
+ int countWaiting = 0;\r
+ m_mutexThreads.lock();\r
+ for (int ii = 0; ii < m_maxThreads; ii++) {\r
+ ReThread* current = m_threads[ii];\r
+ if (current != NULL && !current->m_isStopped) {\r
+ countWaiting++;\r
+ }\r
+ }\r
+ m_mutexThreads.unlock();\r
+ if (countWaiting <= mayResist) {\r
+ rc = true;\r
+ break;\r
+ }\r
+ usleep(200 * 1000);\r
+ now = time(NULL);\r
+ } while (now < start + timeoutSec);\r
+ return rc;\r
+}\r
+/**\r
+ * Waits for the end of all threads.\r
+ *\r
+ * Note: this method is threadsafe.\r
+ *\r
+ * @param timeoutSec maximal time for waiting\r
+ * @return <code>true</code>: all threads are finished<br>\r
+ * <code>false</code>: timeout reached\r
+ */\r
+bool ReThreadPool::waitForDone(int timeoutSec) {\r
+ bool rc = waitForAlmostAll(0, timeoutSec);\r
+ return rc;\r
+}\r
#ifndef BASE_RETHREAD_HPP_\r
#define BASE_RETHREAD_HPP_\r
\r
-class ReThreadStarter;\r
+class ReThreadPool;\r
class ReSlaveAppender;\r
/**\r
* Abstract base class for threads\r
*\r
* Starting is done with a <code>ReThreadStarter</code>.\r
*/\r
-class ReThread {\r
+class ReThread: public ReLoggerOwner {\r
public:\r
ReThread(bool autoDelete);\r
virtual ~ReThread();\r
-private:\r
- friend class ReThreadStarter;\r
- bool prepareToRun(int id, ReLogger* masterLogger,\r
- ReThreadStarter* starter);\r
public:\r
+ /** Does the actual task.\r
+ * This method must do a <code>m_isStopped = true;</code> at the end!\r
+ */\r
virtual void run() = 0;\r
/** Returns if the thread is stopped.\r
* @return <code>true</code>the thread is stopped\r
*/\r
- inline bool isStopped() const{\r
+ inline bool isStopped() const {\r
return m_isStopped;\r
}\r
+ virtual ReLogger* logger();\r
/** Sets the wish for stopping the thread.\r
* @param value <code>true</code>: the thread should stop as soon as possible\r
*/\r
- inline bool setShouldStop(bool value){\r
+ inline void setShouldStop(bool value) {\r
m_shouldStop = value;\r
}\r
+private:\r
+private:\r
+ friend class ReThreadPool;\r
+ void kill();\r
+ bool prepareToRun(int id, ReLogger* masterLogger, ReThreadPool* starter);\r
+#if defined __linux__\r
+ friend void* globalThreadStarterFunction(void *pConnection);\r
+#elif defined __WIN32__\r
+ friend DWORD WINAPI globalThreadStarterFunction(_In_ LPVOID pParameter);\r
+#endif\r
+ void runAndFinish();\r
protected:\r
int m_threadId;\r
ReLogger m_threadLogger;\r
ReSlaveAppender* m_appender;\r
- ReThreadStarter* m_starter;\r
+ ReThreadPool* m_starter;\r
#if defined __linux__\r
pthread_t m_threadInfo;\r
#elif defined __WIN32__\r
bool m_autoDelete;\r
};\r
\r
+class ReSimpleThread: public ReThread {\r
+public:\r
+ ReSimpleThread(ReProcessor* processor);\r
+ virtual ~ReSimpleThread();\r
+public:\r
+ virtual void run();\r
+private:\r
+ ReProcessor* m_processor;\r
+};\r
/**\r
* Offers a portable way to start threads.\r
*/\r
-class ReThreadStarter {\r
+class ReThreadPool {\r
public:\r
- ReThreadStarter(int maxThreads, ReLogger* logger);\r
- virtual ~ReThreadStarter();\r
+ ReThreadPool(int maxThreads, ReLogger* logger);\r
+ virtual ~ReThreadPool();\r
public:\r
- bool startThread(ReThread& thread);\r
+ void killAllThreads();\r
+ bool startSimpleThread(ReProcessor& processor);\r
+ bool startThread(ReThread* thread);\r
+ bool waitForAlmostAll(int mayResist, int timeoutSec);\r
+ bool waitForDone(int timeoutSec);\r
private:\r
bool insertThread(ReThread* thread);\r
private:\r
ReLogger* m_logger;\r
int m_maxThreads;\r
ReThread** m_threads;\r
+ int m_maxKillTimeSec;\r
+ ReMutex m_mutexThreads;\r
};\r
#endif /* BASE_RETHREAD_HPP_ */\r
*/
ReVarArgs::ReVarArgs(void) :
m_argNo(0),
+ m_maxArgNo(0),
m_format(),
m_argBuffer(),
// m_args
*/
ReVarArgs::ReVarArgs(const char* format) :
m_argNo(0),
+ m_maxArgNo(0),
m_format(),
m_argBuffer(),
// m_args
m_trigger(NULL) {
reset(format);
}
+
+/**
+ * Destructor.
+ */
+ReVarArgs::~ReVarArgs() {
+}
/** @brief Resets the instance.
*
* Sets a new format and waits for the arguments.
/** This class will be used as callback method for <code>ReVarArgs</code>.
*/
class ReVarArgTrigger {
+public:
+ virtual ~ReVarArgTrigger() {
+ }
public:
/** @brief This method will be called when a new <code>ReVarArg::log()</code> call was done.
* The call was done after the insertion of the argument into the internal structures.
public:
ReVarArgs();
ReVarArgs(const char* format);
+ virtual ~ReVarArgs();
private:
void initialize(size_t size);
void replacePlaceholder();
* @param alignRight <code>true</code>: 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");
# include <fcntl.h>\r
#include <pthread.h>\r
#include <semaphore.h>\r
+#include <signal.h>\r
typedef u_int64_t uint64_t;\r
typedef u_int8_t uint8_t;\r
typedef __off_t ReFileSize_t;\r
}\r
#endif\r
\r
-#define RE_TESTUNIT\r
+typedef int ReErrNo_t;\r
+/**\r
+ * This base class allows to define classes with very common tasks.\r
+ *\r
+ * Example (a thread starter):\r
+ * the class realizing the task is a sub class of <code>ReProcessor</code>.\r
+ * The thread starter gets an instance of this task class and calls the\r
+ * method <code>process()</code> inside the new thread.\r
+ */\r
+class ReProcessor {\r
+public:\r
+ /** Destructor.\r
+ */\r
+ virtual ~ReProcessor() {\r
+ }\r
+public:\r
+ virtual void process() = 0;\r
+};\r
#include "base/ReMutex.hpp"\r
#include "base/ReByteBuffer.hpp"\r
#include "base/ReVarArgs.hpp"\r
#include "base/ReConfigFile.hpp"\r
#include "base/ReI18N.hpp"\r
#include "base/ReProgramArgs.hpp"\r
+#include "base/ReBaseUtils.hpp"\r
\r
-typedef unsigned char byte_t;\r
-typedef int ReErrNo_t;\r
-#include "../base/baselocations.hpp"\r
+#include "base/baselocations.hpp"\r
#endif /* REBASE_HPP_ */\r
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";
const int tenYear = (365 * 10 + 2) * 24 * 3600;\r
\r
const char* s_allFiles[] = { //\r
- " 1.txt", //\r
- "*dir1", //\r
- "*dir2", //\r
- "*dir1/cache", //\r
- "*dir1/dir1_1", //\r
- "*dir1/dir1_2", //\r
- "*dir1/dir1_2/dir1_2_1", //\r
- " dir1/dir1_2/dir1_2_1/x1.txt", //\r
- " dir1/dir1_2/dir1_2_1/x2.txt", //\r
- " dir2/2.x", //\r
- " dir1/cache/cache.txt", //\r
- NULL };\r
+ " 1.txt", //\r
+ "*dir1", //\r
+ "*dir2", //\r
+ "*dir1/cache", //\r
+ "*dir1/dir1_1", //\r
+ "*dir1/dir1_2", //\r
+ "*dir1/dir1_2/dir1_2_1", //\r
+ " dir1/dir1_2/dir1_2_1/x1.txt", //\r
+ " dir1/dir1_2/dir1_2_1/x2.txt", //\r
+ " dir2/2.x", //\r
+ " dir1/cache/cache.txt", //\r
+ NULL };\r
\r
class TestReDirTools: public ReTestUnit {\r
public:\r
testRandom();\r
}\r
}\r
- void testRandom(){\r
+ void testRandom() {\r
const char* argv[] = { "random", "-l20", "-s", "40", "50",\r
- NULL };\r
+ NULL };\r
ReDirRandom(m_logger).run(-1, argv);\r
}\r
void testDelete() {\r
const char* argv[] = { "delete", "-p;x*.txt", optOutput.str(), m_base\r
.str(), NULL };\r
const char* existing[] = { //\r
- " 1.txt", //\r
- "*dir1", //\r
- "*dir2", //\r
- "*dir1/cache", //\r
- "*dir1/dir1_1", //\r
- "*dir1/dir1_2", //\r
- "*dir1/dir1_2/dir1_2_1", //\r
- " dir2/2.x", //\r
- " dir1/cache/cache.txt", //\r
- NULL };\r
+ " 1.txt", //\r
+ "*dir1", //\r
+ "*dir2", //\r
+ "*dir1/cache", //\r
+ "*dir1/dir1_1", //\r
+ "*dir1/dir1_2", //\r
+ "*dir1/dir1_2/dir1_2_1", //\r
+ " dir2/2.x", //\r
+ " dir1/cache/cache.txt", //\r
+ NULL };\r
const char* notExisting[] = { //\r
- " dir1/dir1_2/dir1_2_1/x1.txt", //\r
- " dir1/dir1_2/dir1_2_1/x2.txt", //\r
- NULL };\r
+ " dir1/dir1_2/dir1_2_1/x1.txt", //\r
+ " dir1/dir1_2/dir1_2_1/x2.txt", //\r
+ NULL };\r
ReDirDelete(m_logger).run(-1, argv);\r
mustExist(existing);\r
mayNotExist(notExisting);\r
\r
- const char* argv2[] = { "delete", optOutput.str(), m_base\r
- .str(), NULL };\r
+ const char* argv2[] = { "delete", optOutput.str(), m_base.str(), NULL };\r
ReDirDelete(m_logger).run(-1, argv2);\r
mayNotExist(s_allFiles);\r
}\r
- void mustExist(const char** names){\r
+ void mustExist(const char** names) {\r
ReByteBuffer name;\r
struct stat info;\r
- for (int ix = 0; names[ix] != NULL; ix++){\r
+ for (int ix = 0; names[ix] != NULL; ix++) {\r
const char* arg = names[ix];\r
name = m_base;\r
name.ensureLastChar(OS_SEPARATOR_CHAR);\r
if (stat(name.str(), &info) != 0)\r
checkEqu("missing", name);\r
bool isDir = arg[0] == '*';\r
- if (isDir && ! S_ISDIR(info.st_mode))\r
+ if (isDir && !S_ISDIR(info.st_mode))\r
checkEqu("file not dir", name);\r
- if (! isDir && S_ISDIR(info.st_mode))\r
+ if (!isDir && S_ISDIR(info.st_mode))\r
checkEqu("dir not file", name);\r
}\r
}\r
- void mayNotExist(const char** names){\r
+ void mayNotExist(const char** names) {\r
ReByteBuffer name;\r
struct stat info;\r
- for (int ix = 0; names[ix] != NULL; ix++){\r
+ for (int ix = 0; names[ix] != NULL; ix++) {\r
const char* arg = names[ix];\r
name = m_base;\r
name.ensureLastChar(OS_SEPARATOR_CHAR);\r
}\r
}\r
void initTree() {\r
- for (int ix = 0; s_allFiles[ix] != 0; ix++){\r
+ for (int ix = 0; s_allFiles[ix] != 0; ix++) {\r
const char* name = s_allFiles[ix];\r
if (name[0] == '*')\r
makeDir(name + 1);\r
}
try {
throw ReFormatException("ReFormatException", "format", __FILE__,
- __LINE__);
+ __LINE__);
checkT(false);
} catch (ReException& e) {
log(false, e.getMessage());
testMemoryAppender();
testBase();
}
- void testBase(){
+ void testBase() {
ReStreamAppender app1(stdout);
app1.setMode(CAT_ALL, CAT_ALL, CAT_ALL, GRAN_ALL);
.end();
globalLogger()->say(CAT_LIB, __LINE__, "globalLogger()");
}
- void testMemoryAppender(){
+ void testMemoryAppender() {
ReLogger logger(false);
ReMemoryAppender appender(3);
logger.addAppender(&appender);
ReByteBuffer all;
checkEqu(3, appender.join(all).count("\n"));
}
- void testSlaveAppender(){
+ void testSlaveAppender() {
ReLogger masterLogger(false);
ReMemoryAppender memoryAppender(10);
masterLogger.addAppender(&memoryAppender);
"-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"));
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);
"--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"));
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);
#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);
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");
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);
void testOs() {
void testReDirTools();
testReDirTools();
- void testReTraverser();
- testReTraverser();
+ void testReTraverser();
+ testReTraverser();
if (s_testAll) {
void testReTraverser();
//testNet();
testBase();
}
- } catch (ReException e) {
+ } catch (ReException& e) {
fprintf(stderr, "testBase.cpp: unexpected exception: %s\n",
e.getMessage());
}
#include "base/rebase.hpp"\r
#include "math/remath.hpp"\r
\r
-const int ReMD5::m_s[RE_DIGEST_CHUNK_SIZE] = { \r
- 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12,\r
- 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16,\r
- 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15,\r
- 21, 6, 10, 15, 21, 6, 10, 15, 21 };\r
-static int s_ix = 0;\r
+const int ReMD5::m_s[RE_DIGEST_CHUNK_SIZE] = { 7, 12, 17, 22, 7, 12, 17, 22, 7,\r
+ 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9,\r
+ 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10,\r
+ 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 };\r
// for x in [1..64] : int(2**32 * sin(x))\r
-const uint32_t ReMD5::m_K[RE_DIGEST_CHUNK_SIZE] = { \r
- 0xd76aa478, 0xe8c7b756, 0x242070db,\r
- 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8,\r
- 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e,\r
- 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d,\r
- 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87,\r
- 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942,\r
- 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60,\r
- 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039,\r
- 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7,\r
- 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f,\r
- 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb,\r
- 0xeb86d391 };\r
+const uint32_t ReMD5::m_K[RE_DIGEST_CHUNK_SIZE] = { 0xd76aa478, 0xe8c7b756,\r
+ 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,\r
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193,\r
+ 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,\r
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6,\r
+ 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,\r
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9,\r
+ 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,\r
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97,\r
+ 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,\r
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235,\r
+ 0x2ad7d2bb, 0xeb86d391 };\r
\r
/**\r
* Constructor.\r
* @param chunkSize the length of one full input block\r
*/\r
ReDigest::ReDigest(uint8_t* digest, size_t digestSize, uint8_t* waiting,\r
- size_t chunkSize) :\r
+ size_t chunkSize) :\r
m_digest(digest),\r
m_digestSize(digestSize),\r
// m_waitingBuffer[RE_DIGEST_CHUNK_SIZE];\r
/**\r
* Destructor.\r
*/\r
-ReDigest::~ReDigest(){\r
+ReDigest::~ReDigest() {\r
}\r
/**\r
* Returns the binary digest value.\r
*\r
* @param salt the salt to set\r
*/\r
-void ReDigest::setSalt(uint64_t salt){\r
+void ReDigest::setSalt(uint64_t salt) {\r
m_salt = salt;\r
}\r
/**\r
inline void rotate_left_and_add(uint32_t& rc, uint32_t data, int shift, uint32_t term) {\r
rc = ((data << shift) | (data >> (32-shift))) + term;\r
}\r
+//#define TRACE_MD5\r
+#if defined TRACE_MD5\r
+static int s_ix = 0;\r
+#endif\r
inline void X1(uint32_t &var, uint32_t x, uint32_t y, uint32_t z,\r
uint32_t data, uint32_t aConst, uint32_t shift) {\r
-//#define TRACE_MD5\r
#if defined TRACE_MD5\r
printf("%2d: A: %08x B: %08x C: %08x D%08x\n", s_ix++ % 16, var, x, y, z);\r
printf(" K[%2d]: %08x M[?]: %08x shift: %02d\n",\r
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();
*/
inline void update(const ReByteBuffer& block) {
update(reinterpret_cast<const uint8_t*>(block.str()),
- (int) block.length());
+ (int) block.length());
}
virtual void processChunk(const uint8_t* block) = 0;
virtual void reset() = 0;
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;
*
* The algorithm is described in http://en.wikipedia.org/wiki/MD5.
*/
-class ReMD5 : public ReDigest {
+class ReMD5: public ReDigest {
public:
ReMD5();
virtual ~ReMD5();
* Constructor.\r
*/\r
ReRPD64::ReRPD64() :\r
- ReDigest(m_digest, sizeof m_digest),\r
+ ReDigest(m_digest, sizeof m_digest),\r
//m_digest\r
m_a0(0),\r
m_b0(0),\r
*
* 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();
}
#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.
+ (-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
*
* @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);
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;
* @param logger logger for the error handling
*/
ReTCPClient::ReTCPClient(ReLogger* logger) :
- ReTCPConnection(-1, logger) {
+ ReTCPConnection(-1, this),
+ m_logger(logger) {
}
/**
* Destructor.
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){\r
- m_logger->sayF(LOG_ERROR | CAT_NETWORK, LC_TCP_CONNECTION_1,
- i18n("WSAStartup() failed: $1")).arg(errno).arg(getLastOSError()).end();\r
- throw ReException("WSAStartup() failed");\r
- }\r
+ 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
}
/**
* Frees the global resources.
*/
-void ReTCPConnection::globalClose(){
+void ReTCPConnection::globalClose() {
#if defined __WIN32__
WSACleanup();
#endif
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 {
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);
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) {
* @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;
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;
}
* @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) {
}
/**
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();
}
*/
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);
}
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);
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<const char*>(&yes),
- sizeof(int)) == -1) {
+ if (setsockopt(m_handleSocket, SOL_SOCKET, SO_REUSEADDR,
+ reinterpret_cast<const char*>(&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!
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(
return rc;
}
+/**
+ * Returns the logger.
+ *
+ * @param the logger for error handling
+ */
+ReLogger* ReTCPServer::logger() {
+ return m_logger;
+}
+
/**
* Constructor.
*/
* 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);
}
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);
+}
*/
class ReSocketAddress {
public:
- ReSocketAddress(ReLogger* logger);
+ ReSocketAddress(ReLoggerOwner* loggerOwner);
virtual ~ReSocketAddress();
public:
/**
//@ 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;
};
*/
class ReTCPConnection: public ReSocketAddress {
public:
- ReTCPConnection(int id, ReLogger* logger);
+ ReTCPConnection(int id, ReLoggerOwner* loggerOwner);
virtual ~ReTCPConnection();
public:
void close();
ReByteBuffer m_peerName;
ReByteBuffer m_received;
ReByteBuffer m_toSend;
- ReLogger* m_logger;
int m_handleSocket;
int m_id;
uint32_t m_noSent;
/**
* 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;
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;
};
/**
ReNetCommandHandler();
/** Destructor.
*/
- virtual ~ReNetCommandHandler(){
+ virtual ~ReNetCommandHandler() {
}
public:
void addHandler(ReNetCommandHandler* handler);
* 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<br>
+ * "localtim": returns the local time<br>
+ * "strlen": returns the length of the sent data (for upload bandwith meas.)<br>
+ * "filldata": returns data of a requested length (for download bandwith m.)<br>
+ * "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_ */
* 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.
*
* 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);
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();
}
* 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;
}
}
* @param logger Logger.
*/
ReUdpServer::ReUdpServer(ReLogger* logger) :
- ReUdpConnection(true, logger)
-{
+ ReUdpConnection(true, logger) {
}
/** @brief Destructor.
* @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;
* @param logger Logger.
*/
ReUdpClient::ReUdpClient(ReLogger* logger) :
- ReUdpConnection(false, logger){
+ ReUdpConnection(false, logger) {
}
/** @brief Destructor.
*
* @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;
}
* @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.
*
* @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());
}
}
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();
* 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();
* 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();
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();
bool connect(const char* ip, int port);
};
-
#endif /* UDPSERVER_H_ */
"delete delete the selected files",\r
"help shows info about the arguments/options",\r
"list shows the meta data of the selected files",\r
- "random displays random numbers",\r
+ "random displays random numbers",\r
"statistic shows statistics about a direcctory tree",\r
"synchronize copies only modified or new files from",\r
" from a source directory tre to a target",\r
"dirtool li --type=f -y7d --size=10M -p;*.cpp;*.hpp;Makefile*;-*~ /home/data",\r
NULL };\r
\r
-const char* s_checksumUsage[] = {\r
- "<command>: c(hecksum) [<opts>] <dir_or_file1> [<dir_or_file2> ...]",\r
- " shows a check sum of the given files or manages a checksum storage file in each directory for observing",\r
- NULL };\r
+const char* s_checksumUsage[] =\r
+ { "<command>: c(hecksum) [<opts>] <dir_or_file1> [<dir_or_file2> ...]",\r
+ " shows a check sum of the given files or manages a checksum storage file in each directory for observing",\r
+ NULL };\r
const char* s_checksumExamples[] = { "dirtool ch --buffer-size=512 e:\\data",\r
"dirtool check -cList -p;*.iso /home/iso /down/debian.iso",\r
"dirtool checksum -cBuild -aMD5 /home",\r
"dirtool checksum --command=Compare /home",\r
"dirtool checksum -cUpdate -O/var/log/checksum.log /home",\r
NULL };\r
-const char* s_randomUsage[] = {\r
- "<command>: r(andom) <opts> count until [from]",\r
- " displays random numbers.",\r
- " <count> count of generated numbers",\r
- " <until> the maximum (including) value of the numbers",\r
- " <from> the minimum (including) value of the numbers. Default: 1",\r
- NULL };\r
+const char* s_randomUsage[] = { "<command>: r(andom) <opts> count until [from]",\r
+ " displays random numbers.", " <count> count of generated numbers",\r
+ " <until> the maximum (including) value of the numbers",\r
+ " <from> the minimum (including) value of the numbers. Default: 1",\r
+ NULL };\r
const char* s_randomExamples[] = { "dirtool ra --multiple -w3 10 33",\r
- "dirtool rand -s 6 49",\r
- "dirtool rand --sort --width=1 5 50",\r
- "dirtool rand --sort --width=1 2 10",\r
- NULL };\r
+ "dirtool rand -s 6 49", "dirtool rand --sort --width=1 5 50",\r
+ "dirtool rand --sort --width=1 2 10",\r
+ NULL };\r
\r
static const char* s_statisticUsage[] =\r
{ "<command>: st(atistic) [<opts>] <path1> [<path2> ...] [<depth>]",\r
"dirtool sync --type=r --max-size=1G usr etc /media/backup",\r
NULL };\r
\r
-const char* s_tcpUsage[] =\r
- { "<command>: tcp [<opts>] <subcommand> [<param> ...]",\r
- " test tool for network test",\r
- "<subcommand>:",\r
- " server",\r
- " client <ip> [<rounds> [<print_interval>]]",\r
- " <ip>: URL of the server",\r
- " <rounds>: number of messages to send",\r
- NULL };\r
-const char* s_tcpExamples[] = {\r
- "dirtool tcp -p 5555 server",\r
+const char* s_tcpUsage[] = {\r
+ "<command>: tcp [<opts>] <subcommand> [<param> ...]",\r
+ " test tool for network test", "<subcommand>:", " server",\r
+ " client <ip> [<rounds> [<print_interval>]]",\r
+ " <ip>: URL of the server", " <rounds>: number of messages to send",\r
+ NULL };\r
+const char* s_tcpExamples[] = { "dirtool tcp -p 5555 server",\r
"dirtool tcp -p 5555 client localhost 10000 10",\r
"dirtool tcp -p 5555 --buffer-size=1024 client 192.168.7.3 10 25",\r
NULL };\r
\r
-\r
const char* s_touchUsage[] =\r
{ "<command>: touch [<opts>] <dir_or_file1> [<dir_or_file2> ...]",\r
" sets the filetimes (modification and/or access time) of the selected files",\r
*/\r
void ReTool::run(int argc, const char** argv) {\r
try {\r
- if (argc < 0){\r
- for (argc = 0; argv[argc] != NULL; argc++){\r
+ if (argc < 0) {\r
+ for (argc = 0; argv[argc] != NULL; argc++) {\r
// nothing to do\r
}\r
}\r
m_programArgs.init(argc, argv);\r
- if (m_programArgs.getArgCount() < m_minArguments)\r
+ if (m_programArgs.argCount() < m_minArguments)\r
m_programArgs.help(i18n("too few arguments"), false, stdout);\r
if (m_hasStandardArgs)\r
setFilterFromProgramArgs(m_filter);\r
*\r
*/\r
void ReTool::processFileArguments() {\r
- int max = m_programArgs.getArgCount() - m_reservedLast;\r
+ int max = m_programArgs.argCount() - m_reservedLast;\r
// Test whether the arguments are files or directories:\r
ReByteBuffer arg;\r
for (int ii = m_reservedFirst; ii < max; ii++) {\r
- arg = m_programArgs.getArg(ii);\r
+ arg = m_programArgs.arg(ii);\r
if (!exists(arg) != 0)\r
m_programArgs.help(\r
ReByteBuffer(i18n("not a file or a directory: ")).append(arg)\r
}\r
// process the files:\r
for (int ii = m_reservedFirst; ii < max; ii++) {\r
- const char* arg = m_programArgs.getArg(ii);\r
+ const char* arg = m_programArgs.arg(ii);\r
if (S_ISDIR(m_statInfo.st_mode))\r
processTree(arg);\r
else\r
*/\r
ReDirStatistic::ReDirStatistic(ReLogger* logger, int deltaList, int deltaBuffer) :\r
ReTool(s_statisticUsage, s_statisticExamples, 2, 0, 1, false, logger),\r
- m_list(deltaList, deltaBuffer) {\r
+ m_list(deltaList, deltaBuffer),\r
+ m_traceInterval(60),\r
+ m_lastTrace(0) {\r
// standard short options: D d O o P p T t v y Z z\r
m_programArgs.addBool("kbyte",\r
i18n("output format is '<kbyte> <path>' (like unix 'du' command)"), 'k',\r
m_isExe(false) {\r
// standard short options: D d O o P p T t v y Z z\r
m_programArgs.addString("first",\r
- i18n("defines the first line of the output"),\r
- '1', "first-line", true,\r
+ i18n("defines the first line of the output"), '1', "first-line", true,\r
#if defined __linux__\r
- "#! /bin/sh"\r
+ "#! /bin/sh"\r
#elif defined __WIN32__\r
- "rem this batch is created by dirtool"\r
+ "rem this batch is created by dirtool"\r
#endif\r
- );\r
+) ;\r
m_programArgs.addString("arguments", i18n("template for the output line.\n"\r
- "Possible placeholders: (e.g. e:\\data\\sample.txt)\n"\r
- " !full!: e:\\data\\sample.txt\n"\r
- " !path!: e:\\data\\\n"\r
- " !basename!: sample.txt\n"\r
- " !name!: sample\n"\r
- " !ext!: .txt\n"\r
- "example: --arguments='echo !basename! in !path! found'"), 'a',\r
- "arguments", false, NULL);\r
+ "Possible placeholders: (e.g. e:\\data\\sample.txt)\n"\r
+ " !full!: e:\\data\\sample.txt\n"\r
+ " !path!: e:\\data\\\n"\r
+ " !basename!: sample.txt\n"\r
+ " !name!: sample\n"\r
+ " !ext!: .txt\n"\r
+ "example: --arguments='echo !basename! in !path! found'"), 'a',\r
+ "arguments", false, NULL);\r
m_programArgs.addString("script",\r
- i18n("name of the script (starts each output line)"), 'c', "script",\r
- false, NULL);\r
+ i18n("name of the script (starts each output line)"), 'c', "script",\r
+ false, NULL);\r
#if defined __WIN32__\r
m_programArgs.addBool("isexe",\r
i18n("supresses the starting 'call' of each output line"\r
#elif defined __WIN32__\r
static const char* prefix = "rem ";\r
#endif\r
- printSummary (prefix);\r
+ printSummary(prefix);\r
}\r
\r
/**\r
m_digest(NULL),\r
m_buffer() {\r
// standard short options: D d O o P p T t v y Z z\r
- m_programArgs.addString("algorithm",\r
- i18n("algorithm: 'MD5' or 'RPD64'"), 'a', "--algorithm", false, "MD5");\r
+ m_programArgs.addString("algorithm", i18n("algorithm: 'MD5' or 'RPD64'"),\r
+ 'a', "--algorithm", false, "MD5");\r
m_programArgs.addInt("buffersize",\r
i18n("buffer size for file reading (in KiByte)"), 'b', "--buffer-size",\r
4 * 1024);\r
m_programArgs.addString("command",\r
- i18n("'build': builds in each directory a file '.dt.chksum' with sum and name\n"\r
- "'compare': shows differences between the content of '.dt.chksum' and the current files\n"\r
- "'list': shows checksum and filename\n"\r
- "'update': like compare, but update the content of '.dt.chksum'"),\r
- 'c', "--command", false, "list");\r
- m_programArgs.addInt("salt",\r
- i18n("a number which change the checksum"), 's', "--salt", 0);\r
+ i18n(\r
+ "'build': builds in each directory a file '.dt.chksum' with sum and name\n"\r
+ "'compare': shows differences between the content of '.dt.chksum' and the current files\n"\r
+ "'list': shows checksum and filename\n"\r
+ "'update': like compare, but update the content of '.dt.chksum'"),\r
+ 'c', "--command", false, "list");\r
+ m_programArgs.addInt("salt", i18n("a number which change the checksum"),\r
+ 's', "--salt", 0);\r
addStandardFilterOptions();\r
}\r
\r
/**\r
* Destructor.\r
*/\r
-ReDirChecksum::~ReDirChecksum(){\r
+ReDirChecksum::~ReDirChecksum() {\r
delete m_digest;\r
m_digest = NULL;\r
}\r
*\r
* @param path the directory to process\r
*/\r
-void ReDirChecksum::buildStorage(const char* path, const char* storageFile){\r
+void ReDirChecksum::buildStorage(const char* path, const char* storageFile) {\r
ReTraverser traverser(path);\r
traverser.setMaxLevel(0);\r
ReDirStatus_t* entry;\r
digest2.setSalt(0x2004199111121989ll);\r
ReByteBuffer line;\r
FILE* fp = fopen(storageFile, "w");\r
- if (fp == NULL){\r
+ if (fp == NULL) {\r
m_logger->sayF(LOG_ERROR | CAT_FILE, LC_BUILD_DIRECTORY_1,\r
i18n("cannot open file: $1 (errno: $2)")).arg(storageFile).arg(\r
- errno).end();\r
+ errno).end();\r
\r
} else {\r
int level;\r
while ((entry = traverser.nextFile(level, &m_filter)) != NULL) {\r
line.setLength(0);\r
- if (!entry->isDirectory()){\r
+ if (!entry->isDirectory()) {\r
calculateChecksum(entry->fullName(), *m_digest, m_buffer,\r
- m_logger);\r
+ m_logger);\r
line.append(m_digest->hexDigest());\r
}\r
line.appendChar('\t').append(entry->node());\r
fprintf(fp, "%s\n", line.str());\r
if (m_verboseLevel >= V_NORMAL)\r
fprintf(m_output, "%16s\t%s",\r
- entry->isDirectory() ? "" : m_digest->hexDigest().str(),\r
- entry->fullName());\r
+ entry->isDirectory() ? "" : m_digest->hexDigest().str(),\r
+ entry->fullName());\r
}\r
fprintf(fp, "%s\n", digest2.hexDigest().str());\r
fclose(fp);\r
* @param storageFile the file with the checksums\r
*/\r
void ReDirChecksum::compareDir(const char* path, ReStringList& names,\r
- const char* storageFile){\r
+ const char* storageFile) {\r
// forget the last line (checksum):\r
int count = names.count() - 1;\r
names.remove(count);\r
- for (int ii = 0; ii < count; ii++){\r
+ for (int ii = 0; ii < count; ii++) {\r
const char* name = names.strOf(ii);\r
const char* ptr = strchr(name, '\t');\r
if (ptr != NULL)\r
ReSeqArray::Index index;\r
const char* node = entry->node();\r
// the stringlist stores the string with trailing '\0'\r
- if (! names.binarySearch(node, strlen(node) + 1, index)){\r
+ if (!names.binarySearch(node, strlen(node) + 1, index)) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_DIR_1,\r
- i18n("missing file $1 in storage $2")).arg(entry->fullName())\r
- .arg(storageFile).end();\r
+ i18n("missing file $1 in storage $2")).arg(entry->fullName())\r
+ .arg(storageFile).end();\r
}\r
}\r
}\r
* @param path the directory\r
* @param storageFile the file with the checksums\r
*/\r
-void ReDirChecksum::compareStorage(const char* path, const char* storageFile){\r
+void ReDirChecksum::compareStorage(const char* path, const char* storageFile) {\r
ReStringList storage;\r
storage.readFromFile(storageFile);\r
- if (storage.count() <= 0){\r
+ if (storage.count() <= 0) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_STORAGE_1,\r
- i18n("empty storage file: $1")).arg(storageFile).end();\r
- } else if (! isValid(storage)){\r
+ i18n("empty storage file: $1")).arg(storageFile).end();\r
+ } else if (!isValid(storage)) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_STORAGE_2,\r
- i18n("corrupted storage file: $1")).arg(storageFile).end();\r
+ i18n("corrupted storage file: $1")).arg(storageFile).end();\r
} else {\r
ReStringList cols;\r
ReByteBuffer fullname(path);\r
int pathLength = fullname.length();\r
struct stat info;\r
// test all files of the storage:\r
- for (size_t ii = 0; ii < storage.count() - 1; ii++){\r
+ for (size_t ii = 0; ii < storage.count() - 1; ii++) {\r
cols.split(storage.strOf(ii), '\t');\r
int colCount = cols.count();\r
- if (colCount != 2){\r
+ if (colCount != 2) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY, LC_COMPARE_STORAGE_3,\r
- i18n("wrong format ($1) in storage file $2-$3"))\r
- .arg(colCount).arg(storageFile).arg(ii+1).end();\r
+ i18n("wrong format ($1) in storage file $2-$3")).arg(\r
+ colCount).arg(storageFile).arg(ii + 1).end();\r
break;\r
} else {\r
fullname.setLength(pathLength).append(cols.strOf(1));\r
- if (cols.strLengthOf(0) == 0){\r
+ if (cols.strLengthOf(0) == 0) {\r
// a directory:\r
- if (stat(fullname.str(), &info) != 0){\r
+ if (stat(fullname.str(), &info) != 0) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY,\r
- LC_COMPARE_STORAGE_4,\r
- i18n("missing directory $1 ($2-$3)"))\r
- .arg(fullname).arg(storageFile).arg(ii+1).end();\r
- } else if (! S_ISDIR(info.st_mode)){\r
+ LC_COMPARE_STORAGE_4,\r
+ i18n("missing directory $1 ($2-$3)")).arg(fullname)\r
+ .arg(storageFile).arg(ii + 1).end();\r
+ } else if (!S_ISDIR(info.st_mode)) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY,\r
- LC_COMPARE_STORAGE_5,\r
- i18n("directory is now a file: $1 ($2-$3)"))\r
- .arg(fullname).arg(storageFile).arg(ii+1).end();\r
+ LC_COMPARE_STORAGE_5,\r
+ i18n("directory is now a file: $1 ($2-$3)")).arg(\r
+ fullname).arg(storageFile).arg(ii + 1).end();\r
}\r
} else {\r
// a directory:\r
- if (stat(fullname.str(), &info) != 0){\r
+ if (stat(fullname.str(), &info) != 0) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY,\r
- LC_COMPARE_STORAGE_6,\r
- i18n("missing file $1 ($2-$3)"))\r
- .arg(fullname).arg(storageFile).arg(ii+1).end();\r
- } else if (S_ISDIR(info.st_mode)){\r
+ LC_COMPARE_STORAGE_6,\r
+ i18n("missing file $1 ($2-$3)")).arg(fullname).arg(\r
+ storageFile).arg(ii + 1).end();\r
+ } else if (S_ISDIR(info.st_mode)) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY,\r
- LC_COMPARE_STORAGE_7,\r
- i18n("file is now a directory: $1 ($2-$3)"))\r
- .arg(fullname).arg(storageFile).arg(ii+1).end();\r
+ LC_COMPARE_STORAGE_7,\r
+ i18n("file is now a directory: $1 ($2-$3)")).arg(\r
+ fullname).arg(storageFile).arg(ii + 1).end();\r
} else {\r
calculateChecksum(fullname.str(), *m_digest, m_buffer,\r
- m_logger);\r
- if (! m_digest->hexDigest().equals(cols.strOf(0))){\r
+ m_logger);\r
+ if (!m_digest->hexDigest().equals(cols.strOf(0))) {\r
m_logger->sayF(LOG_ERROR | CAT_SECURITY,\r
- LC_COMPARE_STORAGE_7,\r
- i18n("checksum different: $1 ($2-$3)"))\r
- .arg(fullname).arg(storageFile).arg(ii+1).end();\r
+ LC_COMPARE_STORAGE_7,\r
+ i18n("checksum different: $1 ($2-$3)")).arg(\r
+ fullname).arg(storageFile).arg(ii + 1).end();\r
}\r
}\r
}\r
*\r
* @param storage the storage file as string list.\r
*/\r
-bool ReDirChecksum::isValid(const ReStringList& storage){\r
+bool ReDirChecksum::isValid(const ReStringList& storage) {\r
int count = storage.count();\r
ReRPD64 digest2;\r
digest2.setSalt(0x2004199111121989ll);\r
\r
- for (int ii = 0; ii < count - 1; ii++){\r
+ for (int ii = 0; ii < count - 1; ii++) {\r
const char* line = storage.strOf(ii);\r
digest2.update(line);\r
}\r
bool rc = true;\r
const char* hex = storage.strOf(count - 1);\r
- if (! digest2.hexDigest().equals(hex))\r
+ if (!digest2.hexDigest().equals(hex))\r
rc = false;\r
return rc;\r
}\r
m_command = CMD_UPDATE;\r
else\r
help(i18n("unknown command (expected: build compare list update): "),\r
- value.str());\r
+ value.str());\r
\r
m_programArgs.getString("algorithm", value);\r
if (value.equals("md5", -1, true))\r
else if (value.equals("rpd64", -1, true))\r
m_digest = new ReRPD64();\r
else\r
- help(i18n("unknown algorithm (expected: MD5 RPD64): "),\r
- value.str());\r
+ help(i18n("unknown algorithm (expected: MD5 RPD64): "), value.str());\r
int salt = m_programArgs.getInt("salt");\r
if (salt != 0)\r
m_digest->setSalt(salt);\r
storageFile.ensureLastChar(OS_SEPARATOR_CHAR);\r
storageFile.append(".dt.chksum");\r
}\r
- switch(m_command){\r
+ switch (m_command) {\r
case CMD_BUILD:\r
buildStorage(entry->fullName(), storageFile.str());\r
break;\r
*/\r
void ReDirChecksum::processFile(ReDirStatus_t* entry) {\r
const char* name = entry->fullName();\r
- switch(m_command){\r
+ switch (m_command) {\r
case CMD_LIST:\r
calculateChecksum(name, *m_digest, m_buffer, m_logger);\r
fprintf(m_output, "%s %s\n", m_digest->hexDigest().str(), name);\r
* @param path the directory\r
* @param storageFile the file with the checksums\r
*/\r
-void ReDirChecksum::updateStorage(const char* path, const char* storageFile){\r
+void ReDirChecksum::updateStorage(const char* path, const char* storageFile) {\r
\r
}\r
\r
* @param logger logger for error processing\r
* @return <code>digest</code> (for chaining)\r
*/\r
-ReDigest& ReDirChecksum::calculateChecksum(const char* name,\r
- ReDigest& digest, ReByteBuffer& buffer, ReLogger* logger){\r
+ReDigest& ReDirChecksum::calculateChecksum(const char* name, ReDigest& digest,\r
+ ReByteBuffer& buffer, ReLogger* logger) {\r
FILE* fp = fopen(name, "rb");\r
if (fp == NULL) {\r
if (logger != NULL)\r
logger->sayF(LOG_ERROR | CAT_FILE, LC_CALCULATE_CHECKSUM_1,\r
i18n("cannot open file: $1 (errno: $2)")).arg(name).arg(\r
- errno).end();\r
+ errno).end();\r
} else {\r
ReMD5 digest;\r
size_t readBytes;\r
*/\r
void ReDirDelete::processFile(ReDirStatus_t* entry) {\r
const char* name = entry->fullName();\r
- if (m_verboseLevel >= V_NORMAL){\r
+ if (m_verboseLevel >= V_NORMAL) {\r
fprintf(m_output, "%s\n", name);\r
}\r
if (_unlink(name) != 0)\r
m_logger->sayF(LOG_ERROR | CAT_FILE, LC_DELETE_1,\r
- i18n("cannot delete ($1): $2")).arg(errno).arg(name).end();\r
+ i18n("cannot delete ($1): $2")).arg(errno).arg(name).end();\r
}\r
\r
/**\r
ReDirRandom::ReDirRandom(ReLogger* logger) :\r
ReTool(s_randomUsage, s_randomExamples, 2, 0, 0, true, logger) {\r
m_hasStandardArgs = false;\r
- m_programArgs.addBool("multiple", i18n("result can contain a value multiple times"),\r
- 'm', "--multiple", false);\r
- m_programArgs.addInt("perline", i18n("number of values per line"),\r
- 'l', "--values-per-line", 10);\r
- m_programArgs.addBool("sort", i18n("the result is sorted"),\r
- 's', "--sort", false);\r
- m_programArgs.addInt("width", i18n("output format: minimum width of the numbers"\r
- " 0: width of the maximum"),\r
- 'w', "--min-width", 0);\r
+ m_programArgs.addBool("multiple",\r
+ i18n("result can contain a value multiple times"), 'm', "--multiple",\r
+ false);\r
+ m_programArgs.addInt("perline", i18n("number of values per line"), 'l',\r
+ "--values-per-line", 10);\r
+ m_programArgs.addBool("sort", i18n("the result is sorted"), 's', "--sort",\r
+ false);\r
+ m_programArgs.addInt("width",\r
+ i18n("output format: minimum width of the numbers"\r
+ " 0: width of the maximum"), 'w', "--min-width", 0);\r
}\r
\r
/**\r
void ReDirRandom::doIt() {\r
bool multiple = m_programArgs.getBool("multiple");\r
bool sort = m_programArgs.getBool("sort");\r
- int count = atol(m_programArgs.getArg(0));\r
- int to = atol(m_programArgs.getArg(1));\r
+ int count = atol(m_programArgs.arg(0));\r
+ int to = atol(m_programArgs.arg(1));\r
int from = 1;\r
- if (m_programArgs.getArgCount() > 2)\r
- from = atol(m_programArgs.getArg(2));\r
+ if (m_programArgs.argCount() > 2)\r
+ from = atol(m_programArgs.arg(2));\r
ReShiftRandom rand;\r
rand.setSeed(rand.nearTrueRandom());\r
for (int ii = rand.nextInt(100); ii > 0; ii--)\r
int found = 0;\r
ReSeqArray values(count);\r
ReByteBuffer value;\r
- if (! multiple && count >= to - from + 1)\r
- help(i18n("not realy random: all possible values requested. Do you mean '--multiple'?"));\r
- while(found < count){\r
- value.setLength(0).appendInt(from + rand.nextInt((to - from + 1) * factor) / factor, "%010d");\r
+ if (!multiple && count >= to - from + 1)\r
+ help(\r
+ i18n(\r
+ "not realy random: all possible values requested. Do you mean '--multiple'?"));\r
+ while (found < count) {\r
+ value.setLength(0).appendInt(\r
+ from + rand.nextInt((to - from + 1) * factor) / factor, "%010d");\r
int ix = (int) values.find(value.str());\r
- if (! multiple && ix != -1)\r
+ if (!multiple && ix != -1)\r
continue;\r
found++;\r
values.add(-1, value.str());\r
}\r
if (sort)\r
values.sort();\r
- for (int ii = 0; ii < count; ii++){\r
+ for (int ii = 0; ii < count; ii++) {\r
values.get(ii, value);\r
int val = atol(value.str());\r
printf(format.str(), val,\r
- ii % numbersPerLine == numbersPerLine - 1 ? "\n" : " ");\r
+ ii % numbersPerLine == numbersPerLine - 1 ? "\n" : " ");\r
}\r
if (count % numbersPerLine != 0)\r
printf("\n");\r
}\r
\r
-\r
/**\r
* Calculates the statistic of a directory tree.\r
*\r
*/\r
void ReDirStatistic::doIt() {\r
int depth = 1;\r
- if (m_programArgs.getArgCount() > 1) {\r
- const char* arg1 = m_programArgs.getArg(1);\r
+ if (m_programArgs.argCount() > 1) {\r
+ const char* arg1 = m_programArgs.arg(1);\r
if (ReStringUtils::lengthOfUnsigned(arg1, -1, (unsigned *) &depth) == 0)\r
m_programArgs.help("depth is not an integer", false, stdout);\r
}\r
ReByteBuffer& line) = &formatWithSizeFilesAndDirs;\r
if (m_programArgs.getBool("kbyte"))\r
proc = &formatLikeDu;\r
- const ReStringList& list = calculate(m_programArgs.getArg(0), depth, proc);\r
+ const ReStringList& list = calculate(m_programArgs.arg(0), depth, proc);\r
ReByteBuffer buffer;\r
for (size_t ix = 0; ix < list.count(); ix++) {\r
buffer.set(list.strOf(ix), list.strLengthOf(ix));\r
\r
static bool isAbsoluteTime(ReFileTime_t& time) {\r
#if defined __linux__\r
- static struct tm year1980 = {0, 0, 0, 1, 1 - 1, 1980-1900};\r
+ static struct tm year1980 = { 0, 0, 0, 1, 1 - 1, 1980 - 1900 };\r
static time_t time1980 = mktime(&year1980);\r
return time.tv_sec >= time1980;\r
#elif defined __WIN32__\r
static void addRelativeTime(ReFileTime_t& absTime,\r
const ReFileTime_t& relTime) {\r
#if defined __linux__\r
- if ( (absTime.tv_nsec += relTime.tv_nsec) >= 1000*1000*1000) {\r
- absTime.tv_nsec -= 1000*1000*1000;\r
+ if ((absTime.tv_nsec += relTime.tv_nsec) >= 1000 * 1000 * 1000) {\r
+ absTime.tv_nsec -= 1000 * 1000 * 1000;\r
absTime.tv_sec += 1;\r
}\r
absTime.tv_sec += relTime.tv_sec;\r
filetimeIsUndefined(m_modified) ? &m_accessed : &m_modified,\r
bufferTime);\r
fprintf(m_output, "%s -> %s %s\n",\r
- ReDirStatus_t::filetimeToString(entry->modified(),\r
- bufferTime2),\r
- bufferTime.str(), (char*) name);\r
+ ReDirStatus_t::filetimeToString(entry->modified(),\r
+ bufferTime2), bufferTime.str(), (char*) name);\r
}\r
}\r
}\r
if (rc != 0 && logger != NULL)\r
logger->sayF(LOG_ERROR | CAT_FILE, LC_TOUCH_1,\r
i18n("cannot change filetime: $1 (errno: $2)")).arg(filename).arg(\r
- errno).end();\r
+ errno).end();\r
return rc;\r
}\r
\r
struct stat info;\r
if (properties == NULL) {\r
if (stat(source, &info) == 0)\r
- properties = &info;\r
+ properties = &info;\r
else {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1,\r
- i18n("could not find: $1 (errno: $2)")).arg(source)\r
- .arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_1,\r
+ i18n("could not find: $1 (errno: $2)")).arg(source).arg(\r
+ errno).end();\r
}\r
}\r
FILE* fpSource = fopen(source, "rb");\r
if (fpSource == NULL) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2,\r
- i18n("cannot open $1 (errno: $2)"))\r
- .arg(source).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_2,\r
+ i18n("cannot open $1 (errno: $2)")).arg(source).arg(errno).end();\r
} else {\r
- ReFileSize_t size = properties == NULL ? 0x7fffffff : properties->st_size;\r
+ ReFileSize_t size =\r
+ properties == NULL ? 0x7fffffff : properties->st_size;\r
FILE* fpTarget = fopen(target, "w");\r
if (fpTarget == NULL) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3,\r
- i18n("cannot open $1 (errno: $2)"))\r
- .arg(target).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_3,\r
+ i18n("cannot open $1 (errno: $2)")).arg(target).arg(errno)\r
+ .end();\r
} else {\r
- while(size > 0) {\r
+ while (size > 0) {\r
size_t blockSize = buffer.capacity();\r
if ((int) blockSize > size)\r
- blockSize = size;\r
+ blockSize = size;\r
if (fread(buffer.buffer(), blockSize, 1, fpSource) != 1) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5,\r
- i18n("cannot read $1 (errno: $2)"))\r
- .arg(source).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_5,\r
+ i18n("cannot read $1 (errno: $2)")).arg(source).arg(\r
+ errno).end();\r
break;\r
}\r
size_t written;\r
- if ((written = fwrite(buffer.buffer(), 1, blockSize,\r
- fpTarget)) != blockSize) {\r
+ if ((written = fwrite(buffer.buffer(), 1, blockSize, fpTarget))\r
+ != blockSize) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6,\r
- i18n("cannot write $1 [$2] (errno: $3)"))\r
- .arg(target).arg(written).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_COPY_FILE_6,\r
+ i18n("cannot write $1 [$2] (errno: $3)")).arg(\r
+ target).arg(written).arg(errno).end();\r
break;\r
}\r
size -= blockSize;\r
rc = size == 0ll;\r
fclose(fpTarget);\r
if (properties != NULL)\r
- setProperties(target, properties, logger);\r
+ setProperties(target, properties, logger);\r
}\r
fclose(fpSource);\r
}\r
times[1].tv_usec = properties->st_mtim.tv_nsec / 1000;\r
if (utimes(fullName, times) != 0) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1,\r
- i18n("cannot change file times: $1 (errno: $2)"))\r
- .arg(fullName).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_1,\r
+ i18n("cannot change file times: $1 (errno: $2)")).arg(fullName)\r
+ .arg(errno).end();\r
rc = false;\r
}\r
int rights = properties->st_mode & (S_IRWXO | S_IRWXG | S_IRWXU);\r
if (chmod(fullName, rights) != 0) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2,\r
- i18n("cannot change file modes: $1 (errno: $2)"))\r
- .arg(fullName).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_2,\r
+ i18n("cannot change file modes: $1 (errno: $2)")).arg(fullName)\r
+ .arg(errno).end();\r
rc = false;\r
}\r
if (chown(fullName, properties->st_uid, properties->st_gid) != 0) {\r
if (logger != NULL)\r
- logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3,\r
- i18n("cannot change file owner: $1 (errno: $2)"))\r
- .arg(fullName).arg(errno).end();\r
+ logger->sayF(LOG_ERROR | CAT_FILE, LC_SET_PROPERTIES_3,\r
+ i18n("cannot change file owner: $1 (errno: $2)")).arg(fullName)\r
+ .arg(errno).end();\r
rc = false;\r
}\r
#endif\r
ReDirEntryFilter_t filter;\r
const char* sep = OS_SEPARATOR;\r
ReByteBuffer buffer;\r
- ReByteBuffer target(m_programArgs.getArg(m_programArgs.getArgCount() - 1));\r
+ ReByteBuffer target(m_programArgs.arg(m_programArgs.argCount() - 1));\r
target.removeLastChar(OS_SEPARATOR_CHAR);\r
if (!exists(target))\r
help(i18n("target does not exist: $1"), target.str());\r
int treeDirs = 0;\r
int64_t treeSumSizes = 0ll;\r
ReByteBuffer source, targetFile;\r
- for (int ix = 0; ix < m_programArgs.getArgCount() - 1; ix++) {\r
- source.set(m_programArgs.getArg(ix), -1);\r
+ for (int ix = 0; ix < m_programArgs.argCount() - 1; ix++) {\r
+ source.set(m_programArgs.arg(ix), -1);\r
target.setLength(lengthTargetBase);\r
bool endsWithSlash = source.endsWith(sep, 1);\r
if (endsWithSlash)\r
int diff = int(\r
m_statInfo.st_mtime\r
- entry->filetimeToTime(entry->modified()));\r
- if (!ignoreDate\r
- && diff <= maxFileTimeDiff) {\r
+ if (!ignoreDate && diff <= maxFileTimeDiff) {\r
if (m_verboseLevel >= V_CHATTER)\r
fprintf(m_output, "=ignored: %s same time\n",\r
targetRelativePath);\r
ReDirTCP::ReDirTCP(ReLogger* logger) :\r
ReTool(s_tcpUsage, s_tcpExamples, 1, 0, 0, true, logger) {\r
m_hasStandardArgs = false;\r
- m_programArgs.addInt("size", i18n("size of the message to send/receive (in KiByte)"),\r
- 'b', "--buffer-size", 64);\r
- m_programArgs.addInt("port", i18n("port of the server/client"),\r
- 'p', "--port", 58111);\r
+ m_programArgs.addInt("size",\r
+ i18n("size of the message to send/receive (in KiByte)"), 'b',\r
+ "--buffer-size", 64);\r
+ m_programArgs.addInt("port", i18n("port of the server/client"), 'p',\r
+ "--port", 58111);\r
}\r
\r
/**\r
int port = m_programArgs.getInt("port");\r
int bufferSize = m_programArgs.getInt("size") * 1024;\r
\r
- const char* command = m_programArgs.getArg(0);\r
- if (_stricmp(command, "server") == 0){\r
+ const char* command = m_programArgs.arg(0);\r
+ if (_stricmp(command, "server") == 0) {\r
ReTCPEchoServer server(port, m_logger);\r
server.listenForAll();\r
- } else if (_stricmp(command, "client") == 0){\r
- const char* ip = m_programArgs.getArg(1);\r
+ } else if (_stricmp(command, "client") == 0) {\r
+ const char* ip = m_programArgs.arg(1);\r
int rounds = 10;\r
int interval = 5;\r
- if (m_programArgs.getArgCount() > 2)\r
- rounds = atoi(m_programArgs.getArg(2));\r
- if (m_programArgs.getArgCount() > 3)\r
- interval = atoi(m_programArgs.getArg(3));\r
+ if (m_programArgs.argCount() > 2)\r
+ rounds = atoi(m_programArgs.arg(2));\r
+ if (m_programArgs.argCount() > 3)\r
+ interval = atoi(m_programArgs.arg(3));\r
ReTCPClient client(m_logger);\r
- if (client.connect(ip, port)){\r
+ if (client.connect(ip, port)) {\r
time_t start = time(NULL);\r
int64_t millisec;\r
ReByteBuffer message;\r
time_t lastPrint = start;\r
int64_t size = 0;\r
int duration = 0;\r
- for (int ii = 0; ii < rounds; ii++){\r
+ for (int ii = 0; ii < rounds; ii++) {\r
client.send("strlen", message.str(), message.length());\r
size += message.length();\r
time_t now = time(NULL);\r
- if (now >= lastPrint + interval){\r
+ if (now >= lastPrint + interval) {\r
duration = int(now - start);\r
printf("%2d: %9.3f MiByte %8.3f kiByte/sec\n", ii,\r
- size / 1024.0 / 1024, (double) size / duration / 1024);\r
+ size / 1024.0 / 1024, (double) size / duration / 1024);\r
lastPrint = now;\r
}\r
}\r
duration = int(time(NULL) - start);\r
if (duration == 0)\r
duration = 1;\r
- printf("%2d: %9.3f MiByte %8.3f kiByte/sec\n", rounds, size / 1024.0 / 1024,\r
- (double) size / duration / 1024);\r
+ printf("%2d: %9.3f MiByte %8.3f kiByte/sec\n", rounds,\r
+ size / 1024.0 / 1024, (double) size / duration / 1024);\r
\r
}\r
} else\r
\r
}\r
\r
-\r
/**\r
* Constructor.\r
*\r
i18n("a path list (separator see option 'separator'"), 'l', "list",\r
false, NULL);\r
m_programArgs.addString("separator",\r
- i18n("separator between the path elements"),\r
- 's', "separator", false,\r
+ i18n("separator between the path elements"), 's', "separator", false,\r
#if defined __linux__\r
- ":"\r
+ ":"\r
#elif defined __WIN32__\r
- ";"\r
+ ";"\r
#endif\r
- );\r
+) ;\r
m_programArgs.addString("variable", i18n("variable with the path list"),\r
'v', "variable", false, "PATH");\r
m_hasStandardArgs = false;\r
items.split(path.str(), sep);\r
struct stat info;\r
ReByteBuffer full;\r
- for (int ix = 0; ix < m_programArgs.getArgCount(); ix++) {\r
+ for (int ix = 0; ix < m_programArgs.argCount(); ix++) {\r
bool found = false;\r
\r
- ReByteBuffer arg(m_programArgs.getArg(ix));\r
+ ReByteBuffer arg(m_programArgs.arg(ix));\r
for (size_t ixItem = 0; ixItem < items.count(); ixItem++) {\r
full.set(items.strOf(ixItem));\r
if (arg.indexOf('*') < 0) {\r
*/\r
int ReDirTools::main(int argc, char* orgArgv[]) {\r
ReDirTools tools;\r
- if (argc < 0){\r
+ if (argc < 0) {\r
argc = 0;\r
for (int ix = 0; orgArgv[ix] != NULL; ix++)\r
argc++;\r
FILETIME m_modified;
FILETIME m_accessed;
ReFileSize_t m_size;
-} ReFileProperties_t;
+}ReFileProperties_t;
#endif
/**
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;
virtual void doIt();
};
-
/**
* Changes the filetime of files.
*/
};
class ReDirTools {
-
+public:
+ /** Destructor.
+ */
+ virtual ~ReDirTools() {
+ }
public:
virtual void usage(const char* msg, const char* msg2 = NULL);
void help(int argc, const char* argv[]);
* Constructor.\r
*/\r
ReDirStatus_t::ReDirStatus_t(ReLogger* logger) :\r
-m_path(),\r
-m_fullName(),\r
-m_passNo(0),\r
-m_logger(logger),\r
+ m_path(),\r
+ m_fullName(),\r
+ m_passNo(0),\r
+ m_logger(logger),\r
#ifdef __linux__\r
-m_handle(NULL),\r
-m_data(NULL)\r
+ m_handle(NULL),\r
+ m_data(NULL)\r
//m_status;\r
#elif defined WIN32\r
m_handle(INVALID_HANDLE_VALUE),\r
bool rc = false;\r
#if defined __linux__\r
if (m_handle != NULL)\r
- closedir(m_handle);\r
+ closedir(m_handle);\r
m_handle = opendir(m_path.str());\r
rc = m_handle != NULL && (m_data = readdir(m_handle)) != NULL;\r
m_status.st_ino = 0;\r
bool ReDirStatus_t::isDirectory() {\r
#ifdef __linux__\r
return m_data->d_type == DT_DIR\r
- || (m_data->d_type == DT_UNKNOWN && S_ISDIR(getStatus()->st_mode));\r
+ || (m_data->d_type == DT_UNKNOWN && S_ISDIR(getStatus()->st_mode));\r
#elif defined __WIN32__\r
return 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);\r
#endif\r
*/\r
bool ReDirStatus_t::isDotDir() const {\r
#ifdef __linux__\r
- bool rc = m_data == NULL || (m_data->d_name[0] == '.' && (m_data->d_name[1] == '\0'\r
- || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0')));\r
+ bool rc = m_data == NULL\r
+ || (m_data->d_name[0] == '.'\r
+ && (m_data->d_name[1] == '\0'\r
+ || (m_data->d_name[1] == '.' && m_data->d_name[2] == '\0')));\r
#elif defined __WIN32__\r
bool rc = m_data.cFileName[0] == '.' && (m_data.cFileName[1] == '\0'\r
|| (m_data.cFileName[1] == '.' && m_data.cFileName[2] == '\0'));\r
bool rc;\r
#ifdef __linux__\r
rc = m_data->d_type == DT_LNK\r
- || (m_data->d_type == DT_UNKNOWN && S_ISLNK(getStatus()->st_mode));\r
+ || (m_data->d_type == DT_UNKNOWN && S_ISLNK(getStatus()->st_mode));\r
#elif defined __WIN32__\r
rc = 0 != (m_data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT);\r
#endif\r
bool ReDirStatus_t::isRegular() {\r
#ifdef __linux__\r
return m_data->d_type == DT_REG\r
- || (m_data->d_type == DT_UNKNOWN && S_ISREG(getStatus()->st_mode));\r
+ || (m_data->d_type == DT_UNKNOWN && S_ISREG(getStatus()->st_mode));\r
#elif defined __WIN32__\r
return 0 == (m_data.dwFileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));\r
#endif\r
buffer.appendChar(' ');\r
struct passwd* passwd = getpwuid(getStatus()->st_uid);\r
if (passwd == NULL)\r
- buffer.appendInt(getStatus()->st_uid, "%4d");\r
+ buffer.appendInt(getStatus()->st_uid, "%4d");\r
else\r
- addId(passwd->pw_name, 5, buffer);\r
+ addId(passwd->pw_name, 5, buffer);\r
buffer.appendChar(' ');\r
struct group* group = getgrgid(getStatus()->st_gid);\r
if (group == NULL)\r
- buffer.appendInt(getStatus()->st_gid, "%4d");\r
+ buffer.appendInt(getStatus()->st_gid, "%4d");\r
else\r
- addId(group->gr_name, 5, buffer);\r
+ addId(group->gr_name, 5, buffer);\r
buffer.appendChar(' ');\r
}\r
#elif defined __WIN32__\r
#if defined __linux__\r
int flags = getStatus()->st_mode;\r
if (S_ISDIR(flags))\r
- rc = TF_SUBDIR;\r
+ rc = TF_SUBDIR;\r
else if (flags == 0 || S_ISREG(flags))\r
- rc = TF_REGULAR;\r
+ rc = TF_REGULAR;\r
else if (S_ISLNK(flags))\r
- rc = TF_LINK;\r
+ rc = TF_LINK;\r
else if (S_ISCHR(flags))\r
- rc = TF_CHAR;\r
+ rc = TF_CHAR;\r
else if (S_ISBLK(flags))\r
- rc = TF_BLOCK;\r
+ rc = TF_BLOCK;\r
else if (S_ISFIFO(flags))\r
- rc = TF_PIPE;\r
+ rc = TF_PIPE;\r
else if (S_ISSOCK(flags))\r
- rc = TF_SOCKET;\r
+ rc = TF_SOCKET;\r
else\r
- rc = TF_OTHER;\r
+ rc = TF_OTHER;\r
#elif defined __WIN32__\r
int flags = (m_data.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY\r
| FILE_ATTRIBUTE_HIDDEN\r
//m_maxAge(0),\r
m_minDepth(0),\r
m_maxDepth(512),\r
- m_allDirectories(false){\r
+ m_allDirectories(false) {\r
setFiletimeUndef(m_minAge);\r
setFiletimeUndef(m_maxAge);\r
}\r
bool ReDirEntryFilter_t::match(ReDirStatus_t& entry) {\r
bool rc = false;\r
do {\r
- if (m_allDirectories && entry.isDirectory()){\r
+ if (m_allDirectories && entry.isDirectory()) {\r
rc = true;\r
break;\r
}\r
struct stat* ReDirStatus_t::getStatus() {\r
if (m_status.st_ino == 0) {\r
if (stat(fullName(), &m_status) != 0)\r
- m_status.st_ino = 0;\r
+ m_status.st_ino = 0;\r
}\r
return &m_status;\r
}\r
class ReTraverser: public ReDirTreeStatistic {
public:
ReTraverser(const char* base, ReTraceUnit* tracer = NULL, ReLogger* logger =
- NULL);
+ NULL);
virtual ~ReTraverser();
public:
void changeBase(const char* base);
* The value has no interest for the caller
* @return <code>true</code>: 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);
* @param depthFirst <code>true</code>: 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).
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"
#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);
ReSimpleMatcher::ReSimpleMatcher() :
ReMatcher(),
m_pattern(),
- m_tokens() {
+ m_tokens(),
+ m_ignoreCase(false) {
}
/**
ReSimpleMatcher::ReSimpleMatcher(const char* pattern) :
ReMatcher(),
m_pattern(),
- m_tokens() {
+ m_tokens(),
+ m_ignoreCase(false) {
compile(pattern);
}
/**
RePatternList::RePatternList() :
m_patternString(),
m_patterns(NULL),
- m_count(0) {
+ m_count(0),
+ m_startNot(0) {
}
/**
* Destructor.