]> gitweb.hamatoma.de Git - crepublib/commitdiff
Refactoring ReRandomizer, fix in ReStringList::readFromFile()
authorhama <hama@siduction.net>
Sun, 18 Jan 2015 11:23:01 +0000 (12:23 +0100)
committerhama <hama@siduction.net>
Sun, 18 Jan 2015 11:23:01 +0000 (12:23 +0100)
23 files changed:
base/ReByteBuffer.cpp
base/ReByteBuffer.hpp
base/ReProgramArgs.cpp
base/ReStringList.cpp
base/ReStringList.hpp
base/ReTestUnit.cpp
base/ReTestUnit.hpp
base/ReVarArgs.cpp
base/rebase.hpp
cunit/cuHashList.cpp [deleted file]
cunit/cuReByteBuffer.cpp
cunit/cuReDirectory.cpp
cunit/cuReHashList.cpp [new file with mode: 0644]
cunit/cuReProgramArgs.cpp
cunit/cuReRandomizer.cpp [new file with mode: 0644]
cunit/cuReStringList.cpp
cunit/cuReTest.cpp
cunit/cuReTraverser.cpp
cunit/cuReconfig.cpp
cunit/testall.cpp
math/ReRandomizer.cpp
math/ReRandomizer.hpp
math/remath.hpp

index c44ef3fefd928385575fe2fab933cf58ced13933..4e18366e277543ccb213ba517387a12d46e72bcf 100644 (file)
@@ -161,6 +161,40 @@ ReByteBuffer&  ReByteBuffer::appendInt(int number, const char* format){
 ReByteBuffer& ReByteBuffer::append(const ReByteBuffer& source){
        return append(source.str(), source.length());
 }
+/** @brief Appends a time (given in milli seconds) as 'dd:HH:MM.mmm'.
+ *
+ * @param time         the time (duration) in msec
+ * @param minLength    > 5: seconds will be 2 digits (preceeding '0' if needed)<br>
+ *                                     > 6: at least MM:SS.sss<br>
+ *                                     > 9: at least HH:MM:SS.sss<br>
+ *                                     > 12: at least dd:HH:MM:SS.sss<br>
+ * @return                     <code>buffer</code> (for chaining)
+ */
+ReByteBuffer& ReByteBuffer::appendMilliSec(int time, int minLength){
+       int days = time / (24 * 3600 * 1000LL);
+       time %= 24 * 3600 * 1000;
+       int expectedLength = days > 0 ? 12 : 0;
+       int hours = time / (3600 * 1000);
+       time %= 3600 * 1000;
+       if (hours > 0 && expectedLength == 0)
+               expectedLength = 9;
+       int minutes = time / (60 * 1000);
+       time %= 60 * 1000;
+       if (minutes > 0 && expectedLength == 0)
+               expectedLength = 5;
+       int minimum = minLength > expectedLength ? minLength : expectedLength;
+       int sec = time / 1000;
+       int msec = time % 1000;
+       static const char* stdFormat = "%02d";
+       if (days > 0 || minimum > 12)
+               appendInt(days).append(":");
+       if (hours > 0 || minimum > 9)
+               appendInt(hours, stdFormat).append(":");
+       if (minutes > 0 || minimum > 6)
+               appendInt(minutes, stdFormat).append(":");
+       appendInt(sec, sec > 10 || minimum > 5 ? stdFormat : "%d").append(".");
+       appendInt(msec, "%03d");
+}
 
 /** Converts a subsequence into an integer.
  *
@@ -261,6 +295,24 @@ void ReByteBuffer::ensureSize(size_t size){
                m_capacity = size;
        }
 }
+/**
+ * @brief Fills a part of the buffer with a given character.
+ *
+ * @param filler       the byte which is used as filler
+ * @param start                the first index to fill. <code>0 <= start < m_length</code>
+ * @param end          the index behind the last filled position. May be behind m_length
+ * @return                     the instance itself (vor chaining)
+ */
+ReByteBuffer& ReByteBuffer::fill(Byte filler, int start, int end){
+       if (end == -1)
+               end = m_length;
+       if (start >= 0 && start < end){
+               if (end > m_length)
+                       setLength(end);
+               memset(m_buffer + start, filler, end - start);
+       }
+       return *this;
+}
 
 /** @brief Checks for the index of the first different byte.
  *
@@ -454,7 +506,7 @@ ReByteBuffer&  ReByteBuffer::setLength(size_t length){
  *                                     will be filled with this value
  * @return *this (for chaining)
  */
-ReByteBuffer&  ReByteBuffer::setLengthAndFill(size_t length, Byte filler){
+ReByteBuffer&  ReByteBuffer::setLengthAndFillOut(size_t length, Byte filler){
        ensureSize(length);
        if (length > m_length)
                memset(m_buffer + m_length, filler, length - m_length);
index aa6f891b762b0a9e06ff1e49e31f7dfe82b4567f..e4df448bd46b6596b2f28fe0fe60ed06659f7cec 100644 (file)
@@ -45,6 +45,7 @@ public:
        ReByteBuffer& append(const Byte* source, size_t length = -1);
        ReByteBuffer& append(const ReByteBuffer& source);
        ReByteBuffer& appendInt(int number, const char* format = "%d");
+       ReByteBuffer& appendMilliSec(int time, int minLength = 5);
        /** @brief Returns the n-th byte of the internal buffer.
         * @param index         The index of the wanted byte.
         * @return 0: Wrong index. Otherwise: The byte from the wanted position.
@@ -83,6 +84,7 @@ public:
                bool rc = buffer.length() == m_length && _memcmp(buffer.str(), m_buffer, m_length) == 0;
                return rc;
        }
+       ReByteBuffer& fill(Byte filler = 0, int start = 0, int end = -1);
        int firstDifference(const Byte* source, size_t length, int start = 0, bool ignoreCase = false);
        /** @brief Finds the index of the first occurrence of a given byte.
         * @param toFind        This byte will be searched.
@@ -158,8 +160,7 @@ public:
        }
        void setDelta(int delta);
        ReByteBuffer& setLength(size_t length);
-       ReByteBuffer& setLengthAndFill(size_t length, Byte filler = 0);
-
+       ReByteBuffer& setLengthAndFillOut(size_t length, Byte filler = 0);
        bool splice(size_t ix, size_t replacedLength, const Byte* source, size_t length);
        bool startsWith(const Byte* head, size_t headLength = -1,
                                const bool ignoreCase = false) const;
index 3f82448377e56d55d77318ce83c448cf038b2c12..7bf6cee9c091391a74e2b985e657974c868d4bba 100644 (file)
@@ -334,7 +334,6 @@ void ReProgramArgs::search(char shortName, const char* longName,
        }
        while (! found && m_properties.next(position, &name, &properties)){
                const char* ptr = properties.str();
-               printf("%s\n", ptr);
                list.split(properties.str(), '\1');
                if (longName == NULL && list.count() > IxShort && shortName == list.strOf(IxShort)[0])
                        found = true;
index 52dc481ae9b3208590dded9a2e053bd1420f0d03..2acae526208b9e74d66fee1954415d7286ca5801 100644 (file)
@@ -21,11 +21,11 @@ ReStringList::ReStringList(int deltaList, int deltaBuffer)  :
  */
 ReStringList::~ReStringList() {
 }
-/** @brief Appends a string at the end.
+/** @brief Appends a string at the end
  *
- * @param source       The new string.
+ * @param source       the new string
  * @param tagOf        An item which will stored with the string. It can be retrieved
- *                                     by the same index.This class knows nothing about this.
+ *                                     by the same index.This class knows nothing about this
  * @return                     the instance itself (for chaining)
  */
 ReStringList& ReStringList::append(const char* source, Tag tagOf){
@@ -34,65 +34,65 @@ ReStringList& ReStringList::append(const char* source, Tag tagOf){
 }
 /** @brief Appends a string at the end.
  *
- * @param source       The new string.
+ * @param source       the new string
  * @param tagOf        An item which will stored with the string. It can be retrieved
- *                                     by the same index.This class knows nothing about this.
+ *                                     by the same index.This class knows nothing about this
  * @return                     the instance itself (for chaining)
  */
 ReStringList& ReStringList::append(const ReByteBuffer& source, Tag tagOf){
-       add(-1, source.str(), source.length() + 1, tagOf);
+       int ix = add(-1, source.str(), source.length() + 1, tagOf);
        return *this;
 }
 
 /** @brief Appends a stringlist at the end.
  *
- * @param source       The new stringlist.
+ * @param source       the new stringlist
  * @return                     the instance itself (for chaining)
  */
 ReStringList& ReStringList::append(const ReStringList& source){
        for (size_t ii = 0; ii < source.count(); ii++)
-               add(-1, source.strOf(ii), source.sizeOf(ii), source.tagOf(ii));
+               add(-1, source.strOf(ii), source.strLengthOf(ii), source.tagOf(ii));
        return *this;
 }
 /** @brief Inserts a string at a given index.
  *
  * If the index exceeds the length of the array it will be appended.
  *
- * @param source       The new string.
- * @param tagOf                An item which will stored with the string. It can be retrieved by the same index.
- *                                     This class knows nothing about this.
+ * @param source       the new string
+ * @param tagOf                an item which will stored with the string. It can be retrieved by the same index.
+ *                                     This class knows nothing about this
  */
 void ReStringList::insert(Index index, const char* source, Tag tagOf){
        add(index, source, strlen(source) + 1, tagOf);
 }
 /** @brief Replaces an element in the internal array: a string and a tagOf.
  *
- * @param index        The element with this index will be replaced.
- * @param source       The new string of the replaced element.
- * @param tagOf                The tagOf of the replace element.
+ * @param index        the element with this index will be replaced
+ * @param source       the new string of the replaced element
+ * @param tagOf                the tagOf of the replace element
  */
 void ReStringList::replace(Index index, const char* source, Tag tagOf){
-       set(index, source, strlen(source), tagOf);
+       set(index, source, strlen(source) + 1, tagOf);
 }
 /** @brief Replaces a string in the internal array.
  *
  * The tagOf of the element remains unchanged.
  *
- * @param index        The element with this index will be replaced.
- * @param source       The new string of the replaced element.
+ * @param index        the element with this index will be replaced
+ * @param source       the new string of the replaced element
  */
 void ReStringList::replaceString(Index index, const char* source){
        if (index < count()){
                Sequence* seq = getInfo(index);
-               set(index, source, strlen(source), seq->m_tag);
+               set(index, source, strlen(source) + 1, seq->m_tag);
        }
 }
 /** @brief Replaces a tagOf in the internal array.
  *
  * The string of the element remains unchanged.
  *
- * @param index        The element with this index will be replaced.
- * @param source       The new string of the replaced element.
+ * @param index        the element with this index will be replaced
+ * @param source       the new string of the replaced element
  */
 void ReStringList::replaceTag(Index index, Tag tagOf){
        if (index < count()){
@@ -103,10 +103,10 @@ void ReStringList::replaceTag(Index index, Tag tagOf){
 
 /** @brief Returns the C string given by an index.
  *
- * @param index                The index of the wanted string.
+ * @param index                the index of the wanted string
  *
- * @return     NULL: The index is too large.
- *                     Otherwise: The wanted string.
+ * @return     NULL: the index is too large.
+ *                     Otherwise: the wanted string
  */
 const char* ReStringList::strOf(Index index) const{
        const char* rc = NULL;
@@ -120,10 +120,10 @@ const char* ReStringList::strOf(Index index) const{
  *
  * A tagOf is an additional info stored with the string.
  *
- * @param index                The index of the wanted tagOf.
+ * @param index                the index of the wanted tagOf
  *
- * @return     -1: The index is too large.
- *                     Otherwise: The wanted tagOf.
+ * @return     -1: the index is too large.<br>
+ *                     Otherwise: the wanted tag
  */
 ReSeqArray::Tag ReStringList::tagOf(Index index) const{
        Tag rc = -1;
@@ -135,11 +135,11 @@ ReSeqArray::Tag ReStringList::tagOf(Index index) const{
 }
 /** @brief Returns the length of the byte sequence given by an index.
  *
- * @param index                The index of the wanted string length.
+ * @param index                the index of the wanted string length
  *
- * @return     0: The index is too large.
- *                     Otherwise: The length of the <code>index</code>-th sequence
- *                     (including the trailing '\0').
+ * @return     0: the index is too large
+ *                     Otherwise: the length of the <code>index</code>-th sequence
+ *                     (including the trailing '\0')
  */
 size_t ReStringList::sizeOf(Index index) const{
        size_t rc = 0;
@@ -152,11 +152,11 @@ size_t ReStringList::sizeOf(Index index) const{
 }
 /** @brief Returns the length of the string given by an index.
  *
- * @param index                The index of the wanted string length.
+ * @param index                the index of the wanted string length
  *
- * @return     0: The index is too large.
- *                     Otherwise: The length of the <code>index</code>-th sequence
- *                     (excluding the trailing '\0').
+ * @return     0: the index is too large.<br>
+ *                     Otherwise: the length of the <code>index</code>-th sequence
+ *                     (excluding the trailing '\0')
  */
 size_t ReStringList::strLengthOf(Index index) const{
        size_t rc = 0;
@@ -168,7 +168,7 @@ size_t ReStringList::strLengthOf(Index index) const{
 }
 /** @brief Returns the sum of all string lengths stored in the array.
  *
- * @return The sum of all string lengths stored in the array.
+ * @return the sum of all string lengths stored in the array
  */
 size_t ReStringList::sumOfSizes() const{
        size_t rc = 0;
@@ -181,7 +181,7 @@ size_t ReStringList::sumOfSizes() const{
 }
 /** @brief Returns the sum of all string lengths stored in the array.
  *
- * @return The sum of all string lengths stored in the array.
+ * @return the sum of all string lengths stored in the array
  */
 size_t ReStringList::sumOfStrLengths() const{
        size_t rc = 0;
@@ -194,12 +194,12 @@ size_t ReStringList::sumOfStrLengths() const{
 }
 /** @brief Returns the index of a given string in the array.
  *
- * @param toFind               The string which will be searched.
- * @param ignoreCase   true: The search is case insensitive.
- *                                             false: The search is case sensitive.
- * @param start                        The search starts at this index.
+ * @param toFind               the string which will be searched
+ * @param ignoreCase   true: the search is case insensitive.<br<
+ *                                             false: the search is case sensitive
+ * @param start                        the search starts at this index
  *
- * @return -1: The string was not found. Otherwise: The index of the string.
+ * @return -1: the string was not found. Otherwise: the index of the string
  */
 ReSeqArray::Index ReStringList::indexOf(const char* toFind,
                bool ignoreCase, Index start) const{
@@ -220,12 +220,12 @@ ReSeqArray::Index ReStringList::indexOf(const char* toFind,
 }
 /** Returns the index of the next string starting with a given substring.
  *
- * @param start                        The search starts at this index.
- * @param prefix               The substring which will be searched.
- * @param ignoreCase   true: The search is case insensitive.
- *                                             false: The search is case sensitive.
+ * @param start                        the search starts at this index
+ * @param prefix               the substring which will be searched
+ * @param ignoreCase   true: the search is case insensitive<br>
+ *                                             false: the search is case sensitive
  *
- * @return -1: The string was not found. Otherwise: The index of the string.
+ * @return -1: the string was not found. Otherwise: the index of the string
  */
 ReSeqArray::Index ReStringList::nextStartingWith(Index start,
                const char* prefix, bool ignoreCase){
@@ -247,11 +247,11 @@ ReSeqArray::Index ReStringList::nextStartingWith(Index start,
 }
 /** @brief Splits a string in an array.
  *
- * @param list                 The string which is splitted.
- * @param separator            The separator of the substrings.
- *                                             If '\\n' a preceeding or trailing '\\r' will be ignored too.
- * @param append               false: The list will be cleared at the beginning.
- *                                             true: The new content is stored at the end.
+ * @param list                 the string which is splitted
+ * @param separator            the separator of the substrings.<br>
+ *                                             If '\\n' a preceeding or trailing '\\r' will be ignored too
+ * @param append               false: the list will be cleared at the beginning.<br>
+ *                                             true: the new content is stored at the end
  */
 void ReStringList::split(const char* list, char separator, bool append){
        if (! append)
@@ -280,8 +280,8 @@ void ReStringList::split(const char* list, char separator, bool append){
 }
 /** @brief Joins all string of the array into a string.
  *
- * @param separator            This string was put between the substrings. May be NULL or "".
- * @param result               Out: The result buffer.
+ * @param separator            This string was put between the substrings. May be NULL or ""
+ * @param result               Out: the result buffer
  * @return                             <code>buffer</code> (for chaining)
  */
 ReByteBuffer& ReStringList::join(const char* separator, ReByteBuffer& result) const{
@@ -299,11 +299,11 @@ ReByteBuffer& ReStringList::join(const char* separator, ReByteBuffer& result) co
 }
 /** @brief Writes the stringlist to a file.
  *
- * @param filename             The name of the file.
- * @param separator            This string was put between the substrings. May be NULL.
- * @param mode                 The file open mode: "w" for truncate and write, "a" for append.
+ * @param filename             the name of the file
+ * @param separator            this string was put between the substrings. May be NULL
+ * @param mode                 the file open mode: "w" for truncate and write, "a" for append
  *
- * @return true: The file could be opened. false: otherwise.
+ * @return true: the file could be opened. false: otherwise
  */
 bool ReStringList::writeToFile(const char* filename,
                const char* separator, const char* mode){
@@ -323,25 +323,25 @@ bool ReStringList::writeToFile(const char* filename,
 }
 /** @brief Reads a file into the array.
  *
- * Every line is stored as entry of the array.
+ * Each line is stored as an element of the array.
  *
- * @param filename             The name of the file.
- * @param cutNewline   true: The newline characters will be cut.
- *                                             false: The newline characters will be stored.
+ * @param filename             the name of the file
+ * @param cutNewline   true: the newline characters will be cut<br>
+ *                                             false: the newline characters will be stored
  *
- * @return true: The file could be opened. false: otherwise.
+ * @return true: the file could be opened. false: otherwise
  */
 bool ReStringList::readFromFile(const char* filename, bool cutNewline){
        FILE* fp = fopen(filename, "r");
        bool rc = false;
        if (fp != NULL){
                char line[8096];
-
+               char cc;
                while(fgets(line, sizeof line, fp) != NULL){
                        size_t length = strlen(line);
                        if (cutNewline){
-                               while(--length > 0 && (line[length] == '\n' || line[length] == '\r'))
-                                       line[length] = '\n';
+                               while(length > 0 && ( (cc = line[length - 1]) == '\n' || cc == '\r'))
+                                       line[--length] = '\0';
                        }
                        add(-1, line, length + 1);
                }
@@ -351,11 +351,11 @@ bool ReStringList::readFromFile(const char* filename, bool cutNewline){
 }
 /** @brief Returns the index of the first different string.
  *
- * Compares the internal array of strings with another instance.
+ * Compares the internal array of strings with another instance
  *
- * @param toCompare    The other instance which will be compared.
+ * @param toCompare    the other instance which will be compared
  *
- * @return -1: The instances are equal. Otherwise: The index of the first different string.
+ * @return -1: the instances are equal. Otherwise: the index of the first different string
  *
  */
 int ReStringList::firstDiff(const ReStringList& toCompare) const{
@@ -378,9 +378,9 @@ int ReStringList::firstDiff(const ReStringList& toCompare) const{
  * Two instances are equal when the number of strings are equal
  * and the n.th string is equal to the n.th string in the other instance.
  *
- * @param toCompare    The other instance which will be compared.
+ * @param toCompare    the other instance which will be compared
  *
- * @return true: The other instance is equal. false: Otherwise.
+ * @return true: the other instance is equal. false: Otherwise
  */
 bool ReStringList::equal(const ReStringList& toCompare) const{
        bool rc = count() == toCompare.count() && firstDiff(toCompare) == -1;
index 0020fbbb7d38f608ee1f67f3779701c7f3a2f447..df96e71a82c26aeabe7cc50a9e519b0bfa6d43f4 100644 (file)
@@ -10,7 +10,8 @@
 
 /**
  * This class implements a dynamic array of C strings.
- * <p>With this class it is very simple to break a string into a vector of substrings.</p>
+ * With this class it is very simple to break a string into a vector of substrings.
+ *
  * <pre>
  * <strong>Example:</strong>
  * This example adds a column with a current number to a CSV file (comma separated file):
index 366de0f723f30e826fc7d9b09f162724a3546f5c..7b6a24113577f5a6a7e36308321b711978049562 100644 (file)
@@ -19,6 +19,7 @@ ReTestUnit::ReTestUnit(const char* name, const char* sourceFile)
        m_buffer()
 {
        logF(false, i18n("Start %s"), name);
+       createTestDir();
 }
 
 /** @brief Destructor.
@@ -165,11 +166,11 @@ void ReTestUnit::assertEqualFiles(const char* name1, const char* name2, int line
        list1.readFromFile(name1);
        list2.readFromFile(name2);
        int ix = list1.firstDiff(list2);
-       if (ix < 0){
+       if (ix >= 0){
                ReByteBuffer line1(list1.strOf(ix), list1.strLengthOf(ix));
                int ixLine = line1.firstDifference(list2.strOf(ix), list2.strLengthOf(ix));
                logF(true, i18n("%s-%d: Files differ in line %d-%d\n%s\n%s\n%s"),
-                       m_sourceFile.str(), lineNo, ix, ixLine,
+                       m_sourceFile.str(), lineNo, ix + 1, ixLine,
                        (int) list1.count() > ix ? list1.strOf(ix) : "",
                        (int) list2.count() > ix ? list2.strOf(ix) : "",
                        colMarker(ixLine));
@@ -177,6 +178,18 @@ void ReTestUnit::assertEqualFiles(const char* name1, const char* name2, int line
 
 }
 
+/** @brief Returns the full path of a file in the test directory.
+ *
+ * @param node         the node (filename without path)
+ * @param buffer       OUT: the filename will be constructed in this buffer
+ * @return                     <code>buffer.str()</code>: the full filename
+ */
+const char* ReTestUnit::buildFilename(const char* node, ReByteBuffer& buffer){
+       createTestDir();
+       buffer.setLength(0).append(m_tempDir).append(node);
+       return buffer.str();
+}
+
 /**
  * Returns a string usable as a marker of a given column.
  *
@@ -185,7 +198,7 @@ void ReTestUnit::assertEqualFiles(const char* name1, const char* name2, int line
  */
 const char* ReTestUnit::colMarker(int col){
        if (col > 0)
-               m_buffer.setLengthAndFill(col - 1, '-');
+               m_buffer.fill('-', 0, col - 1);
        else
                m_buffer.setLength(0);
        m_buffer.append("^", 1);
@@ -196,41 +209,81 @@ const char* ReTestUnit::colMarker(int col){
  * the name can be retrieved by <code>getTestDir()</code>.
  */
 void ReTestUnit::createTestDir(){
-       char name[512];
-       if (getenv("TMP") != NULL){
-               strcpy(name, getenv("TMP"));
-       } else if (getenv("TEMP")){
-               strcpy(name, getenv("TEMP"));
-       } else {
-               strcpy(name, "/tmp/");
+       if (m_tempDir.length() == 0){
+               char name[512];
+               if (getenv("TMP") != NULL){
+                       strcpy(name, getenv("TMP"));
+               } else if (getenv("TEMP")){
+                       strcpy(name, getenv("TEMP"));
+               } else {
+                       strcpy(name, "/tmp/");
+               }
+               char* ptr = name + strlen(name) - 1;
+               if (*ptr != ReStringUtils::pathSeparator())
+                       strcpy(ptr + 1, ReStringUtils::pathSeparatorStr());
+               strcat(ptr, "retestunit");
+               strcat(ptr, ReStringUtils::pathSeparatorStr());
+               struct stat info;
+       #ifdef __WIN32__
+       #define ALLPERMS 0
+       #endif
+               if (lstat(name, &info) != 0)
+                       _mkdir(name);
+               else{
+                       char cmd[512 + 128];
+                       _snprintf(cmd, sizeof cmd, "rm -Rf %s*", name);
+                       system(cmd);
+               }
+               m_tempDir.set(name, -1);
        }
-       char* ptr = name + strlen(name) - 1;
-       if (*ptr != ReStringUtils::pathSeparator())
-               strcpy(ptr + 1, ReStringUtils::pathSeparatorStr());
-       strcat(ptr, "retestunit");
-       strcat(ptr, ReStringUtils::pathSeparatorStr());
-       struct stat info;
-#ifdef __WIN32__
-#define lstat stat
-#define mkdir(name, flags) _mkdir(name)
-#define ALLPERMS 0
+}
+
+/**
+ * @brief Calculates the time since a given start.
+ *
+ * <pre>int64_t start = test.timer();
+ * ...
+ * int duration = test.milliSecSince(start);
+ * </pre>
+ *
+ * @return     a time usable for for runtime measurement
+ */
+int ReTestUnit::milliSecSince(int64_t start){
+#if defined __linux__
+       int64_t diff = clock() - start;
+       return diff * 1000 / CLOCKS_PER_SEC;
+#else
+#      error "timer not defined"
+#endif
+}
+
+/**
+ * @brief 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
+ */
+int64_t ReTestUnit::timer(){
+#if defined __linux__
+       return clock();
+#else
+#      error "timer not defined"
 #endif
-       if (lstat(name, &info) != 0)
-               _mkdir(name);
-       else{
-               char cmd[512 + 128];
-               _snprintf(cmd, sizeof cmd, "rm -Rf %s*", name);
-               system(cmd);
-       }
-       m_tempDir.set(name, -1);
 }
+
 /** @brief Returns the temporary directory.
  *
  * @return the name of a temporary directory
  */
-const char* ReTestUnit::getTestDir(){
+const char* ReTestUnit::testDir(){
+       createTestDir();
        return m_tempDir.str();
 }
+
 /** @brief Creates a file and fills it with an given content.
  *
  * @param filename     the name of the file
index 2b1d1874b969e62d251c71b310bf6bf0616c4c6b..d902ada5add63647993068146c92adb7199df2f7 100644 (file)
@@ -30,13 +30,17 @@ public:
        void assertNotNull(void* pointer, int lineNo);
        void assertNull(void* pointer, int lineNo);
        void assertTrue(bool conditon, int lineNo);
+       const char* buildFilename(const char* node, ReByteBuffer& buffer);
        void createDir(const char* filename);
        void createFile(const char* filename, const char* content);
-       void createTestDir();
        const char* colMarker(int col);
-       const char* getTestDir();
+       const char* testDir();
        virtual bool log(bool isError, const char* message);
        virtual bool logF(bool isError, const char* format, ...);
+       int milliSecSince(int64_t start);
+       int64_t timer();
+private:
+       void createTestDir();
 protected:
        int m_errorCount;
        ReByteBuffer m_name;
index a0b91510ce7c7012d054d9b5062abcf88f27a873..8f995804999d03b38f44015f9b82a36ce6c6e806 100644 (file)
@@ -213,7 +213,7 @@ ReVarArgs& ReVarArgs::arg(const char* value, int minWidth, int maxWidth, bool al
                store(value, maxWidth);
        } else {
                ReByteBuffer buffer;
-               buffer.setLengthAndFill(minWidth, ' ');
+               buffer.setLengthAndFillOut(minWidth, ' ');
                if (alignRight)
                        memcpy(buffer.buffer() + minWidth - length, value, length);
                else
index 19251d2b55a0717fc46189464c018de6b3013bc6..8ad33c652485451f3289039c1551be29753eb676 100644 (file)
@@ -17,6 +17,7 @@
 #include <ctype.h>
 #include <assert.h>
 #include <stdarg.h>
+#include <limits.h>
 
 #if defined __linux__
 
@@ -26,7 +27,8 @@
 #      include <regex.h>
 #      include <unistd.h>
 #      include <inttypes.h>
-
+#      include <fcntl.h>
+typedef u_int64_t uint64_t;
 #      define _strdup strdup
 #      define _unlink unlink
 #      define _strnicmp(s1, s2, n) strncasecmp(s1, s2, n)
@@ -38,6 +40,7 @@
 #      include <direct.h>
 #      include <windows.h>
 #      define _memcmp(t,s,n) memcmp(t,s,n)
+#      define lstat stat
        typedef _int64 int64_t;
     typedef unsigned long long uint64_t;
     typedef unsigned char uint8_t;
diff --git a/cunit/cuHashList.cpp b/cunit/cuHashList.cpp
deleted file mode 100644 (file)
index cd92cd5..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "base/rebase.hpp"
-
-class TestReHashList : public ReTestUnit {
-public:
-       TestReHashList() : ReTestUnit("ReHashList", __FILE__){
-               run();
-       }
-private:
-       void run(){
-               testBasic();
-               testNext();
-       }
-       void massTest(){
-               ReHashList hash();
-               ReByteBuffer key, value;
-               log(false, "missing masstest");
-       }
-       void testBasic(){
-               ReHashList hash;
-               ReByteBuffer key, value;
-
-               hash.put("abc", "123");
-               checkT(hash.get("abc", -1, value));
-               checkEqu("123", value.str());
-
-               hash.put("ab", "999");
-               checkT(hash.get("ab", -1, value));
-               checkEqu("999", value.str());
-
-               checkT(hash.get("abc", -1, value));
-               checkEqu("123", value.str());
-
-               hash.put("abc", "!!!");
-               checkT(hash.get("abc", -1, value));
-               checkEqu("!!!", value.str());
-
-               checkT(hash.get("ab", -1, value));
-               checkEqu("999", value.str());
-
-               hash.put("abc", "longer");
-               checkT(hash.get("abc", -1, value));
-               checkEqu("longer", value.str());
-
-               checkT(hash.get("ab", -1, value));
-               checkEqu("999", value.str());
-       }
-       void testNext(){
-               ReHashList hash;
-               hash.put("4", "2");
-               hash.put("1", "8");
-               hash.put("2", "4");
-               hash.put("8", "1");
-               int flagsKey = 0;
-               int flagsVal = 0;
-               ReArrayPosition pos;
-               ReByteBuffer key, value;
-               while(hash.next(pos, &key, &value)){
-                       int x = atol(key.buffer());
-                       int y = atol(value.buffer());
-                       checkEqu(8, x * y);
-                       flagsKey += x;
-                       flagsVal += y;
-               }
-               checkEqu(15, flagsKey);
-               checkEqu(15, flagsVal);
-       }
-};
-extern void testReHashList(void);
-
-void testReHashList(void){
-       TestReHashList unit;
-}
index a97af5fa7d08b3e44e333f2e92419cd79089b642..41481bdc85e176cac0743c952cb2014ca8283612 100644 (file)
@@ -2,7 +2,6 @@
  * cuReByteBuffer.cpp
  *
  *  Created on: 27.11.2010
- *      Author: wk
  */
 #include "base/rebase.hpp"
 class TestReByteBuffer : public ReTestUnit {
@@ -13,6 +12,8 @@ public:
        }
 private:
        void run(){
+               testFill();
+               testAppendMilliSec();
                testSetDelta();
                testFirstDiff();
                testCount();
@@ -32,6 +33,21 @@ private:
                testSplice();
                testReplace();
        }
+       void testFill(){
+               ReByteBuffer buf;
+               buf.fill('=', 0, 3);
+               checkEqu("===", buf.str());
+               buf.fill('x', 1, 2);
+               checkEqu("=x=", buf.str());
+       }
+       void testAppendMilliSec(){
+               ReByteBuffer buf;
+               checkEqu("5.123", buf.appendMilliSec(5123).str());
+               checkEqu("32:45.789", buf.setLength(0)
+                       .appendMilliSec(32*60*1000+45789).str());
+               checkEqu("17:04:06.976", buf.setLength(0)
+                       .appendMilliSec(17*3600*1000 + 4*60*1000 + 6976).str());
+       }
        void testSetDelta(){
                ReByteBuffer buf("abcd");
                int maxDelta = 512 * (1 << 10);
@@ -220,15 +236,15 @@ private:
                checkEqu("123ab", buffer.buffer());
                checkEqu(5u, buffer.length());
 
-               buffer.setLengthAndFill(8, 'x');
+               buffer.setLengthAndFillOut(8, 'x');
                checkEqu("123abxxx", buffer.buffer());
                checkEqu(8u, buffer.length());
                buffer.setLength(3);
                checkEqu("123", buffer.buffer());
                checkEqu(3u, buffer.length());
 
-               buffer.setLengthAndFill(511, 'y');
-               buffer.setLengthAndFill(512, 'z');
+               buffer.setLengthAndFillOut(511, 'y');
+               buffer.setLengthAndFillOut(512, 'z');
                checkEqu("yyz", buffer.buffer() + 509);
                checkEqu(521u, buffer.capacity());
 
@@ -339,7 +355,7 @@ private:
                checkEqu("01234", buf1.str());
                checkEqu(5u, buf1.length());
 
-               buf1.setLengthAndFill(8, 'X');
+               buf1.setLengthAndFillOut(8, 'X');
                checkEqu("01234XXX", buf1.str());
                checkEqu(8u, buf1.length());
                checkEqu(2000u, buf1.capacity());
index 566e4e57778948b2a1c7b5d29018ddbf9fce6b1c..473e2598aa638c34edb1cdebf0a6f10ddd19d519 100644 (file)
@@ -7,9 +7,8 @@ public:
        }
 private:
        void run(){
-               createTestDir();
                ReByteBuffer dir;
-               dir.set(getTestDir(), -1);
+               dir.set(testDir(), -1);
                ReByteBuffer file1 = dir;
                file1.append("abc.1.txt", -1);
                createFile(file1.str(), "abc1");
diff --git a/cunit/cuReHashList.cpp b/cunit/cuReHashList.cpp
new file mode 100644 (file)
index 0000000..3df7c16
--- /dev/null
@@ -0,0 +1,74 @@
+#include "base/rebase.hpp"
+#include "math/remath.hpp"
+
+class TestReHashList : public ReTestUnit {
+public:
+       TestReHashList() : ReTestUnit("ReHashList", __FILE__){
+               run();
+       }
+private:
+       void run(){
+               testBasic();
+               testNext();
+       }
+       void massTest(){
+               ReCongruentialGenerator rand;
+               ReHashList hash();
+               ReByteBuffer key, value;
+               log(false, "missing masstest");
+       }
+       void testBasic(){
+               ReHashList hash;
+               ReByteBuffer key, value;
+
+               hash.put("abc", "123");
+               checkT(hash.get("abc", -1, value));
+               checkEqu("123", value.str());
+
+               hash.put("ab", "999");
+               checkT(hash.get("ab", -1, value));
+               checkEqu("999", value.str());
+
+               checkT(hash.get("abc", -1, value));
+               checkEqu("123", value.str());
+
+               hash.put("abc", "!!!");
+               checkT(hash.get("abc", -1, value));
+               checkEqu("!!!", value.str());
+
+               checkT(hash.get("ab", -1, value));
+               checkEqu("999", value.str());
+
+               hash.put("abc", "longer");
+               checkT(hash.get("abc", -1, value));
+               checkEqu("longer", value.str());
+
+               checkT(hash.get("ab", -1, value));
+               checkEqu("999", value.str());
+       }
+       void testNext(){
+               ReHashList hash;
+               hash.put("4", "2");
+               hash.put("1", "8");
+               hash.put("2", "4");
+               hash.put("8", "1");
+               int flagsKey = 0;
+               int flagsVal = 0;
+               ReArrayPosition pos;
+               ReByteBuffer key, value;
+               while(hash.next(pos, &key, &value)){
+                       int x = atol(key.buffer());
+                       int y = atol(value.buffer());
+                       checkEqu(8, x * y);
+                       flagsKey += x;
+                       flagsVal += y;
+               }
+               checkEqu(15, flagsKey);
+               checkEqu(15, flagsVal);
+       }
+};
+extern void testReHashList(void);
+
+void testReHashList(void){
+       TestReHashList unit;
+}
index 46810844d1391ecdf7ca7d2afa4e8962ee86450d..075cc3290691481e02340264f46817ccc0966d66 100644 (file)
@@ -25,6 +25,36 @@ private:
         } catch (ReOptionException& exc) {
             checkEqu("Unknown option: v", exc.getMessage());
         }
+    }
+    void createExpectedShortHelp(const char* filename){
+               createFile(filename,
+"test <opts> <args>This tests the usage of ReProgramArg\n"
+"This tests the usage of ReProgramArg\n"
+"\n"
+"<options>:\n"
+"-B  or --boolval2\n"
+"   This is the 2nd boolean arg\n"
+"-x  or --boolval3\n"
+"   This is the 3rd boolean arg\n"
+"-Y  or --boolval4\n"
+"   This is the 4th boolean arg\n"
+"-S[<string>]  or --estring=[<string>] Default value: empty\n"
+"   This string may be empty\n"
+"-U[<string>]  or --estring2=[<string>] Default value: undef2\n"
+"   This 2nd string may be empty\n"
+"-i<number>  or --intval=<number> Default value: 9\n"
+"   This is an integer arg\n"
+"-I<number>  or --intval=<number> Default value: 1000\n"
+"   This is the 2nd integer arg\n"
+"-s<not empty string>  or --string=<not empty string> Default value: 'abc'\n"
+"   This string must be non empty\n"
+"-u<not empty string>  or --string2=<not empty string> Default value: 'undef'\n"
+"   This 2nd string must be non empty\n"
+"Example(s):\n"
+"$0 -b+ -B- file dir\ttest of an exampl+++ Not really an error!\n"
+"\ttest of an exampl+++ Not really an error!\n"
+"+++ Not really an error!\n"
+               );
     }
        void testShort(){
                ReProgramArgs args("test <opts> <args>\nThis tests the usage of ReProgramArgs",
@@ -67,8 +97,17 @@ private:
                checkEqu("arg1", args.getArg(0));
                checkEqu("arg2", args.getArg(1));
                checkEqu(2, args.getArgCount());
-
-               args.help("Not really an error!", false, stdout);
+               ReByteBuffer fn;
+               FILE* fp = fopen(buildFilename("help.tmp.txt", fn), "w");
+               checkF(fp == NULL);
+               if (fp != NULL){
+                       args.help("Not really an error!", false, fp);
+                       fclose(fp);
+                       ReByteBuffer fnExpected;
+                       buildFilename("help.exp.txt", fnExpected);
+                       createExpectedShortHelp(fnExpected.str());
+                       checkFileEqu(fnExpected.str(), fn.str());
+               }
        }
     void testSetUsage(){
         class MyArgs : public ReProgramArgs {
@@ -82,6 +121,32 @@ private:
         args.setUsage(usage);
         checkEqu("x1", args.usage().strOf(0));
         checkEqu("x2", args.usage().strOf(1));
+    }
+    void createExpectedLongHelp(const char* filename){
+               createFile(filename,
+"test <opts> <argsThis tests the usage of ReProgramArg\n"
+"This tests the usage of ReProgramArg\n"
+"\n"
+"<options>:\n"
+"--boolval2\n"
+"   This is the 2nd boolean arg\n"
+"-x  or --boolval3\n"
+"   This is the 3rd boolean arg\n"
+"--boolval4\n"
+"   This is the 3rd boolean arg\n"
+"--estring=[<string>] Default value: empty\n"
+"   This string may be empty\n"
+"-U[<string>]  or --estring2=[<string>] Default value: undef2\n"
+"   This 2nd string may be empty\n"
+"-V[<string>]  or --estring3=[<string>] Default value: undef3\n"
+"   This 3thrd string may be empty\n"
+"-i<number>  or --intval=<number> Default value: 9\n"
+"   This is an integer arg\n"
+"-s<not empty string>  or --string=<not empty string> Default value: 'abc'\n"
+"   This string must be non empty\n"
+"Example(s):\n"
+"test -intval=10 --boolval=t\n"
+                       );
     }
        void testLong(){
                const char* call[] = {
@@ -125,7 +190,16 @@ private:
                checkEqu("arg1", args.getArg(0));
                checkEqu("arg2", args.getArg(1));
                checkEqu(2, args.getArgCount());
-               args.help(NULL, false, stdout);
+               ReByteBuffer fn;
+               FILE* fp = fopen(buildFilename("help.tmp.txt", fn), "w");
+               checkT(fp != NULL);
+               if (fp){
+                       args.help(NULL, false, fp);
+                       fclose(fp);
+                       ReByteBuffer fnExpected;
+                       createExpectedLongHelp(buildFilename("help.exp.txt", fnExpected));
+                       checkFileEqu(fnExpected.str(), fn.str());
+               }
        }
 };
 extern void testReProgramArgs(void);
diff --git a/cunit/cuReRandomizer.cpp b/cunit/cuReRandomizer.cpp
new file mode 100644 (file)
index 0000000..7d2285c
--- /dev/null
@@ -0,0 +1,49 @@
+#include "base/rebase.hpp"
+#include "math/remath.hpp"
+
+class TestReRandomizer : public ReTestUnit {
+public:
+       TestReRandomizer() :
+               ReTestUnit("ReRandomizer", __FILE__)
+       {
+               run();
+       }
+private:
+       void run(){
+               testNextInt64Repeater();
+               testNextInt64();
+
+       }
+       void testNextInt64Repeater(){
+               ReCongruentialGenerator rand;
+               const int MAX = 16;
+               time_t start = time(NULL);
+               ReRandomizer::seed_t field[MAX];
+               for (int ix = 0; ix < MAX; ix++)
+                       field[ix] = rand.nextInt64();
+               rand.reset();
+               for (int ix = 0; ix < MAX; ix++){
+                       checkEqu(field[ix], rand.nextInt64(ix + 10));
+               }
+       }
+       void testNextInt64(){
+               ReCongruentialGenerator rand;
+               const int MAX = 16;
+               time_t start = time(NULL);
+               ReRandomizer::seed_t field[MAX];
+               for (int ix = 0; ix < MAX; ix++)
+                       field[ix] = rand.nextInt64(ix + 10);
+               rand.reset();
+               for (int ix = 0; ix < MAX; ix++){
+                       checkEqu(field[ix], rand.nextInt64(ix + 10));
+                       checkT(field[ix] >= 0 && field[ix] < ix + 10);
+               }
+               time_t diff = time(NULL) - start;
+       }
+};
+extern void testReRandomizer(void);
+
+void testReRandomizer(void){
+       TestReRandomizer unit;
+}
+
index a4baf0083bf8e4ed06e19e07cbf35d688610403c..9da0d4da04c25a523b231ecb416b7ec404252ec9 100644 (file)
@@ -148,9 +148,8 @@ private:
        }
        void testFile(){
                if (true){
-                       createTestDir();
                        ReByteBuffer file;
-                       file.set(getTestDir(), -1).append("abc.csv", -1);
+                       buildFilename("abc.csv", file);
 
                        ReStringList list;
                        const char* str = "1;abc;xyz;4;;99";
@@ -159,6 +158,20 @@ private:
 
                        ReStringList list2;
                        list2.readFromFile(file.str(), true);
+                       checkEqu("1", list2.strOf(0));
+                       checkEqu("abc", list2.strOf(1));
+                       checkEqu("xyz", list2.strOf(2));
+                       checkEqu("4", list2.strOf(3));
+                       checkEqu("", list2.strOf(4));
+                       checkEqu("99", list2.strOf(5));
+                       list2.clear();
+                       list2.readFromFile(file.str(), false);
+                       checkEqu("1", list2.strOf(0));
+                       checkEqu("abc", list2.strOf(1));
+                       checkEqu("xyz", list2.strOf(2));
+                       checkEqu("4", list2.strOf(3));
+                       checkEqu("", list2.strOf(4));
+                       checkEqu("99", list2.strOf(5));
 
                        checkEqu(-1, list2.firstDiff(list2));
                }
index 2f7766bf4636f79544b19a86ac2bb1a0741fbc3a..15bec42b316b671d87c7376ced7206f2486744a7 100644 (file)
@@ -7,10 +7,29 @@ public:
        }
 private:
        void run(){
+               testFileNameInTestDir();
+               testTimer();
                testBasic();
                testColMarker();
                testEquFiles();
        }
+       void testFileNameInTestDir(){
+               ReByteBuffer fn;
+               const char* name = buildFilename("xyz.txt", fn);
+               checkEqu(name, fn.str());
+               checkT(fn.endsWith("xyz.txt"));
+               checkT(fn.startsWith(testDir()));
+       }
+       void testTimer(){
+               int64_t start = timer();
+               // busy wait (clock() measures only busy times):
+               time_t to = time(NULL) + 1;
+               while(time(NULL) <= to){
+                       // do nothing
+               }
+               int duration = milliSecSince(start);
+               checkT(duration >= 1000 && duration < 3000);
+       }
        void testBasic(){
                checkT(true);
                checkF(false);
@@ -36,16 +55,14 @@ private:
                log(false, "end of 8 expected errors");
        }
        void testColMarker(){
-               checkEqu("--^", colMarker(2));
+               checkEqu("-^", colMarker(2));
                checkEqu("^", colMarker(0));
        }
        void testEquFiles(){
-               createTestDir();
-               ReByteBuffer dir = getTestDir();
-               ReByteBuffer fn1(dir);
-               fn1.append("x1.txt");
-               ReByteBuffer fn2(dir);
-               fn2.append("x2.txt");
+               ReByteBuffer fn1;
+               buildFilename("x1.txt", fn1);
+               ReByteBuffer fn2;
+               buildFilename("x2.txt", fn2);
                createFile(fn1.str(), "123\nline 2");
                createFile(fn2.str(), "123\nline 2");
                checkFileEqu(fn1.str(), fn2.str());
index 9314d9fca9e8f47a841c2329e061d3df610fcea0..f64406f14c4f4e57f803d7fe6f7036097c166c21 100644 (file)
@@ -13,8 +13,7 @@ static const char* s_empty[] = { NULL };
 class TestReTraverser : public ReTestUnit {
 public:
        TestReTraverser() : ReTestUnit("ReTraverser", __FILE__){
-        createTestDir();
-        m_base = getTestDir();
+        m_base = testDir();
         m_base.append("traverser").append(ReTraverser::m_separatorStr, -1);
         _mkdir(m_base.str());
                run();
@@ -70,7 +69,7 @@ private:
     void testCopyFile(){
         ReByteBuffer src(m_base);
         src.append("dir1/dir1_2/dir1_2_1/x1.txt");
-        ReByteBuffer trg(getTestDir());
+        ReByteBuffer trg(testDir());
         trg.append("copy_x1.txt");
         ReByteBuffer buffer;
                buffer.ensureSize(5);
index 94c22cd986e0d0bf85fa1cb0aac0585de5fb4264..4ee28850b849e035d127b8e7276ce1353691390e 100644 (file)
@@ -11,9 +11,8 @@ private:
                testBasic();
        }
        void testBasic(){
-               createTestDir();
                ReByteBuffer fn;
-               fn.append(getTestDir(), -1).append("reconfigfile.cfg", -1);
+               buildFilename("reconfigfile.cfg", fn);
                createFile(fn.str(), "#x.int=a\nx.int=1\nx.bool=true\nx.str=abc\nx.bool2=0\nstring=abc\n");
                ReConfigFile config(fn.str());
                checkT(config.isValid());
index 7ce041eb529d21e0c9c0f561e8c4f348e91234a1..961541a7d1953b6ba7edd4b4c040095ffc078d1d 100644 (file)
@@ -11,9 +11,6 @@
 #endif
 
 void testBase(){
-       extern void testReLogger(void);
-       testReLogger();
-       testReLogger();
 
        extern void testReTestUnit();
        testReTestUnit();
@@ -58,13 +55,18 @@ void testString(){
 }
 void testOs(){
        void testReTraverser();
-       testReTraverser();
+       //testReTraverser();
+}
+void testMath(){
+       extern void testReRandomizer();
+       testReRandomizer();
 }
 void testAll(){
        try
        {
-               testOs();
                testBase();
+               testMath();
+               testOs();
                testString();
        } catch (ReException e){
                fprintf(stderr, "testBase.cpp: unexpected exception: %s\n", e.getMessage());
index 552b750fb6a06a0a96281200dac86a66b8c9fcbe..233c500476289ff1231749ce79496f0291d9edfd 100644 (file)
@@ -5,17 +5,16 @@
  *      Author: wk
  */
 
-#include "assert.h"
-#include "memory.h"
-#include "limits.h"
-#include "math.h"
-#include "remath.hpp"
+
+#include "base/rebase.hpp"
+#include "math/remath.hpp"
 
 static bool s_trace = false;
 /**
  * @brief Constructor.
  */
-ReRandomizer::ReRandomizer(){
+ReRandomizer::ReRandomizer()
+{
 }
 /**
  * @brief Destructor.
@@ -38,16 +37,69 @@ char ReRandomizer::nextChar()
        return rc;
 }
 
+/**
+ * @brief Returns a random number which is not predictable.
+ *
+ * @return a number which is not predictable
+ */
+ReRandomizer::seed_t ReRandomizer::nearTrueRandom(){
+       time_t random = time(NULL);
+       static int dummy = 5;
+       void* dummy2 = malloc(1);
+       free(dummy2);
+       seed_t rc = (((seed_t) random) << 31) + ((seed_t) &dummy << 9) + (-random ^ 0x20111958)
+               ^ (seed_t(dummy2));
+#if defined __linux__
+       int fh = open("/dev/urandom", O_RDONLY);
+       char buffer[sizeof (seed_t)];
+       size_t length = 0;
+
+       if (read(fh, buffer, sizeof buffer) > 0)
+               rc ^= *(seed_t*) buffer;
+       close(fh);
+#else
+#error "no true random"
+#endif
+}
 /**
  * @brief Returns the next random integer.
  *
  *
+ * @param maxValue     The maximum of the result (including).
  * @param minValue     The minimum of the result.
+ *
+ * @return The next seed.
+ */
+int ReRandomizer::nextInt(int maxValue, int minValue){
+       int rc;
+       if (minValue > maxValue){
+               rc = minValue;
+               minValue = maxValue;
+               maxValue = rc;
+       }
+       seed_t seed = nextSeed();
+       if (minValue == maxValue)
+               rc = minValue;
+       else
+               // we calculate in 64 bit:
+               rc = (int) (minValue + seed % (maxValue - minValue + 1));
+       if (s_trace){
+               static int count = 0;
+               printf ("%c %8x ", count++ % 4 == 0 ? '\n' : ' ', rc);
+       }
+       return rc;
+}
+
+/**
+ * @brief Returns the next random integer.
+ *
+ *
  * @param maxValue     The maximum of the result (including).
+ * @param minValue     The minimum of the result.
  *
  * @return The next seed.
  */
-int ReRandomizer::nextInt(int minValue, int maxValue){
+int64_t ReRandomizer::nextInt64(int64_t maxValue, int64_t minValue){
        int rc;
        if (minValue > maxValue){
                rc = minValue;
@@ -57,17 +109,19 @@ int ReRandomizer::nextInt(int minValue, int maxValue){
        seed_t seed = nextSeed();
        if (minValue == maxValue)
                rc = minValue;
-       else if (minValue == 0 && maxValue == INT_MAX)
+       else if (minValue == 0 && maxValue == LLONG_MAX)
                rc = abs(seed);
-       else if (unsigned(maxValue - minValue) < INT_MAX)
+       else if (uint64_t(maxValue - minValue) < LLONG_MAX)
+               // no signed int64 overflow:
                rc = minValue + seed % (maxValue - minValue + 1);
        else {
+               // int64 overflow: we need a higher precision:
                double rc2 = minValue + fmod((double) seed, maxValue - minValue);
                rc = (int) rc2;
        }
        if (s_trace){
                static int count = 0;
-               printf ("%c %8x ", count++ % 4 == 0 ? '\n' : ' ', rc);
+               printf ("%c %16llx ", count++ % 4 == 0 ? '\n' : ' ', rc);
        }
        return rc;
 }
@@ -101,6 +155,7 @@ char* ReRandomizer::nextString(char* buffer, int maxLength, int minLength){
        buffer[len] = '\0';
        return buffer;
 }
+
 /**
  * @brief Builds a random permutation of an array.
  *
@@ -162,7 +217,8 @@ void ReRandomizer::shuffle(void* array, size_t length, size_t elemSize){
 ReCongruentialGenerator::ReCongruentialGenerator() :
        m_seed(0x4711),
        m_factor(2631),
-       m_increment(0x9)
+       m_increment(0x9),
+       m_lastSetSeed(0x4711)
 {
 }
 /**
@@ -176,7 +232,7 @@ ReCongruentialGenerator::~ReCongruentialGenerator(){
  *
  * @return The current factor.
  */
-ReRandomizer::seed_t ReCongruentialGenerator::getFactor() const
+ReRandomizer::seed_t ReCongruentialGenerator::factor() const
 {
     return m_factor;
 }
@@ -186,7 +242,7 @@ ReRandomizer::seed_t ReCongruentialGenerator::getFactor() const
  *
  * @return The current increment.
  */
-ReRandomizer::seed_t ReCongruentialGenerator::getIncrement() const
+ReRandomizer::seed_t ReCongruentialGenerator::increment() const
 {
     return m_increment;
 }
@@ -196,11 +252,20 @@ ReRandomizer::seed_t ReCongruentialGenerator::getIncrement() const
  *
  * @return The current seed.
  */
-ReRandomizer::seed_t ReCongruentialGenerator::getSeed() const
+ReRandomizer::seed_t ReCongruentialGenerator::seed() const
 {
     return m_seed;
 }
 
+/**
+ * @brief Sets the seed to the value given by the last <code>setSeed()</code>.
+ *
+ * Note: The constructor does the first <code>setSeed()</code>.
+ */
+void ReCongruentialGenerator::reset(){
+       m_seed = m_lastSetSeed;
+}
+
 /**
  * Sets the factor.
  *
@@ -227,8 +292,8 @@ void ReCongruentialGenerator::setIncrement(seed_t increment)
  */
 void ReCongruentialGenerator::setSeed(seed_t seed)
 {
-    this->m_seed = seed;
+    m_seed = m_lastSetSeed = seed;
     if (s_trace)
-       printf(" Seed: %x ", seed);
+       printf(" Seed: %llx ", seed);
 }
 
index 958649b9cefd636f78d8c366e335d9538a3f508e..32f0812104a953b99288f2845e259d00b0169fcf 100644 (file)
@@ -7,44 +7,53 @@
 
 #ifndef RANDOMIZER_H_
 #define RANDOMIZER_H_
-#include "stdio.h"
-#include "limits.h"
 
 /**
  * This implements an abstract base class for random generators.
  */
 class ReRandomizer {
 public:
-       enum { CHARRANGE = 128 - ' ' };
-       typedef unsigned int seed_t;
+       enum { START_RANGE = ' ',
+               CHARRANGE = 128 - START_RANGE };
+       typedef uint64_t seed_t;
 public:
        ReRandomizer();
        virtual ~ReRandomizer();
 public:
-       virtual int nextInt(int minValue = 0, int maxValue = INT_MAX);
-       void shuffle(void* array, size_t length, size_t elemSize);
+       virtual int nextInt(int maxValue = INT_MAX, int minValue = 0);
+       virtual int64_t nextInt64(int64_t maxValue = LLONG_MAX, int64_t minValue = 0);
        char nextChar();
        char* nextString(char* buffer, int maxLength = 80, int minLength = 0);
+       void shuffle(void* array, size_t length, size_t elemSize);
+       /** @brief Sets the instance to a defined start state.
+        */
+       virtual void reset() = 0;
 protected:
+       /** @brief Returns the next pseudo random number.
+        * @return the next pseudo random number
+        * */
     virtual seed_t nextSeed() = 0;
+public:
+       seed_t nearTrueRandom();
 };
 
 /**
  * Implements a simple random generator.
  * A linear congruential generator produces the next value using this formula:
  * seed = (seed * factor + increment) % modulus
- * In this implementation modulus is 2**32.
+ * In this implementation modulus is 2**64.
  */
 class ReCongruentialGenerator : public ReRandomizer {
 public:
        ReCongruentialGenerator();
        virtual ~ReCongruentialGenerator();
 public:
-    seed_t getFactor() const;
-    seed_t getIncrement() const;
+    seed_t factor() const;
+    seed_t increment() const;
+    seed_t seed() const;
+       virtual void reset();
     void setFactor(seed_t factor);
     void setIncrement(seed_t increment);
-    seed_t getSeed() const;
     void setSeed(seed_t m_seed);
 private:
        virtual seed_t nextSeed();
@@ -52,6 +61,7 @@ private:
        seed_t m_seed;
        seed_t m_factor;
        seed_t m_increment;
+       seed_t m_lastSetSeed;
 };
 
 #endif /* RANDOMIZER_H_ */
index d3b64bc0b8499b4cb05fd4599a68f4b82af091f6..d9233c39f579095f80fce567a9f72440513dfd5c 100644 (file)
@@ -7,8 +7,9 @@
 
 #ifndef REMATH_HPP_
 #define REMATH_HPP_
+#include "math.h"
 
-#include "ReObfuscator.hpp"
-#include "ReRandomizer.hpp"
+#include "math/ReObfuscator.hpp"
+#include "math/ReRandomizer.hpp"
 
 #endif /* REMATH_HPP_ */