*.o
dirtool
alltest
+.hg/
+Debug/
+.settings/
* Author: wk
*/
-#include "rebase.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 int memcmp (const void* s1, const void* s2, size_t n);
+extern int snprintf (char* s, size_t maxlen, const char* format, ...);
+#endif
/** @brief Constructor.
*
// m_primaryBuffer
m_buffer(m_primaryBuffer),
m_length(0),
- m_size(sizeof m_primaryBuffer - 1)
+ m_capacity(sizeof m_primaryBuffer - 1)
{
m_buffer[0] = '\0';
}
-/** @brief Copy constructor.
+/** @brief Constructor.
*
* @param source The instance to copy (C string).
*/
-ReByteBuffer::ReByteBuffer(const char* source)
- :
- m_delta(256),
+ReByteBuffer::ReByteBuffer(const char* source) :
+ m_delta(PRIMARY_BUFFER_SIZE),
// m_primaryBuffer
m_buffer(m_primaryBuffer),
m_length(0),
- m_size(sizeof m_primaryBuffer)
+ m_capacity(sizeof m_primaryBuffer)
{
m_buffer[0] = '\0';
append(source);
}
+
+/** @brief Constructor.
+ *
+ * @param source The byte sequence to copy
+ * @param sourceLength length of <code>source</code>
+ */
+ReByteBuffer::ReByteBuffer(const Byte* source, size_t sourceLength) :
+ m_delta(PRIMARY_BUFFER_SIZE),
+ // m_primaryBuffer
+ m_buffer(m_primaryBuffer),
+ m_length(0),
+ m_capacity(sizeof m_primaryBuffer)
+{
+ m_buffer[0] = '\0';
+ append(source, sourceLength);
+}
+
/** @brief Destructor.
*
*/
ReByteBuffer::~ReByteBuffer(){
if (m_buffer != m_primaryBuffer)
- delete m_buffer;
+ delete[] m_buffer;
m_buffer = NULL;
- m_size = 0;
+ m_capacity = 0;
m_length = 0;
}
/** @brief Copy constructor.
*/
ReByteBuffer::ReByteBuffer(const ReByteBuffer& source)
:
- m_delta(source.getDelta()),
+ m_delta(source.delta()),
// m_primaryBuffer
m_buffer(m_primaryBuffer),
m_length(0),
- m_size(sizeof m_primaryBuffer)
+ m_capacity(sizeof m_primaryBuffer)
{
- append(source.getBuffer(), source.getLength());
+ append(source.buffer(), source.length());
}
/** @brief The assignment operator.
* @return The instance itself.
*/
ReByteBuffer& ReByteBuffer::operator =(const ReByteBuffer& source){
- m_delta = source.getDelta();
- set(source.getBuffer(), source.getLength());
+ m_delta = source.delta();
+ set(source.buffer(), source.length());
return *this;
}
if (length == (size_t) -1)
length = strlen(source);
ensureSize(m_length + length);
- memcpy(m_buffer + m_length, source, length);
+ memcpy((void*)(m_buffer + m_length), source, length);
m_length += length;
m_buffer[m_length] = '\0';
return *this;
* @return *this (for chaining).
*/
ReByteBuffer& ReByteBuffer::appendInt(int number, const char* format){
- char buffer [256];
+ char buffer [128];
snprintf(buffer, sizeof buffer, format, number);
size_t length = strlen(buffer);
* @return *this (for chaining).
*/
ReByteBuffer& ReByteBuffer::append(ReByteBuffer& source){
- return append(source.getBuffer(), source.getLength());
+ return append(source.buffer(), source.length());
}
/** Converts a subsequence into an integer.
}
return rc;
}
+
+/**
+ * Counts the occurrencies of a given byte sequence.
+ *
+ * @param toCount the byte sequence to count
+ * @param lengthOfToCount -1: length is <code>strlen(toCount)</count><br>
+ * otherwise: length of <code>toCount</count>.
+ */
+int ReByteBuffer::count(const char* toCount, size_t lengthToCount){
+ int rc = 0;
+ size_t start = 0;
+ if (lengthToCount == (size_t)-1)
+ lengthToCount = strlen(toCount);
+ while( (start = indexOf(toCount, lengthToCount, start)) != (size_t) -1){
+ rc++;
+ start += lengthToCount;
+ }
+ return rc;
+}
+
+/**
+ * Tests whether the buffer ends with a given a byte sequence.
+ *
+ * @param tail the byte sequence to test
+ * @param tailLength -1: <code>strlen(tail)</code><br>
+ * otherwise: the length of <code>tail</code>
+ * @param ignoreCase <code>true</code>: the comparison is case insensitive<br>
+ * <code>false</code>: the comparison is case sensitive<br>
+ * @return <code>true</code>: the buffer ends with <code>tail</code><br>
+ * <code>false</code>: otherwise
+ */
+bool ReByteBuffer::endsWith(const Byte* tail, size_t tailLength,
+ bool ignoreCase) const {
+ bool rc;
+ if (tailLength == (size_t)-1)
+ tailLength = strlen(tail);
+ rc = indexOf(tail, tailLength, m_length - tailLength, m_length, ignoreCase) >= 0;
+ return rc;
+}
+
/** @brief Ensures that there is enough space.
*
* <p>If not it will be allocated and the old value will be copied.
* @param size At the end the size will be at least this value.
*/
void ReByteBuffer::ensureSize(size_t size){
- if (m_size < size){
- if (size - m_size < m_delta)
- size = m_size + m_delta;
+ if (m_capacity < size){
+ if (size - m_capacity < m_delta)
+ size = m_capacity + m_delta;
// Think for the ending '\0':
Byte* buffer = new Byte[size + 1];
assert(buffer != NULL);
- memcpy(buffer, m_buffer, m_length);
+ if (m_length > 0)
+ memcpy(buffer, m_buffer, m_length);
+ buffer[m_length] = '\0';
if (m_buffer != m_primaryBuffer)
delete m_buffer;
m_buffer = buffer;
- m_size = size;
+ m_capacity = size;
}
}
-/** @brief Search for a byte sequence in the internal buffer.
+/** @brief Searches for a byte sequence in the internal buffer.
+ *
+ * Finds the first occurrence of a byte sequence in a given range.
*
* <pre><code>Example:
* ReByteBuffer buf;
* @param toFind The sequence to find.
* @param toFindLength Length of <code>toFind</code>.
* If -1 the <code>strlen(toFind)</code> will be taken.
- * @param start The index of the internal buffer where the search starts.
+ * @param start The search respects the indices in the range [start, end[
+ * @param end -1: no upper limit to search<br>
+ * otherwise: the first index above the search range
+ * @param ignoreCase <code>true</code>: case insensitive search<br>
+ * <code>true</code>: case sensitive search
+ * @return -1: The sequence could not be found.
+ * Otherwise: The index of <code>toFind</code> in the internal buffer.
+ */
+int ReByteBuffer::indexOf(const Byte* toFind, size_t toFindLength, int start,
+ int end, bool ignoreCase) const{
+ if (toFindLength == (size_t) -1)
+ toFindLength = strlen(toFind);
+ int rc = -1;
+ if (end < 0 || end > (int) m_length)
+ end = m_length;
+ if (start >= 0 && start <= int(m_length - toFindLength)
+ && end >= (int) toFindLength && end <= (int) m_length){
+ while(rc < 0 && start <= int(end - toFindLength)){
+ if (ignoreCase ? strncasecmp(toFind, m_buffer + start, toFindLength) == 0
+ : memcmp(toFind, m_buffer + start, toFindLength) == 0)
+ rc = start;
+ else
+ start++;
+ }
+ }
+ return rc;
+}
+/** @brief Searches revers for a byte sequence in the internal buffer.
+ *
+ * Finds the last occurrence of a byte sequence in a given range.
*
+ * <pre><code>Example:
+ * ReByteBuffer buf;
+ * buf.set("12abc123", 8);
+ * assert(5 == buf.rindexOf("12", -1, 3));
+ * </code></pre>
+ *
+ * @param toFind The sequence to find.
+ * @param toFindLength Length of <code>toFind</code>.
+ * If -1 the <code>strlen(toFind)</code> will be taken.
+ * @param start The search respects the indices in the range [start, end[
+ * @param end -1: no upper limit to search<br>
+ * otherwise: the first index above the search range
+ * @param ignoreCase <code>true</code>: case insensitive search<br>
+ * <code>true</code>: case sensitive search
* @return -1: The sequence could not be found.
* Otherwise: The index of <code>toFind</code> in the internal buffer.
*/
-int ReByteBuffer::indexOf(const Byte* toFind, size_t toFindLength, int start) const{
+int ReByteBuffer::rindexOf(const Byte* toFind, size_t toFindLength, int start,
+ int end, bool ignoreCase) const{
if (toFindLength == (size_t) -1)
toFindLength = strlen(toFind);
int rc = -1;
- while(rc < 0 && start <= int(m_length - toFindLength)){
- if (memcmp(toFind, m_buffer + start, toFindLength) == 0)
- rc = start;
- else
- start++;
+ if (end < 0 || end > (int) m_length)
+ end = m_length;
+ if (start >= 0 && start <= int (m_length - toFindLength)
+ && end >= (int) toFindLength && end <= (int) m_length){
+ int current = end - toFindLength;
+ while(current >= start){
+ if (ignoreCase ? strncasecmp(toFind, m_buffer + current, toFindLength) != 0
+ : memcmp(toFind, m_buffer + current, toFindLength) != 0)
+ current--;
+ else{
+ rc = current;
+ break;
+ }
+ }
}
return rc;
}
}
return rc;
}
+/**
+ * Tests whether the buffer starts with a given a byte sequence.
+ *
+ * @param head the byte sequence to test
+ * @param headLength -1: <code>strlen(tail)</code><br>
+ * otherwise: the length of <code>tail</code>
+ * @param ignoreCase <code>true</code>: the comparison is case insensitive<br>
+ * <code>false</code>: the comparison is case sensitive<br>
+ * @return <code>true</code>: the buffer starts with <code>head</code><br>
+ * <code>false</code>: otherwise
+ */
+bool ReByteBuffer::startsWith(const Byte* head, size_t headLength, const bool ignoreCase) const{
+ bool rc;
+ if (headLength == (size_t) -1)
+ headLength = strlen(head);
+ rc = indexOf(head, headLength, 0, headLength, ignoreCase) == 0;
+ return rc;
+}
#ifndef REBYTEBUFFER_H_
#define REBYTEBUFFER_H_
+#define PRIMARY_BUFFER_SIZE 512
+
/** @brief An efficient dynamic memory buffer.
*
* Implements a very efficient dynamic byte sequence.
public:
typedef char Byte;
public:
- ReByteBuffer(size_t delta = 512);
+ ReByteBuffer(size_t delta = PRIMARY_BUFFER_SIZE);
ReByteBuffer(const char* source);
+ ReByteBuffer(const Byte* source, size_t sourceLength);
virtual ~ReByteBuffer();
ReByteBuffer(const ReByteBuffer& source);
ReByteBuffer& operator =(const ReByteBuffer& source);
return index >= m_length ? 0 : m_buffer[index];
}
int atoi(size_t start = 0, int end = -1) const;
+ bool endsWith(const Byte* tail, size_t tailLength = -1,
+ bool ignoreCase = false) const;
void ensureSize(size_t size);
/** @brief Returns the buffer.
* @return The internal used buffer.
*/
- inline Byte* getBuffer() const{
+ inline Byte* buffer() const{
return m_buffer;
}
/**@brief Returns the minimum allocation unit.
* @return The minimum of bytes to allocate.
*/
- inline size_t getDelta() const{
+ inline size_t delta() const{
return m_delta;
}
+ int count(const char* toCount, size_t lengthToCount = -1);
/**@brief Returns the length of the buffer (the count of used bytes).
* @return The count of the allocated bytes in the internal buffer.
*/
- inline size_t getLength() const{
+ inline size_t length() const{
return m_length;
}
/**@brief Returns the current size of the internal buffer.
* @return The current size of the internal buffer.
*/
- inline size_t getSize() const{
- return m_size;
+ inline size_t capacity() const{
+ return m_capacity;
}
/** @brief Finds the index of the first occurrence of a given byte.
* @param toFind This byte will be searched.
return start - 1;
return -1;
}
- int indexOf(const Byte* toFind, size_t toFindLength, int start = 0) const;
+ int indexOf(const Byte* toFind, size_t toFindLength,
+ int start = 0, int end = -1, bool ignoreCase = false) const;
/** @brief Inserts a byte sequence.
* @param ix The position in the internal buffer for the insertion.
* @param source The sequence to insert.
return start + 1;
return -1;
}
+ int rindexOf(const Byte* toFind, size_t toFindLength,
+ int start = 0, int end = -1, bool ignoreCase = false) const;
/** @brief Sets the content of the buffer by copying a byte sequence.
* @param source The byte sequence to copy.
* @param length The length of <code>source</code>.
ReByteBuffer& setLengthAndFill(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;
+
/** @brief Returns the buffer content as C string.
* This is exactly the same result as from <code>getBuffer()</code>.
* @return The internal used buffer.
// The minimum difference between old and new size after a new allocation.
size_t m_delta;
//@ If the needed space is small enough this buffer will be used.
- char m_primaryBuffer[512];
+ char m_primaryBuffer[PRIMARY_BUFFER_SIZE];
//@ The internal buffer. Points to <code>m_primaryBuffer</code> if the space is small enough.
char* m_buffer;
//@ The used bytes in <code>m_buffer</code>.
size_t m_length;
//@ The size of <code>m_buffer</code>.
- size_t m_size;
+ size_t m_capacity;
};
#endif /* REBYTEBUFFER_H_ */
* Author: wk
*/
-#include "../base/restring.hpp"
+#include "base/rebase.hpp"
/** @brief Replaces a substring by another.
*
if (lengthTail + lengthNew - lengthReplaced > bufferSize)
globalLogger()->sayF(LOG_ERROR|GRAN_USER|CAT_LIB, LC_CSTRING_REPLACE_1,
i18n("+++ The name size exceeds: $1 / $2\n"))
- .arg(int(lengthTail + lengthNew - lengthReplaced)).arg((int) bufferSize)
+ .arg(int(lengthTail + lengthNew - lengthReplaced))
+ .arg((int) bufferSize)
.end();
else {
memmove(start + lengthNew, tail, lengthTail);
* @brief Configuration file handling for *.ini files.
*/
-#include "rebase.hpp"
+#include "base/rebase.hpp"
const char* ReConfigFile::m_trueValues = i18nm(";true;t;1;j;ja;yes;");
const char* ReConfigFile::m_falseValues = i18nm(";false;f;0;n;nein;no;");
bool ReConfigFile::getBool(const char* key, bool defaultVal){
ReByteBuffer value;
getString(key, value, NULL);
- int rc = defaultVal;
+ bool rc = defaultVal;
if (ReStringUtils::isInList(value.str(), i18n(m_falseValues)))
rc = false;
else if (ReStringUtils::isInList(value.str(), i18n(m_trueValues)))
.arg(i18n(m_trueValues)).end();
return rc;
}
-
-#if defined RE_TESTUNIT
-class TestReConfigFile : public ReTestUnit {
- typedef ReHashList::Byte Byte;
-public:
- TestReConfigFile() : ReTestUnit("ReConfigFile", __FILE__){
- run();
- }
-private:
- void run(){
- testBasic();
- }
- void testBasic(){
- createTestDir();
- ReByteBuffer fn;
- fn.append(getTestDir(), -1).append("reconfigfile.cfg", -1);
- 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());
- checkEqu(1, config.getInteger("x.int", 2));
- checkEqu(2, config.getInteger("x.int2", 2));
-
- checkT(config.getBool("x.bool", true));
- checkT(config.getBool("x.bool", false));
- checkT(config.getBool("y.bool", true));
- checkF(config.getBool("y.bool", false));
-
- checkF(config.getBool("x.bool2", true));
- checkF(config.getBool("x.bool2", false));
-
- ReByteBuffer buffer;
- config.getString("string", buffer, "x");
- checkEqu("abc", buffer.str());
- config.getString("string1", buffer, "x");
- checkEqu("x", buffer.str());
- }
-};
-extern void testReConfigFile(void);
-
-void testReConfigFile(void){
- TestReConfigFile unit;
-}
-#endif /*RE_TESTUNIT*/
* Author: wk
*/
-#include "rebase.hpp"
-
+#include "base/rebase.hpp"
/** @brief Constructor.
*/
-ReDirectory::ReDirectory()
- :
+ReDirectory::ReDirectory() :
m_valid(false),
- m_dir(NULL),
m_path(),
+ m_pattern(),
+#if defined __linux__
+ m_dir(NULL),
m_entry(NULL),
- m_pattern(),
- m_isRegExpr(false),
- m_regExprFlags(0)
+ // m_regExpr
+ m_regExprFlags(0),
+ m_regExprIsInitialized(false),
+ m_isRegExpr(false)
+#elif defined __WIN32__
+ m_handle(0)
+ //m_data()
+#endif
{
}
/** @brief Constructor.
*
* @param path The path of the directory.
*/
-ReDirectory::ReDirectory(const char* path)
- :
+ReDirectory::ReDirectory(const char* path) :
m_valid(false),
- m_dir(NULL),
m_path(),
- m_entry(NULL),
m_pattern(),
- m_isRegExpr(false),
- m_regExprFlags(0)
+#if defined __linux__
+ m_dir(NULL),
+ m_entry(NULL),
+ // m_regExpr
+ m_regExprFlags(0),
+ m_regExprIsInitialized(false),
+ m_isRegExpr(false)
+#elif defined __WIN32__
+ m_handle(0)
+ //m_data()
+#endif
{
+#if defined __linux__
+ memset(&m_regExpr, 0, sizeof m_regExpr);
+#endif
setDir(path);
}
/** @brief Destructor.
*/
ReDirectory::~ReDirectory(){
+#if defined __linux__
if (m_dir != NULL){
closedir(m_dir);
m_dir = NULL;
m_valid = false;
}
+ if (m_regExprIsInitialized)
+ regfree(&m_regExpr);
+#elif defined __WIN32__
+#endif
}
/** @brief Sets the directory.
*
* @param path The name of the directory.
*/
void ReDirectory::setDir(const char* path){
+ m_path.set(path, -1);
+#if defined __linux__
if (m_dir != NULL){
closedir(m_dir);
m_dir = NULL;
}
m_entry = NULL;
- m_path.set(path, -1);
m_dir = opendir(path);
m_valid = m_dir != NULL;
if (m_valid){
- if (m_path.at(m_path.getLength() - 1) != ReStringUtils::pathSeparator())
+ if (m_path.at(m_path.length() - 1) != ReStringUtils::pathSeparator())
m_path.append(ReStringUtils::pathSeparatorStr(), 1);
}
+#elif defined __WIN32__
+ struct stat info;
+ m_valid = stat(path, &info) == 0 && S_ISDIR(info.st_mode);
+#endif
}
/** @brief Returns the name of the directory.
*
* @return The name of the directory.
*/
const char* ReDirectory::getDir(void) const {
- return m_path.getBuffer();
+ return m_path.buffer();
}
/** @brief Tests whether the directory state is valid.
* @param flags Usefull flags are: REG_ICASE: ignore case.
*/
void ReDirectory::setRegExprFlags(int flags){
+#if defined __linux__
m_regExprFlags = flags;
+#endif
}
/** @brief Find the first file with a given filename pattern.
if (m_valid){
m_pattern.set(pattern, -1);
m_isRegExpr = isRegExpr;
+#if defined __linux__
if (isRegExpr){
+ if (m_regExprIsInitialized)
+ regfree(&m_regExpr);
int rc2 = regcomp(&m_regExpr, pattern, m_regExprFlags);
+ m_regExprIsInitialized = true;
if (rc2 != 0){
rc = false;
m_entry = NULL;
rc = findNext();
}
+#elif defined __WIN32__
+ m_handle = FindFirstFileA(pattern, &m_data);
+ rc = m_handle != INVALID_HANDLE_VALUE;
+#endif
}
return rc;
}
bool ReDirectory::findNext(){
bool rc = false;
if (m_valid){
+#if defined __linux__
while (! rc && (m_entry = readdir(m_dir)) != NULL){
if (m_isRegExpr){
regmatch_t match[10];
rc = true;
}
}
+#elif defined __WIN32__
+ if (m_handle != INVALID_HANDLE_VALUE)
+ rc = FindNextFileA(m_handle, &m_data) != 0;
+#endif
}
return rc;
}
bool ReDirectory::findYoungest(ReByteBuffer& filename){
bool rc = false;
filename.setLength(0);
+ ReByteBuffer fullname;
+
+#if defined __linux__
if (m_entry != NULL)
{
- ReByteBuffer fullname;
- fullname.append(m_path);
- size_t length = fullname.getLength();
- struct stat info;
+ fullname.append(m_path);
+ size_t length = fullname.length();
+ struct stat info;
timespec youngest;
youngest.tv_sec = youngest.tv_nsec = 0;
do{
} while(findNext());
}
+#elif defined __WIN32__
+ FILETIME youngest;
+ memset(&youngest, 0, sizeof youngest);
+ do{
+ if (m_data.ftLastWriteTime.dwHighDateTime > youngest.dwHighDateTime
+ || m_data.ftLastWriteTime.dwHighDateTime == youngest.dwHighDateTime
+ && m_data.ftLastWriteTime.dwLowDateTime > youngest.dwLowDateTime){
+ youngest = m_data.ftLastWriteTime;
+ filename.set(m_data.cFileName, -1);
+ rc = true;
+ }
+
+ } while(findNext());
+#endif
return rc;
}
/** @brief Returns the name of the current file found by the last <code>findFirst()</code>
*
*/
const char* ReDirectory::currentFile(){
+#if defined __linux__
const char* rc = m_entry == NULL ? NULL : m_entry->d_name;
- return rc;
+#elif defined __WIN32__
+ const char* rc = m_data.cFileName;
+#endif
+ return rc;
}
/** @brief Returns the full path of the current file or a given node.
*
ReByteBuffer& ReDirectory::fullpath(ReByteBuffer& path, const char* name){
path.setLength(0);
if (name != NULL){
- path.append(m_path);
+ path.set(m_path.str(), m_path.length());
path.append(name, -1);
- } else if (m_valid && m_entry != NULL){
- path.append(m_path);
- path.append(m_entry->d_name, -1);
+ } else if (m_valid){
+#if defined __linux__
+ if (m_entry != NULL){
+ path.append(m_path);
+ path.append(m_entry->d_name, -1);
+ }
+#elif defined __WIN32__
+ path.set(m_path.str(), m_path.length());
+ path.append(m_data.cFileName, -1);
+#endif
}
return path;
}
* @param useRegExpr True: <code>pattern</code> is a regular expression.
*/
-#if defined RE_TESTUNIT
-class TestReDirectory : public ReTestUnit {
-public:
- TestReDirectory() : ReTestUnit("ReFileFinder", __FILE__){
- run();
- }
-private:
- void run(){
- createTestDir();
- ReByteBuffer dir;
- dir.set(getTestDir(), -1);
- ReByteBuffer file1 = dir;
- file1.append("abc.1.txt", -1);
- createFile(file1.str(), "abc1");
-
- ReByteBuffer file2 = dir;
- file2.append("abc.2.txt", -1);
- createFile(file2.str(), "abc2");
-
- ReDirectory finder(dir.str());
- checkT(finder.isValid());
-
- checkT(finder.findFirst("abc.*.txt", false));
- checkEqu("abc.1.txt", finder.currentFile());
- checkT(finder.findNext());
- checkEqu("abc.2.txt", finder.currentFile());
- checkF(finder.findNext());
- checkF(finder.findFirst("abx.*.txt", false));
-
- checkT(finder.findFirst("abc[.][0-9][.]txt", true));
- checkEqu("abc.1.txt", finder.currentFile());
- checkT(finder.findNext());
- checkEqu("abc.2.txt", finder.currentFile());
- checkF(finder.findNext());
- checkF(finder.findFirst("abx[.][0-9][.]txt", true));
- }
-};
-extern void testReDirectory(void);
-
-void testReDirectory(void){
- TestReDirectory unit;
-}
-#endif /*RE_TESTUNIT*/
#ifndef REFILEFINDER_H_
#define REFILEFINDER_H_
-
/** <code>ReDirectory</code> searches files using pattern matching and/or file date.
*/
class ReDirectory{
ReByteBuffer& fullpath(ReByteBuffer& path, const char* name = NULL);
private:
//@ true: The directory is ok. false: The directory is undefined.
- bool m_valid;
- DIR* m_dir;
+ bool m_valid;
//@ The name of the current directory. Always ends with slash!
- ReByteBuffer m_path;
- struct dirent* m_entry;
- ReByteBuffer m_pattern;
- bool m_isRegExpr;
- regex_t m_regExpr;
+ ReByteBuffer m_path;
+ ReByteBuffer m_pattern;
+#if defined __linux__
+ DIR* m_dir;
+ struct dirent* m_entry;
+ regex_t m_regExpr;
+ int m_regExprFlags;
+ bool m_regExprIsInitialized;
// Flags for the regular expressions: REG_ICASE: ignore Case.
- int m_regExprFlags;
+ bool m_isRegExpr;
+#elif defined __WIN32__
+ HANDLE m_handle;
+ WIN32_FIND_DATAA m_data;
+#endif
};
#endif /* REFILEFINDER_H_ */
* Author: wk
*/
-#include "rebase.hpp"
+#include "base/rebase.hpp"
/** @brief Constructor.
*
*/
ReException::ReException(const char* message)
:
- m_message(strdup(message))
+ m_message(_strdup(message))
{
}
/** @brief Constructor.
{
char buffer[512];
snprintf(buffer, sizeof buffer, "%s [%.100s-%d]", message, file, lineNo);
- m_message = strdup(buffer);
+ m_message = _strdup(buffer);
}
/** @brief Destructor.
*/
ReException::ReException(const ReException& source)
:
- m_message(strdup(source.getMessage()))
+ m_message(_strdup(source.getMessage()))
{
}
ReException& ReException::operator =(const ReException& source){
if (m_message != NULL)
free((void*) m_message);
- m_message = strdup(source.getMessage());
+ m_message = _strdup(source.getMessage());
return *this;
}
{
char buffer[512];
snprintf(buffer, sizeof buffer, "%s%s", message, format == NULL ? "" : format);
- m_message = strdup(buffer);
+ m_message = _strdup(buffer);
}
/** @brief Constructor.
char buffer[512];
snprintf(buffer, sizeof buffer, "%s%s [%.100s-%d]",
message, format == NULL ? "" : format, file, lineNo);
- m_message = strdup(buffer);
+ m_message = _strdup(buffer);
}
/** @brief Constructor.
const char* format = index < bound
? i18n("%s: index underflow: %d / %d") : i18n("%s: index overflow: %d / %d");
snprintf(buffer, sizeof buffer, format, name, index, bound);
- m_message = strdup(buffer);
+ m_message = _strdup(buffer);
}
/** @brief Constructor.
*
const char* format = index < bound
? i18n("%s: index underflow: %d / %d [%s-%d]") : i18n("%s: index overflow: %d / %d [%s-%d]");
snprintf(buffer, sizeof buffer, format, name, index, bound, file, line);
- m_message = strdup(buffer);
+ m_message = _strdup(buffer);
}
-#if defined RE_TESTUNIT
-class TestReException : public ReTestUnit, public ReVarArgTrigger {
-public:
- TestReException()
- :
- ReTestUnit("ReException", __FILE__),
- m_argNo(0),
- m_maxNo(0)
- {
- run();
- }
- virtual void newArg(int no, int maxNo){
- m_argNo = no;
- m_maxNo = maxNo;
- }
-private:
- void run(){
- try{
- throw ReException("ReException");
- checkT(false);
- } catch (ReException& e){
- log(false, e.getMessage());
- }
- try{
- throw ReException("ReException", __FILE__, __LINE__);
- checkT(false);
- } catch (ReException& e){
- log(false, e.getMessage());
- }
- try{
- throw ReFormatException("ReFormatException", "format");
- checkT(false);
- } catch (ReException& e){
- log(false, e.getMessage());
- }
- try{
- throw ReFormatException("ReFormatException", "format", __FILE__, __LINE__);
- checkT(false);
- } catch (ReException& e){
- log(false, e.getMessage());
- }
- try{
- throw ReBoundsException("myArray", 101, 100);
- checkT(false);
- } catch (ReException& e){
- log(false, e.getMessage());
- }
-
- try{
- throw ReBoundsException("myArray", -1, 0, __FILE__, __LINE__);
- checkT(false);
- } catch (ReException& e){
- log(false, e.getMessage());
- }
-
- }
-private:
- int m_argNo;
- int m_maxNo;
-};
-extern void testReException(void);
-
-void testReException(void){
- TestReException unit;
-}
-#endif /*RE_TESTUNIT*/
-
inline void setMessage(const char* message){
if (m_message != NULL)
free((void *) m_message);
- m_message = strdup(message);
+ m_message = _strdup(message);
}
/** @brief Returns the message.
* @returns The description of the exception.
* Author: wk
*/
-#include "rebase.hpp"
+#include "base/rebase.hpp"
/** Constructor.
*/
int ix = find(key, keyLength);
bool storeValue = false;
if (ix < 0){
- ReSeqList::Index pos = m_values.getLength();
+ ReSeqList::Index pos = m_values.length();
storeValue = true;
m_keys.add(-1, key, keyLength, pos);
} else {
Sequence* seq = m_keys.getInfo(ix);
// m_tag contains the index into <code>m_values</code>.
- Byte* ptr = m_values.getBuffer() + seq->m_tag;
+ Byte* ptr = m_values.buffer() + seq->m_tag;
size_t valLength = * (size_t *) ptr;
// Can we take the old storage?
if (valLength >= valueLength){
memcpy(ptr, value, valueLength);
} else {
storeValue = true;
- seq->m_tag = m_values.getLength();
+ seq->m_tag = m_values.length();
}
}
if (storeValue){
* @param value The value.
*/
void ReHashList::put(const ReByteBuffer& key, const ReByteBuffer& value){
- put(key.getBuffer(), key.getLength(), value.getBuffer(), value.getLength());
+ put(key.buffer(), key.length(), value.buffer(), value.length());
}
/** @brief Returns the value of a key value pair.
*
if (rc){
ReSeqList::Sequence* seq = m_keys.getInfo(ix);
// m_tag contains the index into m_values:
- Byte* ptr = m_values.getBuffer() + seq->m_tag;
+ Byte* ptr = m_values.buffer() + seq->m_tag;
// m_values contains <length><sequence>:
size_t valLength = * (size_t*) ptr;
ptr += sizeof (size_t);
*/
bool ReHashList::get(const ReByteBuffer& key,
ReByteBuffer value) const{
- bool rc = get(key.getBuffer(), key.getLength(), value);
+ bool rc = get(key.buffer(), key.length(), value);
return rc;
}
/** @brief Deletes all entries in the list.
if (key != NULL){
const Byte* ptr = m_keys.getContent() + seq->m_index;
key->setLength(seq->m_length);
- memcpy(key->getBuffer(), ptr, seq->m_length);
+ memcpy(key->buffer(), ptr, seq->m_length);
}
if (value != NULL){
- const Byte* ptr = m_values.getBuffer() + seq->m_tag;
+ const Byte* ptr = m_values.buffer() + seq->m_tag;
size_t length = * (size_t*) ptr;
ptr += sizeof (size_t);
value->setLength(length);
- memcpy(value->getBuffer(), ptr, length);
+ memcpy(value->buffer(), ptr, length);
}
}
return rc;
return rc;
}
-#if defined RE_TESTUNIT
-class TestReHashList : public ReTestUnit {
-public:
- TestReHashList() : ReTestUnit("ReHashList", __FILE__){
- run();
- }
-private:
- void run(){
- testBasic();
- testNext();
- }
- 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("1", "8");
- hash.put("2", "4");
- hash.put("4", "2");
- hash.put("8", "1");
- int flagsKey = 0;
- int flagsVal = 0;
- size_t pos = 0;
- ReByteBuffer key, value;
- while(hash.next(pos, &key, &value)){
- int x = atol(key.getBuffer());
- int y = atol(value.getBuffer());
- checkEqu(8, x * y);
- flagsKey += x;
- flagsVal += y;
- }
- checkEqu(15, flagsKey);
- checkEqu(15, flagsVal);
- }
-};
-extern void testReHashList(void);
-
-void testReHashList(void){
- TestReHashList unit;
-}
-#endif /*RE_TESTUNIT*/
* Author: wk
*/
-#include "../base/restring.hpp"
+#include "base/rebase.hpp"
//@ The current language. If NULL no language has been chosen.
ReI18N::LanguagePack* ReI18N::m_current = 0;
return args;
}
-#if defined RE_TESTUNIT
-class TestReI18N : public ReTestUnit {
-public:
- TestReI18N()
- :
- ReTestUnit("ReI18N", __FILE__)
- {
- run();
- }
-private:
- void run(){
- checkEqu("dies ist ein Test", i18n("this is a test"));
- checkEqu("eins: 1 zwei: 2", i18nf("one: $1 two: $2").arg(1).arg(2).asCString());
-
- }
-};
-extern void testReI18N(void);
-
-void testReI18N(void){
- TestReI18N unit;
-}
-#endif /*RE_TESTUNIT*/
-
-
* Author: wk
*/
-#include "rebase.hpp"
+#include "base/rebase.hpp"
+#ifdef __linux__
+extern size_t strftime (char* s, size_t maxsize, const char* format, const struct tm* tp);
+#endif
ReLogger* ReLogger::m_globalLogger = NULL;
*/
ReLogger* ReLogger::globalLogger(){
if (m_globalLogger == NULL){
- ReStreamAppender* stream = new ReStreamAppender(stderr);
- ReFileAppender* file = new ReFileAppender();
- file->setConfig("globallogger", 5, 1000100);
m_globalLogger = new ReLogger();
- m_globalLogger->addAppender(stream);
- m_globalLogger->addAppender(file);
+ m_globalLogger->addStandardAppenders(true, "globallogger");
}
return m_globalLogger;
}
+/**
+ * Frees the resources of the global logger (if it exists).
+ */
+void ReLogger::freeGlobalLogger(){
+ if (m_globalLogger != NULL){
+ delete m_globalLogger;
+ m_globalLogger = NULL;
+ }
+}
/** @brief Constructor.
*/
ReAppender::ReAppender()
/** @brief Destructor.
*/
ReStreamAppender::~ReStreamAppender(){
+ if (m_stream != NULL){
+ fclose(m_stream);
+ m_stream = NULL;
+ }
}
/** @brief Puts a message into the internal stream.
*/
void ReStreamAppender::say(ReLogger* logger, const char* message){
const char* prefix = logger->getStandardPrefix();
- fputs(prefix, m_stream);
- if (message != NULL)
- fputs(message, m_stream);
- else
- fputs(logger->asCString(), m_stream);
- fputc('\n', m_stream);
- fflush(m_stream);
+ if (m_stream != NULL){
+ fputs(prefix, m_stream);
+ if (message != NULL)
+ fputs(message, m_stream);
+ else
+ fputs(logger->asCString(), m_stream);
+ fputc('\n', m_stream);
+ fflush(m_stream);
+ }
}
/** @brief Constructor.
*/
ReByteBuffer fn, protocol, path, name, ext;
ReStringUtils::splitPath(m_filePattern, &protocol, &path, &name, &ext);
ReStringUtils::joinPath(fn, &protocol, &path, NULL, NULL);
- if (fn.getLength() == 0)
+ if (fn.length() == 0)
fn.set(".", 1);
ReDirectory dir(fn.str());
if (! dir.isValid()){
} else {
ReStringUtils::joinPath(fn, NULL, NULL, &name, &ext);
int ix = fn.indexOf(placeholder, -1, 0);
+#if defined __linux__
fn.splice(ix, 4, "[0-9]{4}", -1);
+#elif defined __WIN32__
+ fn.splice(ix, 4, "*", -1);
+#endif
// Looking for the current logfile:
if (! dir.findFirst(fn.str(), true)){
struct stat info;
ReByteBuffer fullname;
dir.fullpath(fullname, fn.str());
+#ifdef __WIN32__
+#define lstat stat
+#endif
int rc = lstat(fullname.str(), &info);
if (rc == 0 && (m_currentSize = info.st_size) > m_maxSize)
changeFile();
else{
m_stream = fopen(fullname.str(), "a");
- assert(m_stream != NULL);
+ if (m_stream == NULL)
+ assert(m_stream != NULL);
}
}
}
snprintf(filename, sizeof filename, m_filePattern, fileNo);
struct stat info;
if (lstat(filename, &info) == 0)
- unlink(filename);
+ _unlink(filename);
else
break;
}
m_stdFileAppender(NULL),
m_locationOfOpenSayF(0)
{
- if (isGlobal)
+ if (isGlobal){
+ delete m_globalLogger;
m_globalLogger = this;
+ }
m_standardPrefix[0] = '\0';
}
/** @brief Destructor.
delete[] m_appenderList;
m_appenderList = NULL;
m_appenderListSize = 0;
+ if (m_globalLogger == this)
+ m_globalLogger = NULL;
}
/** @brief Issues a log message.
*
const char* format){
if (m_locationOfOpenSayF != 0){
char message[128];
- snprintf(message, sizeof message, "missing ReLogger::end(): Location: %d", m_locationOfOpenSayF);
+ snprintf(message, sizeof message, "missing ReLogger::end(): Location: %d",
+ m_locationOfOpenSayF);
say(LOG_ERROR|GRAN_USER|CAT_LIB, LC_LOGGER_SAYF_OPEN, message);
}
m_locationOfOpenSayF = location;
m_locationOfOpenSayF = 0;
}
-#if defined RE_TESTUNIT
-class TestReLogger : public ReTestUnit {
-public:
- TestReLogger() : ReTestUnit("ReLogger", __FILE__){
- run();
- }
-private:
- void run(){
- ReStreamAppender app1(stdout);
- app1.setMode(CAT_ALL, CAT_ALL, CAT_ALL, GRAN_ALL);
-
- ReLogger logger;
- logger.addAppender(&app1);
- log(false, "2 Errors and a warning:");
- logger.say(LOG_ABORT | CAT_TEST | GRAN_TRACE, __LINE__, "abort");;
- logger.say(LOG_ERROR | CAT_TEST, __LINE__, "error");
- logger.say(LOG_WARNING | CAT_TEST, __LINE__, "warning");
-
- logger.sayF(CAT_TEST, __LINE__, "Two: $1 eleven: $021").arg(2).arg(1).end();
- globalLogger()->say(CAT_LIB, __LINE__, "globalLogger()");
- }
-};
-extern void testReLogger(void);
-
-void testReLogger(void){
- TestReLogger unit;
-}
-#endif /*RE_TESTUNIT*/
-
class ReLogger : public ReVarArgs {
public:
static ReLogger* globalLogger();
+ static void freeGlobalLogger();
static ReLogger* m_globalLogger;
public:
ReLogger(bool isGlobal = true);
* Author: wk
*/
-#include "rebase.hpp"
+#include "base/rebase.hpp"
/** @brief Constructor.
ReByteBuffer number;
number.appendInt(defaultVal);
addProperties(name, description, shortOpt, longOpt, DT_INT,
- number.str(), number.getLength());
+ number.str(), number.length());
}
/** @brief Adds an option with a boolean value.
ReOptionException(this, i18n("$1 is not an option name"), name);
properties.split(buffer.str(), '\1');
- if (properties.getCStr(IxType)[0] != 'b')
+ if (properties.strOf(IxType)[0] != 'b')
ReOptionException(this, i18n("$1 is not an boolean option. Type is $2"), name,
- properties.getCStr(IxType));
+ properties.strOf(IxType));
m_values.get(name, -1, buffer);
bool rc = buffer.at(1) == 't';
ReOptionException(this, i18n("$1 is not an option name"), name);
properties.split(buffer.str(), '\1');
- if (properties.getCStr(IxType)[0] != DT_INT)
+ if (properties.strOf(IxType)[0] != DT_INT)
ReOptionException(this, i18n("$1 is not an integer option. Type is $2"), name,
- properties.getCStr(IxType));
+ properties.strOf(IxType));
m_values.get(name, -1, buffer);
int rc = buffer.atoi(1);
ReOptionException(this, i18n("$1 is not an option name"), name);
properties.split(buffer.str(), '\1');
- DataType dataType = (DataType) properties.getCStr(IxType)[0];
+ DataType dataType = (DataType) properties.strOf(IxType)[0];
if (dataType != DT_STRING && dataType != DT_STRING_EMPTY)
ReOptionException(this, i18n("$1 is not a string option. Type is $2"), name,
- properties.getCStr(IxType));
+ properties.strOf(IxType));
m_values.get(name, -1, buffer);
- const char* rc = buffer.getBuffer() + 1;
+ const char* rc = buffer.buffer() + 1;
return rc;
}
}
while (! found && m_properties.next(position, &name, &properties)){
list.split(properties.str(), '\1');
- if (longName == NULL && shortName == list.getCStr(IxShort)[0])
+ if (longName == NULL && shortName == list.strOf(IxShort)[0])
found = true;
- else if (lengthLongName > 0 && list.getLength(IxLong) == lengthLongName + 1
- && strncmp(longName, list.getCStr(IxLong), lengthLongName) == 0)
+ else if (lengthLongName > 0 && list.sizeOf(IxLong) == lengthLongName + 1
+ && strncmp(longName, list.strOf(IxLong), lengthLongName) == 0)
found = true;
}
if (! found){
again = false;
search(opt[0], NULL, name, properties);
- const char* dataType = properties.getCStr(IxType);
+ const char* dataType = properties.strOf(IxType);
const char* nameStr = name.str();
// Forget the option short name:
opt++;
} else if (opt[0] == '+')
opt++;
// Invert the default value:
- if (properties.getCStr(IxDefault)[0] == 't')
+ if (properties.strOf(IxDefault)[0] == 't')
value = value[0] =='t' ? "f" : "t";
setValue(nameStr, value, dataType);
again = opt[0] != '\0';
search('\0', opt, name, properties);
const char* nameStr = name.str();
- const char* dataType = properties.getCStr(IxType);
+ const char* dataType = properties.strOf(IxType);
const char* value = strchr(opt, '=');
if (value != NULL)
value++;
ReOptionException(this, i18n("Option $1: Not a boolean value: $2. Use true or false"),
nameStr, value);
// Invert the default value:
- if (properties.getCStr(IxDefault)[0] == 't')
+ if (properties.strOf(IxDefault)[0] == 't')
boolValue = boolValue[0] =='t' ? "f" : "t";
setValue(nameStr, boolValue, dataType);
break;
ReStringList properties;
properties.split(prop.str(), '\1');
line.setLength(0);
- DataType dataType = DataType(properties.getCStr(IxType)[0]);
- const char* shortName = properties.getCStr(IxShort);
+ DataType dataType = DataType(properties.strOf(IxType)[0]);
+ const char* shortName = properties.strOf(IxShort);
param.setLength(0);
switch(dataType){
case DT_INT:
line.append("-", 1).append(shortName, 1);
line.append(param.str(), -1).append(" ", 1).append(i18n(" or "), -1);
}
- line.append(i18n("--"), -1).append(properties.getCStr(IxLong), -1);
- if (param.getLength() > 0)
+ line.append(i18n("--"), -1).append(properties.strOf(IxLong), -1);
+ if (param.length() > 0)
line.append("=", -1).append(param.str(), -1)
- .append(i18n(" Default value: "), -1).append(properties.getCStr(IxDefault), -1);
+ .append(i18n(" Default value: "), -1).append(properties.strOf(IxDefault), -1);
lines.append(line.str());
- line.set("\t", 1).append(properties.getCStr(IxDescr), -1);
+ line.set("\t", 1).append(properties.strOf(IxDescr), -1);
lines.append(line.str());
}
if (m_examples.getCount() > 0){
lines.append(i18n("Example:"));
lines.append(m_examples);
}
- if (issueLastError && m_lastError.getLength() > 0){
+ if (issueLastError && m_lastError.length() > 0){
line.set("+++ ", 4).append(m_lastError.str(), -1);
lines.append(line.str());
}
ReStringList lines;
help(message, issueLastError, lines);
for(size_t ii = 0; ii < lines.getCount(); ii++){
- fputs(lines.getCStr(ii), stream);
+ fputs(lines.strOf(ii), stream);
fputc('\n', stream);
}
}
-
-#if defined RE_TESTUNIT
-class TestReProgramArgs : public ReTestUnit {
-public:
- TestReProgramArgs()
- :
- ReTestUnit("ReProgramArgs", __FILE__)
- {
- run();
- }
-private:
- void run(){
- testLong();
- testShort();
- }
- void testShort(){
- ReProgramArgs args("test <opts> <args>\nThis tests the usage of ReProgramArgs",
- "$0 -b+ -B- file dir\n\ttest of an example");
-
- args.addBool("boolarg", "This is a boolean arg", 'b', "boolval", false);
- args.addBool("boolarg2", "This is the 2nd boolean arg", 'B', "boolval2", true);
- args.addBool("boolarg3", "This is the 3rd boolean arg", 'x', "boolval3", false);
- args.addBool("boolarg4", "This is the 4th boolean arg", 'Y', "boolval4", true);
- args.addInt("intarg", "This is an integer arg", 'i', "intval", 9);
- args.addInt("intarg2", "This is the 2nd integer arg", 'I', "intval", 1000);
- args.addString("stringarg", "This string must be non empty", 's', "string", false, "abc");
- args.addString("stringarg2", "This 2nd string must be non empty", 'u', "string2", false, "undef");
- args.addString("estringarg", "This string may be empty", 'S', "estring", true, "empty");
- args.addString("estringarg2", "This 2nd string may be empty", 'U', "estring2", true, "undef2");
-
- checkF(args.getBool("boolarg"));
- checkEqu(9, args.getInt("intarg"));
- ReByteBuffer buffer;
- checkEqu("empty", args.getString("estringarg", buffer));
- checkEqu("abc", args.getString("stringarg", buffer));
-
- const char* vector[] = {
- "testprog", "-bB+i123", "-S", "-x-", "-Y+", "-s", "2nd string", "arg1", "arg2"
- };
- args.init(sizeof vector / sizeof vector[0], (char**) vector);
-
- checkEqu("testprog", args.getProgramName());
- checkT(args.getBool("boolarg"));
- checkF(args.getBool("boolarg2"));
- checkF(args.getBool("boolarg3"));
- checkF(args.getBool("boolarg4"));
- checkEqu(123, args.getInt("intarg"));
- checkEqu(1000, args.getInt("intarg2"));
- checkEqu("", args.getString("estringarg", buffer));
- 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());
-
- args.help("Not really an error!", false, stdout);
- }
- void testLong(){
- const char* call[] = {
- "test <opts> <args>",
- "This tests the usage of ReProgramArgs",
- NULL
- };
- const char* examples[] = { "test -intval=10 --boolval=t", NULL};
- ReProgramArgs args(call, examples);
-
- args.addBool("boolarg", "This is a boolean arg", 'b', "boolval", false);
- char none = ReProgramArgs::HIDDEN_SHORT_NAME;
- args.addBool("boolarg2", "This is the 2nd boolean arg", none, "boolval2", true);
- args.addBool("boolarg3", "This is the 3rd boolean arg", 'x', "boolval3", false);
- args.addBool("boolarg4", "This is the 3rd boolean arg", none, "boolval4", true);
- args.addInt("intarg", "This is an integer arg", 'i', "intval", 9);
- args.addString("stringarg", "This string must be non empty", 's', "string", false, "abc");
- args.addString("estringarg", "This string may be empty", none, "estring", true, "empty");
- args.addString("estringarg2", "This 2nd string may be empty", 'U', "estring2", true, "undef2");
- args.addString("estringarg3", "This 3thrd string may be empty", 'V', "estring3", true, "undef3");
-
- ReByteBuffer buffer;
- const char* vector[] = {
- "testprog",
- "--boolval", "--boolval2=true", "--boolval3=f", "--boolval4=0",
- "--intval=3",
- "--string=x y", "--estring=", "--estring2=not empty",
- "arg1", "arg2"
- };
- args.init(sizeof vector / sizeof vector[0], (char**) vector);
-
- checkEqu("testprog", args.getProgramName());
- checkT(args.getBool("boolarg"));
- checkF(args.getBool("boolarg2"));
- checkF(args.getBool("boolarg3"));
- checkT(args.getBool("boolarg4"));
- checkEqu(3, args.getInt("intarg"));
- 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());
- args.help(NULL, false, stdout);
- }
-};
-extern void testReProgramArgs(void);
-
-void testReProgramArgs(void){
- TestReProgramArgs unit;
-}
-#endif /*RE_TESTUNIT*/
-
-
* Author: wk
*/
-#include "rebase.hpp"
+#include "base/rebase.hpp"
/** @brief Constructor.
*
Sequence seq;
if (sourceLength == (size_t) -1)
sourceLength = strlen(source) + 1;
- seq.m_index = m_content.getLength();
+ seq.m_index = m_content.length();
seq.m_length = sourceLength;
seq.m_tag = tag;
m_content.append(source, sourceLength);
bool ReSeqList::get(Index index, ReByteBuffer& value, Tag* tag) const{
bool rc = false;
if (index < getCount()){
- Sequence* seq = ((Sequence*)m_list.getBuffer()) + index;
- value.set(m_content.getBuffer() + seq->m_index, seq->m_length);
+ Sequence* seq = ((Sequence*)m_list.buffer()) + index;
+ value.set(m_content.buffer() + seq->m_index, seq->m_length);
if (tag != NULL)
*tag = seq->m_tag;
rc = true;
seq->m_tag = tag;
if (seq->m_length >= sourceLength){
// Use the existing space:
- memcpy(m_content.getBuffer() + seq->m_index, source, sourceLength);
+ memcpy(m_content.buffer() + seq->m_index, source, sourceLength);
m_lost += seq->m_length - sourceLength;
} else {
// New space must be allocated:
m_lost += seq->m_length;
- seq->m_index = m_content.getLength();
+ seq->m_index = m_content.length();
m_content.append(source, sourceLength);
}
}
if (index <= getCount()){
Sequence* seq = getInfo(index);
// Is this the last entry in m_content?
- if (seq->m_index + seq->m_length >= m_content.getLength()){
+ if (seq->m_index + seq->m_length >= m_content.length()){
// We can free the content:
m_content.setLength(seq->m_index);
} else {
m_list.setLength(0);
}
-#if defined RE_TESTUNIT
-class TestReSeqList : public ReTestUnit {
-public:
- TestReSeqList() : ReTestUnit("ReSeqList", __FILE__){
- run();
- }
-private:
- void run(){
- testBase();
- testRemove();
- }
- void testBase(){
- ReSeqList list;
- ReByteBuffer value;
- ReSeqList::Tag tag = 0;
-
- list.add(-1, "123", -1, 100);
- checkEqu(1, list.getCount());
- checkT(list.get(0, value, &tag));
- checkEqu("123", value.str());
- checkEqu(100, tag);
-
- list.add(-1, "ab", -1, 200);
- checkEqu(2, list.getCount());
- checkT(list.get(0, value));
- checkEqu("123", value.str());
- checkT(list.get(1, value, &tag));
- checkEqu("ab", value.str());
- checkEqu(200, tag);
-
- list.add(0, "xyz", -1, 300);
- checkEqu(3, list.getCount());
- checkT(list.get(0, value, &tag));
- checkEqu("xyz", value.str());
- checkT(list.get(1, value));
- checkEqu("123", value.str());
- checkT(list.get(2, value));
- checkEqu("ab", value.str());
- checkEqu(300, tag);
-
- list.add(1, "vw", -1, 400);
- checkEqu(4, list.getCount());
- checkT(list.get(0, value));
- checkEqu("xyz", value.str());
- checkT(list.get(1, value, &tag));
- checkEqu("vw", value.str());
- checkT(list.get(2, value));
- checkEqu("123", value.str());
- checkT(list.get(3, value));
- checkEqu("ab", value.str());
- checkEqu(400, tag);
-
- list.clear();
- checkEqu(0, list.getCount());
- checkF(list.get(0, value));
- }
- void testRemove(){
- ReSeqList list;
- ReByteBuffer value;
- ReSeqList::Tag tag = 0;
-
- list.add(-1, "abc", -1, 100);
- list.add(-1, "def12", -1, 200);
- list.add(-1, "ghi", -1, 300);
- list.add(-1, "jkl134", -1, 400);
-
- list.remove(3);
- checkEqu(3, list.getCount());
- list.get(0, value, &tag);
- checkEqu("abc", value.str());
- checkEqu(100, tag);
- list.get(1, value, &tag);
- checkEqu("def12", value.str());
- checkEqu(200, tag);
- list.get(2, value, &tag);
- checkEqu("ghi", value.str());
- checkEqu(300, tag);
-
-
- list.remove(1);
- checkEqu(2, list.getCount());
- list.get(0, value, &tag);
- checkEqu("abc", value.str());
- checkEqu(100, tag);
- list.get(1, value, &tag);
- checkEqu("ghi", value.str());
- checkEqu(300, tag);
-
- list.remove(0);
- checkEqu(1, list.getCount());
- list.get(0, value, &tag);
- checkEqu("ghi", value.str());
- checkEqu(300, tag);
-
- }
-};
-extern void testReSeqList(void);
-
-void testReSeqList(void){
- TestReSeqList unit;
-}
-#endif /*RE_TESTUNIT*/
public:
typedef char Byte;
typedef unsigned int Index;
- typedef long int Tag;
+ typedef int64_t Tag;
typedef struct {
Index m_index;
size_t m_length;
* @return The number of defined entries in the list (array).
*/
inline Index getCount() const {
- return m_list.getLength() / sizeof (Sequence);
+ return m_list.length() / sizeof (Sequence);
}
protected:
/** @brief Returns a pointer of the content buffer.
* @return A pointer of the first byte of the content buffer.
*/
inline const Byte* getContent() const {
- return m_content.getBuffer();
+ return m_content.buffer();
}
friend class ReHashList;
/** @brief Returns the info of an entry of the list.
* @return The pointer of the entry.
*/
inline Sequence* getInfo(Index index) const {
- return &((Sequence*) m_list.getBuffer())[index];
+ return &((Sequence*) m_list.buffer())[index];
}
protected:
* Author: wk
*/
-#include "../base/restring.hpp"
+#include "base/rebase.hpp"
/** @brief Constructor.
*/
/** @brief Appends a string at the end.
*
* @param source The new string.
- * @param tag An item which will stored with the string. It can be retrieved by the same index.
+ * @param tagOf An item which will stored with the string. It can be retrieved by the same index.
* T his class knows nothing about this.
*/
-void ReStringList::append(const char* source, Tag tag){
- add(-1, source, -1, tag);
+void ReStringList::append(const char* source, Tag tagOf){
+ add(-1, source, -1, tagOf);
}
/** @brief Appends a stringlist at the end.
*
*/
void ReStringList::append(ReStringList& source){
for (size_t ii = 0; ii < source.getCount(); ii++)
- add(-1, source.getCStr(ii), -1, source.getTag(ii));
+ add(-1, source.strOf(ii), -1, source.tagOf(ii));
}
/** @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 tag An item which will stored with the string. It can be retrieved by the same index.
+ * @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 tag){
- add(index, source, -1, tag);
+void ReStringList::insert(Index index, const char* source, Tag tagOf){
+ add(index, source, -1, tagOf);
}
-/** @brief Replaces an element in the internal array: a string and a tag.
+/** @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 tag The tag of the replace element.
+ * @param tagOf The tagOf of the replace element.
*/
-void ReStringList::replace(Index index, const char* source, Tag tag){
- set(index, source, -1, tag);
+void ReStringList::replace(Index index, const char* source, Tag tagOf){
+ set(index, source, -1, tagOf);
}
/** @brief Replaces a string in the internal array.
*
- * The tag of the element remains unchanged.
+ * 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.
set(index, source, -1, seq->m_tag);
}
}
-/** @brief Replaces a tag in the internal array.
+/** @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.
*/
-void ReStringList::replaceTag(Index index, Tag tag){
+void ReStringList::replaceTag(Index index, Tag tagOf){
if (index < getCount()){
Sequence* seq = getInfo(index);
- seq->m_tag = tag;
+ seq->m_tag = tagOf;
}
}
* @return NULL: The index is too large.
* Otherwise: The wanted string.
*/
-const char* ReStringList::getCStr(Index index) const{
+const char* ReStringList::strOf(Index index) const{
const char* rc = NULL;
if (index < getCount()){
Sequence* seq = getInfo(index);
- rc = m_content.getBuffer() + seq->m_index;
+ rc = m_content.buffer() + seq->m_index;
}
return rc;
}
-/** @brief Returns the tag given by an index.
+/** @brief Returns the tagOf given by an index.
*
- * A tag is an additional info stored with the string.
+ * A tagOf is an additional info stored with the string.
*
- * @param index The index of the wanted tag.
+ * @param index The index of the wanted tagOf.
*
* @return -1: The index is too large.
- * Otherwise: The wanted tag.
+ * Otherwise: The wanted tagOf.
*/
-ReSeqList::Tag ReStringList::getTag(Index index) const{
+ReSeqList::Tag ReStringList::tagOf(Index index) const{
Tag rc = -1;
if (index < getCount()){
Sequence* seq = getInfo(index);
}
return rc;
}
-/** @brief Returns the length of the string given by an index.
+/** @brief Returns the length of the byte sequence given by an index.
*
* @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 string.
+ * Otherwise: The length of the <code>index</code>-th sequence
+ * (including the trailing '\0').
*/
-size_t ReStringList::ReStringList::getLength(Index index) const{
+size_t ReStringList::sizeOf(Index index) const{
size_t rc = 0;
if (index < getCount()){
Sequence* seq = getInfo(index);
}
return rc;
}
+/** @brief Returns the length of the string given by an index.
+ *
+ * @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').
+ */
+size_t ReStringList::strLengthOf(Index index) const{
+ size_t rc = 0;
+ if (index < getCount()){
+ Sequence* seq = getInfo(index);
+ rc = seq->m_length - 1;
+ }
+ return rc;
+}
/** @brief Returns the sum of all string lengths stored in the array.
*
* @return The sum of all string lengths stored in the array.
*/
-size_t ReStringList::sumOfLength() const{
+size_t ReStringList::sumOfSizes() const{
size_t rc = 0;
for (int ii = getCount() - 1; ii >= 0; ii--){
}
return rc;
}
+/** @brief Returns 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;
+
+ for (int ii = getCount() - 1; ii >= 0; ii--){
+ Sequence* seq = getInfo(ii);
+ rc += seq->m_length - 1;
+ }
+ return rc;
+}
/** @brief Returns the index of a given string in the array.
*
* @param toFind The string which will be searched.
Index rc = (Index) -1;
Index count = getCount();
- for (; rc == (size_t) -1 && start < count; start++){
- const char* item = getCStr(start);
+ for (; rc == (Index) -1 && start < count; start++){
+ const char* item = strOf(start);
int rc2;
if (ignoreCase)
rc2 = strcasecmp(item, toFind);
Index count = getCount();
size_t length = strlen(prefix);
- for (; rc == (size_t) -1 && start < count; start++){
- const char* item = getCStr(start);
+ for (; rc == (Index) -1 && start < count; start++){
+ const char* item = strOf(start);
int rc2;
if (ignoreCase)
rc2 = strncasecmp(item, prefix, length);
item.append(list, length);
// Append '\0':
item.append("", 1);
- add(-1, item.getBuffer(), length + 1);
+ add(-1, item.buffer(), length + 1);
list = end + 1;
if (separator == '\n' && list[0] == '\r')
list++;
size_t lengthSep = strlen(separator);
for (size_t ix = 0; ix < count; ix++){
- result.append(getCStr(ix), getLength(ix) - 1);
+ result.append(strOf(ix), sizeOf(ix) - 1);
if (ix != count - 1 && separator != NULL)
result.append(separator, lengthSep);
}
if (fp){
size_t count = getCount();
for (size_t ix = 0; ix < count; ix++){
- fputs(getCStr(ix), fp);
+ fputs(strOf(ix), fp);
if (ix != count - 1 && separator != NULL)
fputs(separator, fp);
}
}
add(-1, line, length + 1);
}
+ fclose(fp);
}
return rc;
}
for (size_t ix = 0; rc == -1 && ix < getCount(); ix++){
if (ix >= toCompare.getCount())
rc = (int) ix;
- else if (getLength(ix) != toCompare.getLength(ix)
- || strcmp(getCStr(ix), toCompare.getCStr(ix)) != 0)
+ else if (sizeOf(ix) != toCompare.sizeOf(ix)
+ || strcmp(strOf(ix), toCompare.strOf(ix)) != 0)
rc = (int) ix;
}
if (rc == -1 && getCount() < toCompare.getCount())
bool rc = getCount() == toCompare.getCount() && firstDiff(toCompare) == -1;
return rc;
}
-
-#if defined RE_TESTUNIT
-class TestReStringList : public ReTestUnit {
-public:
- TestReStringList() : ReTestUnit("ReStringList", __FILE__){
- run();
- }
-private:
- void run(){
- testBase();
- testReplace();
- testJoin();
- testEqu();
- testFile();
- }
- void testReplace(){
- ReStringList list;
-
- list.append("123", 100);
- checkEqu(100, list.getTag(0));
- list.append("2", 200);
- checkEqu(100, list.getTag(0));
- checkEqu(200, list.getTag(1));
- list.append("34", 300);
- checkEqu(100, list.getTag(0));
- checkEqu(200, list.getTag(1));
- checkEqu(300, list.getTag(2));
-
- list.replace(0, "1", 111);
- checkEqu("1", list.getCStr(0));
- checkEqu(111, list.getTag(0));
- checkEqu(200, list.getTag(1));
- checkEqu(300, list.getTag(2));
-
- list.replace(1, "124", 222);
- checkEqu("124", list.getCStr(1));
- checkEqu(111, list.getTag(0));
- checkEqu(222, list.getTag(1));
- checkEqu(300, list.getTag(2));
-
- checkEqu(300, list.getTag(2));
- list.replaceString(2, "4");
- checkEqu("4", list.getCStr(2));
- checkEqu(111, list.getTag(0));
- checkEqu(222, list.getTag(1));
- checkEqu(300, list.getTag(2));
-
- list.replaceTag(2, 123);
- checkEqu("4", list.getCStr(2));
- checkEqu(111, list.getTag(0));
- checkEqu(222, list.getTag(1));
- checkEqu(123, list.getTag(2));
- }
- void testEqu(){
- ReStringList list1;
- ReStringList list2;
-
- list1.split("1;2;1;3", ';');
- list2.split("1\n2\n1\n3", '\n');
- checkEqu(-1, list1.firstDiff(list2));
- checkEqu(-1, list2.firstDiff(list1));
- checkT(list1.equal(list2));
- checkT(list2.equal(list1));
-
- list1.insert(2, "x");
- list1.remove(3);
- checkEqu(2, list1.firstDiff(list2));
- checkEqu(2, list2.firstDiff(list1));
- checkF(list1.equal(list2));
- checkF(list2.equal(list1));
-
- list2.replace(2, "x");
- checkEqu(-1, list1.firstDiff(list2));
- checkEqu(-1, list2.firstDiff(list1));
- checkT(list1.equal(list2));
- checkT(list2.equal(list1));
-
- list2.remove(3);
- checkEqu(3, list1.firstDiff(list2));
- checkEqu(3, list2.firstDiff(list1));
- checkF(list1.equal(list2));
- checkF(list2.equal(list1));
-
- list1.replace(0, "");
- checkEqu(0, list1.firstDiff(list2));
- checkEqu(0, list2.firstDiff(list1));
- checkF(list1.equal(list2));
- checkF(list2.equal(list1));
-
- list1.clear();
- list2.clear();
- checkEqu(-1, list1.firstDiff(list2));
- checkEqu(-1, list2.firstDiff(list1));
- checkT(list1.equal(list2));
- checkT(list2.equal(list1));
-
- list1.append("fjkdajfdkla");
- checkEqu(0, list1.firstDiff(list2));
- checkEqu(0, list2.firstDiff(list1));
- checkF(list1.equal(list2));
- checkF(list2.equal(list1));
- }
- void testJoin(){
- ReStringList list;
- const char* str = "1;abc;xyz;4;;99";
- list.split(str, ';');
- checkEqu(6, list.getCount());
- checkEqu("1", list.getCStr(0));
- checkEqu("abc", list.getCStr(1));
- checkEqu("xyz", list.getCStr(2));
- checkEqu("4", list.getCStr(3));
- checkEqu("", list.getCStr(4));
- checkEqu("99", list.getCStr(5));
- ReByteBuffer value;
- list.join(";", value);
- checkEqu(str, value.str());
-
- list.split("1\r\n2\n\r3", '\n');
- checkEqu(3, list.getCount());
- checkEqu("1", list.getCStr(0));
- checkEqu("2", list.getCStr(1));
- checkEqu("3", list.getCStr(2));
-
- list.split("xyz\tXYZ", '\t', true);
- checkEqu(5, list.getCount());
- checkEqu("1", list.getCStr(0));
- checkEqu("2", list.getCStr(1));
- checkEqu("3", list.getCStr(2));
- checkEqu("xyz", list.getCStr(3));
- checkEqu("XYZ", list.getCStr(4));
-
-
- }
- void testFile(){
- createTestDir();
- ReByteBuffer file;
- file.set(getTestDir(), -1).append("abc.csv", -1);
-
- ReStringList list;
- const char* str = "1;abc;xyz;4;;99";
- list.split(str, ';');
- list.writeToFile(file.str(), "\n");
-
- ReStringList list2;
- list2.readFromFile(file.str(), true);
-
- checkEqu(-1, list2.firstDiff(list2));
- }
- void testBase(){
- ReStringList list;
- ReByteBuffer value;
-
- list.append("123", 100);
- list.append("a", 200);
- list.append("vwxyz", 300);
-
- checkEqu(3, list.getCount());
- int index = 0;
- checkEqu("123", list.getCStr(index));
- checkEqu(4, list.getLength(index));
- checkEqu(100, list.getTag(index));
-
- index++;
- checkEqu("a", list.getCStr(index));
- checkEqu(2, list.getLength(index));
- checkEqu(200, list.getTag(index));
-
- index++;
- checkEqu("vwxyz", list.getCStr(index));
- checkEqu(6, list.getLength(index));
- checkEqu(300, list.getTag(index));
-
- checkEqu(12, list.sumOfLength());
-
- list.insert(0, "0", 50);
- checkEqu(4, list.getCount());
- checkEqu(14, list.sumOfLength());
-
- index = 0;
- checkEqu("0", list.getCStr(index));
- checkEqu(2, list.getLength(index));
- checkEqu(50, list.getTag(index));
-
- index++;
- checkEqu("123", list.getCStr(index));
- checkEqu(4, list.getLength(index));
- checkEqu(100, list.getTag(index));
-
- index++;
- checkEqu("a", list.getCStr(index));
- checkEqu(2, list.getLength(index));
- checkEqu(200, list.getTag(index));
-
- index++;
- checkEqu("vwxyz", list.getCStr(index));
- checkEqu(6, list.getLength(index));
- checkEqu(300, list.getTag(index));
-
- checkEqu(0, list.indexOf("0"));
- checkEqu(1, list.indexOf("123"));
- checkEqu(2, list.indexOf("a"));
- checkEqu(2, list.indexOf("A", true));
- checkEqu(3, list.indexOf("vwxyz"));
- checkEqu(3, list.indexOf("VwXyz", true));
-
- checkEqu(0, list.indexOf("0", false, 0));
- checkEqu(1, list.indexOf("123", false, 1));
- checkEqu(2, list.indexOf("a", false, 1));
- checkEqu(2, list.indexOf("a", false, 2));
- checkEqu(2, list.indexOf("A", true, 2));
- checkEqu(3, list.indexOf("vwxyz", false, 2));
- checkEqu(3, list.indexOf("vwxyz", false, 3));
- checkEqu(3, list.indexOf("VwXyz", true, 3));
-
- checkEqu(-1, list.indexOf("A"));
- checkEqu(-1, list.indexOf("0123"));
- checkEqu(-1, list.indexOf("a", false, 3));
- checkEqu(-1, list.indexOf("A", true, 3));
-
- checkEqu(0, list.nextStartingWith(0, "0"));
- checkEqu(1, list.nextStartingWith(0, "12"));
- checkEqu(2, list.nextStartingWith(0, "a"));
- checkEqu(2, list.nextStartingWith(1, "a"));
- checkEqu(2, list.nextStartingWith(2, "a"));
- checkEqu(2, list.nextStartingWith(0, "A", true));
- checkEqu(-1, list.nextStartingWith(2, "Ab", true));
- checkEqu(-1, list.nextStartingWith(0, "b", true));
-
- checkEqu(3, list.nextStartingWith(0, "vwxy", false));
- checkEqu(3, list.nextStartingWith(0, "vwxy", true));
- checkEqu(-1, list.nextStartingWith(0, "vWxY", false));
-
- ReStringList list2;
- list2.append("a", 100);
- list2.append("b", 200);
- list2.append("c", 300);
- ReStringList list3;
- list3.append("x", 1000);
- list3.append("y", 2000);
-
- list2.append(list3);
- checkEqu(5, list2.getCount());
- checkEqu("a", list2.getCStr(0));
- checkEqu(100, list2.getTag(0));
- checkEqu("b", list2.getCStr(1));
- checkEqu(200, list2.getTag(1));
- checkEqu("c", list2.getCStr(2));
- checkEqu(300, list2.getTag(2));
- checkEqu("x", list2.getCStr(3));
- checkEqu(1000, list2.getTag(3));
- checkEqu("y", list2.getCStr(4));
- checkEqu(2000, list2.getTag(4));
- }
-};
-extern void testReStringList(void);
-
-void testReStringList(void){
- TestReStringList unit;
-}
-#endif /*RE_TESTUNIT*/
-
public:
void append(const char* source, Tag tag = 0);
void append(ReStringList& source);
+ Index indexOf(const char* toFind, bool ignoreCase = false, Index start = 0) const;
void insert(Index index, const char* source, Tag tag = 0);
+ void join(const char* separator, ReByteBuffer& result);
+ Index nextStartingWith(Index index, const char* prefix, bool ignoreCase = false);
void replace(Index index, const char* source, Tag tag = 0);
void replaceString(Index index, const char* source);
void replaceTag(Index index, Tag tag);
+ const char* strOf(Index index) const;
+ size_t sizeOf(Index index) const;
+ void split(const char* list, char separator, bool append = false);
+ size_t strLengthOf(Index index) const;
+ size_t sumOfSizes() const;
+ size_t sumOfStrLengths() const;
+ Tag tagOf(Index index) const;
- const char* getCStr(Index index) const;
- Tag getTag(Index index) const;
- size_t getLength(Index index) const;
- size_t sumOfLength() const;
- Index indexOf(const char* toFind, bool ignoreCase = false, Index start = 0) const;
- Index nextStartingWith(Index index, const char* prefix, bool ignoreCase = false);
-
- void split(const char* list, char separator, bool append = false);
- void join(const char* separator, ReByteBuffer& result);
int firstDiff(const ReStringList& toCompare) const;
bool equal(const ReStringList& toCompare) const;
* Author: wk
*/
-#include "../base/restring.hpp"
+#include "base/rebase.hpp"
char ReStringUtils::slash = ReStringUtils::initPathSeparator();
const char* ReStringUtils::slashStr = NULL;
}
return rc;
}
-
-#if defined RE_TESTUNIT
-class TestReStringUtils : public ReTestUnit {
-public:
- TestReStringUtils() : ReTestUnit("ReStringUtils", __FILE__){
- run();
- }
-private:
- void run(){
- testStrnicmp();
- testIsInList();
- testSplitPath();
- }
- void testStrnicmp(){
- checkT(ReStringUtils::strnicmp("abc", "abc", 3) == 0);
- checkT(ReStringUtils::strnicmp("abc", "ab", 3) > 0);
- checkT(ReStringUtils::strnicmp("ab", "abc", 3) < 0);
-
- checkT(ReStringUtils::strnicmp("aBc", "Abc", 3) == 0);
- checkT(ReStringUtils::strnicmp("Abc", "aB", 3) > 0);
- checkT(ReStringUtils::strnicmp("AB", "abc", 3) < 0);
-
- checkT(ReStringUtils::strnicmp("ABC", "ABD", 2) == 0);
- checkT(ReStringUtils::strnicmp("abC", "ABD", 2) == 0);
-
- checkT(ReStringUtils::strnicmp("AAC", "ABD", 2) < 0);
- checkT(ReStringUtils::strnicmp("aaC", "ABD", 2) < 0);
-
- checkT(ReStringUtils::strnicmp("", "x", 99) < 0);
- checkT(ReStringUtils::strnicmp("x", "", 99) > 0);
-
- checkT(ReStringUtils::strnicmp("abc", "abc", 99) == 0);
- checkT(ReStringUtils::strnicmp("abc", "ab", 99) > 0);
- checkT(ReStringUtils::strnicmp("ab", "abc", 99) < 0);
- }
- void testIsInList(){
- checkT(ReStringUtils::isInList("abc", ";abc;def", true));
- checkT(ReStringUtils::isInList("aBc", ";abc;def", true));
- checkF(ReStringUtils::isInList("aBc", ";abc;def", false));
-
- checkF(ReStringUtils::isInList("aBc", ";abc;def", false));
-
- checkT(ReStringUtils::isInList("abc", ";a;abc;def", true));
- checkT(ReStringUtils::isInList("aBc", ";b;abc;def", true));
- checkF(ReStringUtils::isInList("aBc", ";c;abc;def", false));
-
- checkF(ReStringUtils::isInList("aBc", ";a;abcabc;def", false));
-
- checkT(ReStringUtils::isInList("abc", ";abc", true));
- checkT(ReStringUtils::isInList("aBc", ";abc", true));
- checkF(ReStringUtils::isInList("aBc", ";abc", false));
-
- checkF(ReStringUtils::isInList("aBc", ";abc", false));
-
- }
- void testSplitPath(){
- ReByteBuffer fullname, protocol, path, name, ext;
- const char* fn = "file:/etc/samba/smb.cnf";
-
- ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
- checkEqu("file:", protocol.str());
- checkEqu("/etc/samba/", path.str());
- checkEqu("smb", name.str());
- checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
- checkEqu(fn, fullname.str());
-
- fn = "/etc/samba/smb.cnf";
-
- ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
- checkEqu("", protocol.str());
- checkEqu("/etc/samba/", path.str());
- checkEqu("smb", name.str());
- checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
- checkEqu(fn, fullname.str());
-
- fn = "smb.cnf";
-
- ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
- checkEqu("", protocol.str());
- checkEqu("", path.str());
- checkEqu("smb", name.str());
- checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
- checkEqu(fn, fullname.str());
-
- fn = "smb";
-
- ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
- checkEqu("", protocol.str());
- checkEqu("", path.str());
- checkEqu("smb", name.str());
- checkEqu("", ext.str());
-
- ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
- checkEqu(fn, fullname.str());
-
- fn = "file:smb.003.cnf";
-
- ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
- checkEqu("file:", protocol.str());
- checkEqu("", path.str());
- checkEqu("smb.003", name.str());
- checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
- checkEqu(fn, fullname.str());
-
- fn = "file:/etc.bak/smb";
-
- ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
- checkEqu("file:", protocol.str());
- checkEqu("/etc.bak/", path.str());
- checkEqu("smb", name.str());
- checkEqu("", ext.str());
-
- ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
- checkEqu(fn, fullname.str());
-
- fn = "file:/etc/samba/smb.cnf";
-
- ReStringUtils::splitPath(fn, NULL, &path, &name, &ext);
- checkEqu("file:", protocol.str());
- checkEqu("smb", name.str());
- checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, &protocol, NULL, &name, &ext);
- checkEqu("file:smb.cnf", fullname.str());
-
- fn = "file:/etc/samba/smb.cnf";
-
- ReStringUtils::splitPath(fn, NULL, NULL, &name, &ext);
- checkEqu("smb", name.str());
- checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, NULL, NULL, &name, &ext);
- checkEqu("smb.cnf", fullname.str());
-
- fn = "file:/etc/samba/smb.cnf";
-
- ReStringUtils::splitPath(fn, NULL, NULL, &name, NULL);
- //checkEqu("", protocol.str());
- //checkEqu("/etc/samba/", path.str());
- checkEqu("smb", name.str());
- //checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, NULL, NULL, &name, NULL);
- checkEqu("smb", fullname.str());
-
- fn = "file:/etc/samba/smb.cnf";
-
- ReStringUtils::splitPath(fn, NULL, &path, NULL, &ext);
- //checkEqu("", protocol.str());
- checkEqu("/etc/samba/", path.str());
- //checkEqu("smb", name.str());
- checkEqu(".cnf", ext.str());
-
- ReStringUtils::joinPath(fullname, NULL, &path, NULL, &ext);
- checkEqu("/etc/samba/.cnf", fullname.str());
-
- ReStringUtils::joinPath(fullname, "http:", "//any.de/", "name", ".ext");
- checkEqu("http://any.de/name.ext", fullname.str());
-
- ReStringUtils::joinPath(fullname, NULL, "/any.de/", "name", ".ext");
- checkEqu("/any.de/name.ext", fullname.str());
-
- ReStringUtils::joinPath(fullname, NULL, NULL, "name", ".ext");
- checkEqu("name.ext", fullname.str());
-
- ReStringUtils::joinPath(fullname, NULL, NULL, "name", NULL);
- checkEqu("name", fullname.str());
-
- ReStringUtils::joinPath(fullname, "file:", "/", NULL, NULL);
- checkEqu("file:/", fullname.str());
- }
-};
-extern void testReStringUtils(void);
-
-void testReStringUtils(void){
- TestReStringUtils unit;
-}
-#endif /*RE_TESTUNIT*/
-
* Created on: 04.05.2010
* Author: wk
*/
-#include <stdarg.h>
-
-#include "rebase.hpp"
+#include "base/rebase.hpp"
/** @brief Constructor.
*
* @param name The name of the test class.
*/
ReTestUnit::ReTestUnit(const char* name, const char* sourceFile)
:
- m_name(strdup(name)),
+ m_name(_strdup(name)),
m_errorCount(0),
- m_sourceFile(strdup(sourceFile))
+ m_sourceFile(_strdup(sourceFile))
{
logF(false, i18n("Start %s"), name);
}
* @param current The current value.
* @param lineNo The line number of the test (for the error messge).
*/
-void ReTestUnit::assertEqual(long expected, long current, int lineNo){
+void ReTestUnit::assertEqual(int expected, int current, int lineNo){
+ if (expected != current){
+ logF(true, i18n("%s-%d: expected: %ld (%lx) current: %ld (%lx)"),
+ m_sourceFile, lineNo, expected, expected, current, current);
+ m_errorCount++;
+ }
+}
+/** @brief Compares two integer values. If not equal this will be logged.
+ *
+ * @param expected The expected value
+ * @param current The current value.
+ * @param lineNo The line number of the test (for the error messge).
+ */
+void ReTestUnit::assertEqual(unsigned int expected, unsigned int current, int lineNo){
if (expected != current){
logF(true, i18n("%s-%d: expected: %ld (%lx) current: %ld (%lx)"),
m_sourceFile, lineNo, expected, expected, current, current);
m_errorCount++;
}
}
+/** @brief Compares two integer values. If not equal this will be logged.
+ *
+ * @param expected The expected value
+ * @param current The current value.
+ * @param lineNo The line number of the test (for the error messge).
+ */
+void ReTestUnit::assertEqual(int64_t expected, int64_t current, int lineNo){
+ if (expected != current){
+ logF(true, i18n("%s-%d: expected: %lld (%llx) current: %lld (%llx)"),
+ m_sourceFile, lineNo, expected, expected, current, current);
+ m_errorCount++;
+ }
+}
/** @brief Compares two string values. If not equal this will be logged.
*
* @param expected The expected value
logF(true, i18n("%s-%d: File does not exist: %s"),
m_sourceFile, lineNo, name);
m_errorCount++;
- } else if ((info.st_mode & __S_IFDIR) != 0){
+ } else if (S_ISDIR(info.st_mode)){
logF(true, i18n("%s-%d: File does exist but this is a directory: %s"),
m_sourceFile, lineNo, name);
m_errorCount++;
strcat(ptr, "retestunit");
strcat(ptr, ReStringUtils::pathSeparatorStr());
struct stat info;
+#ifdef __WIN32__
+#define lstat stat
+#define mkdir(name, flags) _mkdir(name)
+#define ALLPERMS 0
+#endif
if (lstat(name, &info) != 0)
mkdir(name, ALLPERMS);
else{
logF(true, i18n("%s-%d: Directory does not exist: %s"),
m_sourceFile, lineNo, dir);
m_errorCount++;
- } else if ((info.st_mode & __S_IFDIR) == 0){
+ } else if (! S_ISDIR(info.st_mode)){
logF(true, i18n("%s-%d: File exists but this is not a directory: %s"),
m_sourceFile, lineNo, dir);
m_errorCount++;
void assertFalse(bool conditon, int lineNo);
void assertNull(void* pointer, int lineNo);
void assertNotNull(void* pointer, int lineNo);
- void assertEqual(long expected, long current, int lineNo);
+ void assertEqual(int64_t expected, int64_t current, int lineNo);
+ void assertEqual(int expected, int current, int lineNo);
+ void assertEqual(unsigned int expected, unsigned int current, int lineNo);
void assertEqual(const char* expected, const char* current, int lineNo);
void createTestDir();
* .arg(info.st_size, "%8d").arg(info.st_size, "%8x").asCString();
* </code></pre>
*/
-#include "rebase.hpp"
+#include "base/rebase.hpp"
int const ReVarArgs::STD_SPACE = 20;
char const ReVarArgs::PLACE_HOLDER_MARK = '$';
}
if (argNo > m_argNo){
throw ReFormatException(i18n("Too large argument number: "),
- m_format.getBuffer() + position,
+ m_format.buffer() + position,
__FILE__, __LINE__);
} else {
- char* arg = m_argBuffer.getBuffer() + m_args[argNo];
+ char* arg = m_argBuffer.buffer() + m_args[argNo];
size_t argLen = strlen(arg);
m_format.splice(position, argNoLen, arg, argLen);
position += argLen;
}
if (found < m_argNo)
throw ReFormatException(i18n("Format contains to few placeholders"),
- m_format.getBuffer(), __FILE__, __LINE__);
+ m_format.buffer(), __FILE__, __LINE__);
}
/** @brief Stores an argument.
*
if (length < 0)
length = strlen(value);
// Store the first index of the argument in <code>m_argBuffer</code>.
- m_args[++m_argNo] = m_argBuffer.getLength();
+ m_args[++m_argNo] = m_argBuffer.length();
// Store the string with trailing '\0':
m_argBuffer.append(value, length);
m_argBuffer.append("", 1);
*
* @return The instance itself. This is useful for chaining.
*/
-ReVarArgs& ReVarArgs::ReVarArgs::arg(int value, const char* format){
+ReVarArgs& ReVarArgs::arg(int value, const char* format){
char number[256];
snprintf(number, sizeof number, format, value);
store(number);
ReByteBuffer buffer;
buffer.setLengthAndFill(minWidth, ' ');
if (alignRight)
- memcpy(buffer.getBuffer() + minWidth - length, value, length);
+ memcpy(buffer.buffer() + minWidth - length, value, length);
else
- memcpy(buffer.getBuffer(), value, length);
- store (buffer.getBuffer(), buffer.getLength());
+ memcpy(buffer.buffer(), value, length);
+ store (buffer.buffer(), buffer.length());
}
return *this;
}
const char* ReVarArgs::asCString(){
if (m_argNo != m_maxArgNo)
throw ReFormatException(i18n("To few arguments"),
- m_format.getBuffer());
+ m_format.buffer());
if (! m_stringIsReady){
replacePlaceholder();
m_stringIsReady = true;
}
- return m_format.getBuffer();
+ return m_format.buffer();
}
/** @brief Stores a trigger.
void ReVarArgs::end(void){
// Nothing to do in this base class
}
-
-#if defined RE_TESTUNIT
-class TestReVarArgs : public ReTestUnit, public ReVarArgTrigger {
-public:
- TestReVarArgs()
- :
- ReTestUnit("ReVarArgs", __FILE__),
- m_argNo(0),
- m_maxNo(0)
- {
- run();
- }
- virtual void newArg(int no, int maxNo){
- m_argNo = no;
- m_maxNo = maxNo;
- }
-private:
- void run(){
- ReVarArgs list("$1 $$ $2");
- list.registerTrigger(this);
-
- list.arg(0).arg(9, "%03u");
- checkEqu(m_argNo, 2);
- checkEqu(m_maxNo, 2);
- checkEqu("0 $ 009", list.asCString());
-
-
- list.reset("x$1y$2");
- list.arg(1.5);
- checkEqu(m_argNo, 1);
- checkEqu(m_maxNo, 2);
- list.arg(2.45,"%7.3f");
- checkEqu(m_argNo, 2);
- checkEqu(m_maxNo, 2);
- checkEqu("x1.500000y 2.450", list.asCString());
-
- list.reset("$2,$1!$3;$4");
- list.arg("1").arg("ab", 4);
- list.arg("xy", 0, 1);
- checkEqu(m_argNo, 3);
- checkEqu(m_maxNo, 4);
- list.arg("ww", 5, 0, true);
- checkEqu(m_argNo, 4);
- checkEqu(m_maxNo, 4);
- checkEqu("ab ,1!x; ww", list.asCString());
- }
-private:
- int m_argNo;
- int m_maxNo;
-};
-extern void testReVarArgs(void);
-
-void testReVarArgs(void){
- TestReVarArgs unit;
-}
-#endif /*RE_TESTUNIT*/
-
#include <errno.h>
#include <ctype.h>
#include <assert.h>
+#include <stdarg.h>
-#define __LINUX__
-
-#if defined __LINUX__
+#if defined __linux__
+#include <stddef.h>
#include <dirent.h>
#include <fnmatch.h>
#include <regex.h>
#include <unistd.h>
#include <inttypes.h>
-#elif defined WIN32
+#define _strdup strdup
+#define _unlink unlink
+//#define _
+#elif defined __WIN32__
+#include <direct.h>
+#include <windows.h>
typedef _int64 int64_t;
-
#endif
#define RE_TESTUNIT
typedef unsigned char byte_t;
+#if defined __linux__
+#elif defined __WIN32__
+#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
+#define strcasecmp(s1, s2) _stricmp(s1, s2)
+#define snprintf _snprintf
+#define S_ISDIR(mode) (((mode) & _S_IFDIR) != 0)
+#endif
+
#include "../base/baselocations.hpp"
#endif /* REBASE_HPP_ */
* Created on: 05.05.2010
* Author: wk
*/
-#include "../base/rebase.hpp"
+#include "base/rebase.hpp"
#if defined RE_TESTUNIT
extern void testReBase(void);
void testReBase(void){
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReHashList : public ReTestUnit {
+public:
+ TestReHashList() : ReTestUnit("ReHashList", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ testBasic();
+ testNext();
+ }
+ 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("1", "8");
+ hash.put("2", "4");
+ hash.put("4", "2");
+ hash.put("8", "1");
+ int flagsKey = 0;
+ int flagsVal = 0;
+ size_t pos = 0;
+ 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;
+}
* Created on: 27.11.2010
* Author: wk
*/
-#include "../base/rebase.hpp"
+#include "base/rebase.hpp"
class TestReByteBuffer : public ReTestUnit {
typedef ReByteBuffer::Byte Byte;
public:
}
private:
void run(){
+ testCount();
+ testEnsureSizeGetLength();
+ testIndexOf();
+ testRIndexOf();
+ testStartsWidth();
+ testEndsWidth();
testOpAssignCopyConstructor();
testAt();
- testEnsureSizeGetLength();
testBasic();
testAtoi();
- testIndexOfRIndexOf();
+ testIndexOfCharRIndexOfChar();
+ testRIndexOf();
testInsert();
testRemove();
testSplice();
testReplace();
}
+ void testCount(){
+ ReByteBuffer buffer("aabbaabb");
+ checkEqu(4, buffer.count("a"));
+ checkEqu(4, buffer.count("b"));
+ checkEqu(2, buffer.count("ab"));
+ checkEqu(1, buffer.count("aabbaabb"));
+ }
+ void testStartsWidth(){
+ // . . . . . . . . . 01234567
+ ReByteBuffer buffer("aabbaabb");
+ // case sensitive
+ checkT(buffer.startsWith("aabbaabb", -1, false));
+ checkT(buffer.startsWith("aabbaabb", 8, false));
+ checkT(buffer.startsWith("a", -1, false));
+ checkT(buffer.startsWith("aab", -1, false));
+ checkT(buffer.startsWith("ax", 1, false));
+
+ // case insensitive
+ checkT(buffer.startsWith("AabbaabB", -1, true));
+ checkT(buffer.startsWith("aabbaabB", 8, true));
+ checkT(buffer.startsWith("A", -1, true));
+ checkT(buffer.startsWith("aAb", -1, true));
+ checkT(buffer.startsWith("Aax", 2, true));
+ checkT(buffer.startsWith("aab", -1, false));
+
+ // not matching:
+ checkF(buffer.startsWith("b", 1, false));
+ checkF(buffer.startsWith("ab", 2, false));
+ checkF(buffer.startsWith("A", 1, false));
+ checkF(buffer.startsWith("Ab", 2, false));
+
+ // binary:
+ buffer.buffer()[1] = '\0';
+ ReByteBuffer buffer2("aab");
+ ReByteBuffer buffer3("aax");
+ buffer2.buffer()[1] = '\0';
+ buffer3.buffer()[1] = '\0';
+ checkT(buffer.startsWith(buffer2.str(), 3, false));
+ checkF(buffer.startsWith(buffer3.str(), 3, false));
+ buffer2.buffer()[0] = 'A';
+ buffer3.buffer()[0] = 'A';
+ checkT(buffer.startsWith(buffer2.str(), 3, true));
+ checkF(buffer.startsWith(buffer3.str(), 3, true));
+ }
+
+ void testEndsWidth(){
+ // . . . . . . . . . 01234567
+ ReByteBuffer buffer("aabbaabb");
+ // case sensitive
+ checkT(buffer.endsWith("b", -1, false));
+ checkT(buffer.endsWith("abb", -1, false));
+ checkT(buffer.endsWith("bx", 1, false));
+
+ // case insensitive
+ checkT(buffer.endsWith("B", -1, true));
+ checkT(buffer.endsWith("aBb", -1, true));
+ checkT(buffer.endsWith("Bbx", 2, true));
+ checkT(buffer.endsWith("Abb", -1, true));
+
+ // not matching:
+ checkF(buffer.endsWith("a", -1, false));
+ checkF(buffer.endsWith("a", 1, false));
+ checkF(buffer.endsWith("ab", 2, false));
+ checkF(buffer.endsWith("B", 1, false));
+ checkF(buffer.endsWith("Ab", 2, false));
+
+ // binary:
+ buffer.buffer()[6] = '\0';
+ ReByteBuffer buffer2("abb");
+ buffer2.buffer()[1] = '\0';
+ checkT(buffer.endsWith(buffer2.str(), 3, false));
+ buffer2.buffer()[0] = 'A';
+ checkT(buffer.endsWith(buffer2.str(), 3, true));
+ }
+
+ void testIndexOf(){
+ // . . . . . . . . . 01234567
+ ReByteBuffer buffer("aabbaabb");
+ // const Byte* toFind, size_t toFindLength, int start,int end, bool ignoreCase
+ checkEqu(0, buffer.indexOf("aa", -1, 0, -1, false));
+ int ix;
+ for (ix = 1; ix <= 4; ix++)
+ checkEqu(4, buffer.indexOf("aa", 2, ix, -1, false));
+ checkEqu(4, buffer.indexOf("aa", 2, 1, 6, false));
+ checkEqu(-1, buffer.indexOf("aa", 2, 1, 5, false));
+ checkEqu(1, buffer.indexOf("ab", 2, 0, -1, false));
+ checkEqu(-1, buffer.indexOf("Aa", 2, 0, -1, false));
+
+ checkEqu(0, buffer.indexOf("aA", 2, 0, -1, true));
+ for (ix = 1; ix <= 4; ix++)
+ checkEqu(4, buffer.indexOf("Aa", 2, ix, -1, true));
+ checkEqu(4, buffer.indexOf("aA", 2, 1, 6, true));
+ checkEqu(-1, buffer.indexOf("Aa", 2, 1, 5, true));
+ checkEqu(1, buffer.indexOf("aB", 2, 0, -1, true));
+ }
+ void testRIndexOf(){
+ // . . . . . . . . . 01234567
+ ReByteBuffer buffer("aabbaabb");
+ // const Byte* toFind, size_t toFindLength, int start,int end, bool ignoreCase
+ checkEqu(4, buffer.rindexOf("aa", -1, 0, -1, false));
+ int ix;
+ for (ix = 9; ix >= 6; ix--)
+ checkEqu(4, buffer.rindexOf("aa", 2, 0, ix, false));
+ checkEqu(0, buffer.rindexOf("aa", 2, 0, 5, false));
+ checkEqu(-1, buffer.rindexOf("aa", 2, 1, 3, false));
+ checkEqu(1, buffer.rindexOf("ab", 2, 0, 5, false));
+ checkEqu(1, buffer.rindexOf("ab", 2, 1, 5, false));
+ checkEqu(-1, buffer.rindexOf("Aa", 2, 0, -1, false));
+
+ for (ix = 9; ix >= 6; ix--)
+ checkEqu(4, buffer.rindexOf("Aa", 2, 0, ix, true));
+ checkEqu(0, buffer.rindexOf("aA", 2, 0, 5, true));
+ checkEqu(-1, buffer.rindexOf("Aa", 2, 1, 3, true));
+ checkEqu(1, buffer.rindexOf("aB", 2, 0, 5, true));
+ checkEqu(1, buffer.rindexOf("Ab", 2, 1, 5, true));
+ checkEqu(4, buffer.rindexOf("Aa", 2, 0, -1, true));
+ }
void testBasic(){
ReByteBuffer buffer(10);
buffer.append((Byte*)"123", 3);
- checkEqu("123", buffer.getBuffer());
+ checkEqu("123", buffer.buffer());
checkEqu("123", buffer.str());
- checkEqu(3, buffer.getLength());
+ checkEqu(3u, buffer.length());
buffer.append((Byte*)"ab", 2);
- checkEqu("123ab", buffer.getBuffer());
- checkEqu(5, buffer.getLength());
+ checkEqu("123ab", buffer.buffer());
+ checkEqu(5u, buffer.length());
buffer.setLengthAndFill(8, 'x');
- checkEqu("123abxxx", buffer.getBuffer());
- checkEqu(8, buffer.getLength());
+ checkEqu("123abxxx", buffer.buffer());
+ checkEqu(8u, buffer.length());
buffer.setLength(3);
- checkEqu("123", buffer.getBuffer());
- checkEqu(3, buffer.getLength());
+ checkEqu("123", buffer.buffer());
+ checkEqu(3u, buffer.length());
buffer.setLengthAndFill(511, 'y');
buffer.setLengthAndFill(512, 'z');
- checkEqu("yyz", buffer.getBuffer() + 509);
- checkEqu(521, buffer.getSize());
+ checkEqu("yyz", buffer.buffer() + 509);
+ checkEqu(521u, buffer.capacity());
ReByteBuffer buffer2;
buffer2.set("xyz", -1);
buffer.set("abc", -1);
- checkEqu("abc", buffer.getBuffer());
- checkEqu(3, buffer.getLength());
+ checkEqu("abc", buffer.buffer());
+ checkEqu(3u, buffer.length());
buffer.append(buffer2);
- checkEqu("abcxyz", buffer.getBuffer());
+ checkEqu("abcxyz", buffer.buffer());
checkEqu("abcxyz", buffer.str());
- checkEqu(6, buffer.getLength());
+ checkEqu(6u, buffer.length());
buffer.setLength(0);
buffer.appendInt(-1);
checkEqu("-1", buffer.str());
- checkEqu(2, buffer.getLength());
+ checkEqu(2u, buffer.length());
buffer.appendInt(9, "%03d");
checkEqu("-1009", buffer.str());
- checkEqu(5, buffer.getLength());
+ checkEqu(5u, buffer.length());
}
void testOpAssignCopyConstructor() {
ReByteBuffer buf1;
void testAt(){
ReByteBuffer buf1;
buf1.set("abc", 3);
- for (size_t ii = 0; ii < buf1.getLength(); ii++){
- checkEqu('a' + ii, buf1.at(ii));
+ for (size_t ii = 0; ii < buf1.length(); ii++){
+ checkEqu(int('a' + ii), (int) buf1.at(ii));
}
checkEqu(0, buf1.at(-1));
checkEqu(0, buf1.at(3));
checkEqu(0, buffer.atoi(5, 6));
buffer.set("0x98765432", -1);
- checkEqu(0x98765432, buffer.atoi());
+ checkEqu(0x98765432, (unsigned) buffer.atoi());
buffer.set("0xabcdef01", -1);
- checkEqu(0xabcdef01, buffer.atoi());
+ checkEqu(0xabcdef01, (unsigned) buffer.atoi());
buffer.set("0xABCDEF01", -1);
- checkEqu(0xabcdef01, buffer.atoi());
+ checkEqu(0xabcdef01, (unsigned) buffer.atoi());
buffer.set("0xaFFe01", -1);
- checkEqu(0xaFFe01, buffer.atoi());
+ checkEqu(0xaFFe01u, (unsigned) buffer.atoi());
}
void testEnsureSizeGetLength(){
ReByteBuffer buf1;
buf1.ensureSize(2000);
- checkEqu(2000, buf1.getSize());
+ checkEqu(2000u, buf1.capacity());
buf1.set("0123456789", 10);
- checkEqu(10, buf1.getLength());
+ checkEqu(10u, buf1.length());
buf1.setLength(5);
checkEqu("01234", buf1.str());
- checkEqu(5, buf1.getLength());
+ checkEqu(5u, buf1.length());
buf1.setLengthAndFill(8, 'X');
checkEqu("01234XXX", buf1.str());
- checkEqu(8, buf1.getLength());
- checkEqu(2000, buf1.getSize());
+ checkEqu(8u, buf1.length());
+ checkEqu(2000u, buf1.capacity());
}
- void testIndexOfRIndexOf(){
+ void testIndexOfCharRIndexOfChar(){
ReByteBuffer buffer;
buffer.set("123123", -1);
checkEqu(0, buffer.indexOf('1'));
ReByteBuffer buf1;
checkT(buf1.insert(0, "123", 2));
checkEqu("12", buf1.str());
- checkEqu(2, buf1.getLength());
+ checkEqu(2u, buf1.length());
checkT(buf1.insert(0, "abc", 1));
checkEqu("a12", buf1.str());
- checkEqu(3, buf1.getLength());
+ checkEqu(3u, buf1.length());
checkT(buf1.insert(1, "x", 1));
checkEqu("ax12", buf1.str());
- checkEqu(4, buf1.getLength());
+ checkEqu(4u, buf1.length());
checkT(buf1.insert(4, "yz", 2));
checkEqu("ax12yz", buf1.str());
- checkEqu(6, buf1.getLength());
+ checkEqu(6u, buf1.length());
checkF(buf1.insert(-1, "-", 1));
checkF(buf1.insert(8, "/", 1));
buf1.set("1234567890", 10);
checkT(buf1.remove(0, 2));
checkEqu("34567890", buf1.str());
- checkEqu(8, buf1.getLength());
+ checkEqu(8u, buf1.length());
checkF(buf1.remove(-1, 2));
checkEqu("34567890", buf1.str());
- checkEqu(8, buf1.getLength());
+ checkEqu(8u, buf1.length());
checkF(buf1.remove(9, 2));
checkEqu("34567890", buf1.str());
- checkEqu(8, buf1.getLength());
+ checkEqu(8u, buf1.length());
checkT(buf1.remove(7, 2));
checkEqu("3456789", buf1.str());
- checkEqu(7, buf1.getLength());
+ checkEqu(7u, buf1.length());
checkT(buf1.remove(5, 2));
checkEqu("34567", buf1.str());
- checkEqu(5, buf1.getLength());
+ checkEqu(5u, buf1.length());
checkT(buf1.remove(0, 99));
checkEqu("", buf1.str());
- checkEqu(0, buf1.getLength());
+ checkEqu(0u, buf1.length());
}
void testReplace(){
ReByteBuffer buffer;
buffer.append((Byte*) "12.ab", 5);
checkT(buffer.splice(0, 0, "xy", 2));
- checkEqu("xy12.ab", buffer.getBuffer());
+ checkEqu("xy12.ab", buffer.buffer());
buffer.splice(2, 2, NULL, 0);
- checkEqu("xy.ab", buffer.getBuffer());
+ checkEqu("xy.ab", buffer.buffer());
buffer.splice(0, 2, "w", 1);
- checkEqu("w.ab", buffer.getBuffer());
+ checkEqu("w.ab", buffer.buffer());
buffer.setLength(0);
buffer.append((Byte*) "123", 3);
buffer.insert(1, "ab", 2);
- checkEqu("1ab23", buffer.getBuffer());
- checkEqu(5, buffer.getLength());
+ checkEqu("1ab23", buffer.buffer());
+ checkEqu(5u, buffer.length());
buffer.remove(0, 1);
- checkEqu("ab23", buffer.getBuffer());
- checkEqu(4, buffer.getLength());
+ checkEqu("ab23", buffer.buffer());
+ checkEqu(4u, buffer.length());
buffer.remove(3, 55);
- checkEqu("ab2", buffer.getBuffer());
- checkEqu(3, buffer.getLength());
+ checkEqu("ab2", buffer.buffer());
+ checkEqu(3u, buffer.length());
buffer.remove(2, 2);
- checkEqu("ab", buffer.getBuffer());
- checkEqu(2, buffer.getLength());
+ checkEqu("ab", buffer.buffer());
+ checkEqu(2u, buffer.length());
buffer.remove(1, 1);
- checkEqu("a", buffer.getBuffer());
- checkEqu(1, buffer.getLength());
+ checkEqu("a", buffer.buffer());
+ checkEqu(1u, buffer.length());
}
};
extern void testReByteBuffer(void);
* Created on: 23.11.2010
* Author: wk
*/
-#include "../base/restring.hpp"
+#include "base/rebase.hpp"
+#include "string/restring.hpp"
class TestReString : public ReTestUnit {
public:
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReDirectory : public ReTestUnit {
+public:
+ TestReDirectory() : ReTestUnit("ReFileFinder", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ createTestDir();
+ ReByteBuffer dir;
+ dir.set(getTestDir(), -1);
+ ReByteBuffer file1 = dir;
+ file1.append("abc.1.txt", -1);
+ createFile(file1.str(), "abc1");
+
+ ReByteBuffer file2 = dir;
+ file2.append("abc.2.txt", -1);
+ createFile(file2.str(), "abc2");
+
+ ReDirectory finder(dir.str());
+ checkT(finder.isValid());
+
+ checkT(finder.findFirst("abc.*.txt", false));
+ checkEqu("abc.1.txt", finder.currentFile());
+ checkT(finder.findNext());
+ checkEqu("abc.2.txt", finder.currentFile());
+ checkF(finder.findNext());
+ checkF(finder.findFirst("abx.*.txt", false));
+
+ checkT(finder.findFirst("abc[.][0-9][.]txt", true));
+ checkEqu("abc.1.txt", finder.currentFile());
+ checkT(finder.findNext());
+ checkEqu("abc.2.txt", finder.currentFile());
+ checkF(finder.findNext());
+ checkF(finder.findFirst("abx[.][0-9][.]txt", true));
+ }
+};
+extern void testReDirectory(void);
+
+void testReDirectory(void){
+ TestReDirectory unit;
+}
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReException : public ReTestUnit, public ReVarArgTrigger {
+public:
+ TestReException()
+ :
+ ReTestUnit("ReException", __FILE__),
+ m_argNo(0),
+ m_maxNo(0)
+ {
+ run();
+ }
+ virtual void newArg(int no, int maxNo){
+ m_argNo = no;
+ m_maxNo = maxNo;
+ }
+private:
+ void run(){
+ try{
+ throw ReException("ReException");
+ checkT(false);
+ } catch (ReException& e){
+ log(false, e.getMessage());
+ }
+ try{
+ throw ReException("ReException", __FILE__, __LINE__);
+ checkT(false);
+ } catch (ReException& e){
+ log(false, e.getMessage());
+ }
+ try{
+ throw ReFormatException("ReFormatException", "format");
+ checkT(false);
+ } catch (ReException& e){
+ log(false, e.getMessage());
+ }
+ try{
+ throw ReFormatException("ReFormatException", "format", __FILE__, __LINE__);
+ checkT(false);
+ } catch (ReException& e){
+ log(false, e.getMessage());
+ }
+ try{
+ throw ReBoundsException("myArray", 101, 100);
+ checkT(false);
+ } catch (ReException& e){
+ log(false, e.getMessage());
+ }
+
+ try{
+ throw ReBoundsException("myArray", -1, 0, __FILE__, __LINE__);
+ checkT(false);
+ } catch (ReException& e){
+ log(false, e.getMessage());
+ }
+
+ }
+private:
+ int m_argNo;
+ int m_maxNo;
+};
+extern void testReException(void);
+
+void testReException(void){
+ TestReException unit;
+}
+
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReI18N : public ReTestUnit {
+public:
+ TestReI18N()
+ :
+ ReTestUnit("ReI18N", __FILE__)
+ {
+ run();
+ }
+private:
+ void run(){
+ checkEqu("dies ist ein Test", i18n("this is a test"));
+ checkEqu("eins: 1 zwei: 2", i18nf("one: $1 two: $2").arg(1).arg(2).asCString());
+
+ }
+};
+extern void testReI18N(void);
+
+void testReI18N(void){
+ TestReI18N unit;
+}
+
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReLogger : public ReTestUnit {
+public:
+ TestReLogger() : ReTestUnit("ReLogger", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ ReStreamAppender app1(stdout);
+ app1.setMode(CAT_ALL, CAT_ALL, CAT_ALL, GRAN_ALL);
+
+ ReLogger logger(false);
+ logger.addAppender(&app1);
+ log(false, "2 Errors and a warning:");
+ logger.say(LOG_ABORT | CAT_TEST | GRAN_TRACE, __LINE__, "abort");;
+ logger.say(LOG_ERROR | CAT_TEST, __LINE__, "error");
+ logger.say(LOG_WARNING | CAT_TEST, __LINE__, "warning");
+
+ logger.sayF(CAT_TEST, __LINE__, "Two: $1 eleven: $021").arg(2).arg(1).end();
+ globalLogger()->say(CAT_LIB, __LINE__, "globalLogger()");
+ }
+};
+extern void testReLogger(void);
+
+void testReLogger(void){
+ TestReLogger unit;
+}
--- /dev/null
+/*
+ * cuReMatcher.cpp
+ *
+ * Created on: 25.12.2014
+ * Author: hm
+ */
+
+#include "base/rebase.hpp"
+#include "string/restring.hpp"
+
+class TestReMatcher : public ReTestUnit {
+public:
+ TestReMatcher() : ReTestUnit("ReMatcher", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ testPatternList();
+ testMatch();
+ testSearch();
+ testMatchManyStars();
+ testSearchManyStars();
+ }
+ void testPatternList(){
+ RePatternList list;
+ list.set(";*.cpp;^cu*;*.hpp;", true);
+ checkT(list.match("a.hpp"));
+
+ checkT(list.match("a.cpp"));
+ checkT(list.match("a.hpp"));
+ checkF(list.match("cuA.hpp"));
+ checkF(list.match("a.hpp~"));
+ list.set(" * ^*~");
+ checkT(list.match("a.hpp"));
+ checkF(list.match("a.hpp~"));
+ }
+ void testMatch(){
+ ReSimpleMatcher matcher("abc*.x");
+
+ matcher.setIgnoreCase(false);
+ checkT(matcher.match("abc.x"));
+ checkT(matcher.match("abcd.x"));
+ checkF(matcher.match("abc.x~"));
+ checkF(matcher.match("_abc.x"));
+ checkF(matcher.match("aBc.x"));
+ checkF(matcher.match("abc.X"));
+
+ matcher.setIgnoreCase(true);
+ checkT(matcher.match("abc.x"));
+ checkT(matcher.match("abcd.x"));
+ checkF(matcher.match("abc.x~"));
+ checkF(matcher.match("_abc.x"));
+ checkT(matcher.match("aBc.x"));
+ checkT(matcher.match("abc.X"));
+ checkT(matcher.match("aBcdef.X"));
+ }
+ void testMatchManyStars(){
+ ReSimpleMatcher matcher("a*b*c*x");
+
+ matcher.setIgnoreCase(false);
+ checkT(matcher.match("abcd.x"));
+ checkT(matcher.match("a1b2c456d.x"));
+ checkF(matcher.match("A1B2C456d.X"));
+
+ matcher.setIgnoreCase(true);
+ checkT(matcher.match("abcd.x"));
+ checkT(matcher.match("a1b2c456d.x"));
+ checkT(matcher.match("aBcD.x"));
+ checkT(matcher.match("A1B2C456d.X"));
+
+ matcher.compile("*.cpp");
+ matcher.setIgnoreCase(false);
+ checkT(matcher.match("abcd.cpp"));
+ checkF(matcher.match("abcd.cppx"));
+ matcher.setIgnoreCase(true);
+ checkT(matcher.match("abcd.CPP"));
+ checkF(matcher.match("abcd.CPP~"));
+
+ matcher.compile("t*");
+ matcher.setIgnoreCase(false);
+ checkT(matcher.match("test"));
+ checkF(matcher.match("xtest"));
+ matcher.setIgnoreCase(true);
+ checkT(matcher.match("Test"));
+ checkF(matcher.match("xTest"));
+
+ matcher.setNotPattern(true);
+ checkT(matcher.isNotPattern());
+ checkF(matcher.match("Test"));
+ checkT(matcher.match("xTest"));
+
+ matcher.compile("*");
+ matcher.setNotPattern(false);
+ checkT(matcher.match(""));
+ checkT(matcher.match("x"));
+
+ checkF(matcher.isNotPattern());
+ matcher.setNotPattern(true);
+ checkT(matcher.isNotPattern());
+ checkF(matcher.match(""));
+ checkF(matcher.match("x"));
+ }
+ void testSearch(){
+ ReSimpleMatcher matcher("abc*.x");
+ matcher.setIgnoreCase(false);
+
+ checkT(matcher.search("abc.x"));
+ checkT(matcher.search("abcd.x"));
+ checkT(matcher.search("abc.x~"));
+ checkT(matcher.search("_abc.x"));
+ checkF(matcher.search("aBc.x"));
+ checkF(matcher.search("abc.X"));
+ checkT(matcher.search("Xabcdef.xY"));
+ matcher.setIgnoreCase(true);
+ checkT(matcher.search("abc.x"));
+ checkT(matcher.search("abcd.x"));
+ checkT(matcher.search("abc.x~"));
+ checkT(matcher.search("_abc.x"));
+ checkT(matcher.search("aBc.x"));
+ checkT(matcher.search("abc.X"));
+ checkT(matcher.search("aBcdef.X"));
+ checkT(matcher.search("Xabcdef.xY"));
+
+ matcher.compile("*.cpp");
+ matcher.setIgnoreCase(false);
+ checkT(matcher.search("abcd.cpp"));
+ checkT(matcher.search("abcd.cpp~"));
+ checkT(matcher.search(".cpp"));
+ checkF(matcher.search("abcd.cxppx"));
+ matcher.setIgnoreCase(true);
+ checkT(matcher.search("abcd.CPP"));
+ checkF(matcher.search("abcd.CP~"));
+
+ matcher.compile("t");
+ matcher.setIgnoreCase(false);
+ checkT(matcher.search("t"));
+ checkT(matcher.search("test"));
+ checkT(matcher.search("rest"));
+ checkF(matcher.search("xyz"));
+ matcher.setIgnoreCase(true);
+ checkT(matcher.search("T"));
+ checkT(matcher.search("Test"));
+ checkT(matcher.search("resT"));
+ checkF(matcher.search("xyz"));
+ }
+ void testSearchManyStars(){
+ ReSimpleMatcher matcher("*a*b*c*x*");
+
+ matcher.setIgnoreCase(false);
+ checkT(matcher.match("abcd.x"));
+ checkT(matcher.match("a1b2c456d.x"));
+ checkF(matcher.match("A1B2C456d.X"));
+
+ matcher.setIgnoreCase(true);
+ checkT(matcher.match("abcd.x"));
+ checkT(matcher.match("a1b2c456d.x"));
+ checkT(matcher.match("aBcD.x"));
+ checkT(matcher.match("A1B2C456d.X"));
+ }
+};
+extern void testReMatcher(void);
+
+void testReMatcher(void){
+ TestReMatcher unit;
+}
+
+
+
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReProgramArgs : public ReTestUnit {
+public:
+ TestReProgramArgs()
+ :
+ ReTestUnit("ReProgramArgs", __FILE__)
+ {
+ run();
+ }
+private:
+ void run(){
+ testLong();
+ testShort();
+ }
+ void testShort(){
+ ReProgramArgs args("test <opts> <args>\nThis tests the usage of ReProgramArgs",
+ "$0 -b+ -B- file dir\n\ttest of an example");
+
+ args.addBool("boolarg", "This is a boolean arg", 'b', "boolval", false);
+ args.addBool("boolarg2", "This is the 2nd boolean arg", 'B', "boolval2", true);
+ args.addBool("boolarg3", "This is the 3rd boolean arg", 'x', "boolval3", false);
+ args.addBool("boolarg4", "This is the 4th boolean arg", 'Y', "boolval4", true);
+ args.addInt("intarg", "This is an integer arg", 'i', "intval", 9);
+ args.addInt("intarg2", "This is the 2nd integer arg", 'I', "intval", 1000);
+ args.addString("stringarg", "This string must be non empty", 's', "string", false, "abc");
+ args.addString("stringarg2", "This 2nd string must be non empty", 'u', "string2", false, "undef");
+ args.addString("estringarg", "This string may be empty", 'S', "estring", true, "empty");
+ args.addString("estringarg2", "This 2nd string may be empty", 'U', "estring2", true, "undef2");
+
+ checkF(args.getBool("boolarg"));
+ checkEqu(9, args.getInt("intarg"));
+ ReByteBuffer buffer;
+ checkEqu("empty", args.getString("estringarg", buffer));
+ checkEqu("abc", args.getString("stringarg", buffer));
+
+ const char* vector[] = {
+ "testprog", "-bB+i123", "-S", "-x-", "-Y+", "-s", "2nd string", "arg1", "arg2"
+ };
+ args.init(sizeof vector / sizeof vector[0], (char**) vector);
+
+ checkEqu("testprog", args.getProgramName());
+ checkT(args.getBool("boolarg"));
+ checkF(args.getBool("boolarg2"));
+ checkF(args.getBool("boolarg3"));
+ checkF(args.getBool("boolarg4"));
+ checkEqu(123, args.getInt("intarg"));
+ checkEqu(1000, args.getInt("intarg2"));
+ checkEqu("", args.getString("estringarg", buffer));
+ 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());
+
+ args.help("Not really an error!", false, stdout);
+ }
+ void testLong(){
+ const char* call[] = {
+ "test <opts> <args>",
+ "This tests the usage of ReProgramArgs",
+ NULL
+ };
+ const char* examples[] = { "test -intval=10 --boolval=t", NULL};
+ ReProgramArgs args(call, examples);
+
+ args.addBool("boolarg", "This is a boolean arg", 'b', "boolval", false);
+ char none = ReProgramArgs::HIDDEN_SHORT_NAME;
+ args.addBool("boolarg2", "This is the 2nd boolean arg", none, "boolval2", true);
+ args.addBool("boolarg3", "This is the 3rd boolean arg", 'x', "boolval3", false);
+ args.addBool("boolarg4", "This is the 3rd boolean arg", none, "boolval4", true);
+ args.addInt("intarg", "This is an integer arg", 'i', "intval", 9);
+ args.addString("stringarg", "This string must be non empty", 's', "string", false, "abc");
+ args.addString("estringarg", "This string may be empty", none, "estring", true, "empty");
+ args.addString("estringarg2", "This 2nd string may be empty", 'U', "estring2", true, "undef2");
+ args.addString("estringarg3", "This 3thrd string may be empty", 'V', "estring3", true, "undef3");
+
+ ReByteBuffer buffer;
+ const char* vector[] = {
+ "testprog",
+ "--boolval", "--boolval2=true", "--boolval3=f", "--boolval4=0",
+ "--intval=3",
+ "--string=x y", "--estring=", "--estring2=not empty",
+ "arg1", "arg2"
+ };
+ args.init(sizeof vector / sizeof vector[0], (char**) vector);
+
+ checkEqu("testprog", args.getProgramName());
+ checkT(args.getBool("boolarg"));
+ checkF(args.getBool("boolarg2"));
+ checkF(args.getBool("boolarg3"));
+ checkT(args.getBool("boolarg4"));
+ checkEqu(3, args.getInt("intarg"));
+ 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());
+ args.help(NULL, false, stdout);
+ }
+};
+extern void testReProgramArgs(void);
+
+void testReProgramArgs(void){
+ TestReProgramArgs unit;
+}
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReSeqList : public ReTestUnit {
+public:
+ TestReSeqList() : ReTestUnit("ReSeqList", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ testBase();
+ testRemove();
+ }
+ void testBase(){
+ ReSeqList list;
+ ReByteBuffer value;
+ ReSeqList::Tag tag = 0;
+
+ list.add(-1, "123", -1, 100);
+ checkEqu(1u, list.getCount());
+ checkT(list.get(0, value, &tag));
+ checkEqu("123", value.str());
+ checkEqu((int64_t) 100, tag);
+
+ list.add(-1, "ab", -1, 200);
+ checkEqu(2u, list.getCount());
+ checkT(list.get(0, value));
+ checkEqu("123", value.str());
+ checkT(list.get(1, value, &tag));
+ checkEqu("ab", value.str());
+ checkEqu(200ll, tag);
+
+ list.add(0, "xyz", -1, 300);
+ checkEqu(3u, list.getCount());
+ checkT(list.get(0, value, &tag));
+ checkEqu("xyz", value.str());
+ checkT(list.get(1, value));
+ checkEqu("123", value.str());
+ checkT(list.get(2, value));
+ checkEqu("ab", value.str());
+ checkEqu(300ll, tag);
+
+ list.add(1, "vw", -1, 400);
+ checkEqu(4u, list.getCount());
+ checkT(list.get(0, value));
+ checkEqu("xyz", value.str());
+ checkT(list.get(1, value, &tag));
+ checkEqu("vw", value.str());
+ checkT(list.get(2, value));
+ checkEqu("123", value.str());
+ checkT(list.get(3, value));
+ checkEqu("ab", value.str());
+ checkEqu(400ll, tag);
+
+ list.clear();
+ checkEqu(0u, list.getCount());
+ checkF(list.get(0, value));
+ }
+ void testRemove(){
+ ReSeqList list;
+ ReByteBuffer value;
+ ReSeqList::Tag tag = 0;
+
+ list.add(-1, "abc", -1, 100);
+ list.add(-1, "def12", -1, 200);
+ list.add(-1, "ghi", -1, 300);
+ list.add(-1, "jkl134", -1, 400);
+
+ list.remove(3);
+ checkEqu(3u, list.getCount());
+ list.get(0, value, &tag);
+ checkEqu("abc", value.str());
+ checkEqu(100ll, tag);
+ list.get(1, value, &tag);
+ checkEqu("def12", value.str());
+ checkEqu(200ll, tag);
+ list.get(2, value, &tag);
+ checkEqu("ghi", value.str());
+ checkEqu(300ll, tag);
+
+
+ list.remove(1);
+ checkEqu(2u, list.getCount());
+ list.get(0, value, &tag);
+ checkEqu("abc", value.str());
+ checkEqu(100ll, tag);
+ list.get(1, value, &tag);
+ checkEqu("ghi", value.str());
+ checkEqu(300ll, tag);
+
+ list.remove(0);
+ checkEqu(1u, list.getCount());
+ list.get(0, value, &tag);
+ checkEqu("ghi", value.str());
+ checkEqu(300ll, tag);
+
+ }
+};
+extern void testReSeqList(void);
+
+void testReSeqList(void){
+ TestReSeqList unit;
+}
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReStringList : public ReTestUnit {
+public:
+ TestReStringList() : ReTestUnit("ReStringList", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ testBase();
+ testReplace();
+ testJoin();
+ testEqu();
+ testFile();
+ }
+ void testReplace(){
+ ReStringList list;
+
+ list.append("123", 100);
+ checkEqu((int64_t) 100, list.tagOf(0));
+ list.append("2", 200);
+ checkEqu((int64_t) 100, list.tagOf(0));
+ checkEqu((int64_t) 200, list.tagOf(1));
+ list.append("34", 300);
+ checkEqu((int64_t) 100, list.tagOf(0));
+ checkEqu((int64_t) 200, list.tagOf(1));
+ checkEqu((int64_t) 300, list.tagOf(2));
+
+ list.replace(0, "1", 111);
+ checkEqu("1", list.strOf(0));
+ checkEqu((int64_t) 111, list.tagOf(0));
+ checkEqu((int64_t) 200, list.tagOf(1));
+ checkEqu((int64_t) 300, list.tagOf(2));
+
+ list.replace(1, "124", 222);
+ checkEqu("124", list.strOf(1));
+ checkEqu((int64_t) 111, list.tagOf(0));
+ checkEqu((int64_t) 222, list.tagOf(1));
+ checkEqu((int64_t) 300, list.tagOf(2));
+
+ checkEqu((int64_t) 300, list.tagOf(2));
+ list.replaceString(2, "4");
+ checkEqu("4", list.strOf(2));
+ checkEqu((int64_t) 111, list.tagOf(0));
+ checkEqu((int64_t) 222, list.tagOf(1));
+ checkEqu((int64_t) 300, list.tagOf(2));
+
+ list.replaceTag(2, 123);
+ checkEqu("4", list.strOf(2));
+ checkEqu((int64_t) 111, list.tagOf(0));
+ checkEqu((int64_t) 222, list.tagOf(1));
+ checkEqu((int64_t) 123, list.tagOf(2));
+ }
+ void testEqu(){
+ ReStringList list1;
+ ReStringList list2;
+
+ list1.split("1;2;1;3", ';');
+ list2.split("1\n2\n1\n3", '\n');
+ checkEqu(-1, list1.firstDiff(list2));
+ checkEqu(-1, list2.firstDiff(list1));
+ checkT(list1.equal(list2));
+ checkT(list2.equal(list1));
+
+ list1.insert(2, "x");
+ list1.remove(3);
+ checkEqu(2, list1.firstDiff(list2));
+ checkEqu(2, list2.firstDiff(list1));
+ checkF(list1.equal(list2));
+ checkF(list2.equal(list1));
+
+ list2.replace(2, "x");
+ checkEqu(-1, list1.firstDiff(list2));
+ checkEqu(-1, list2.firstDiff(list1));
+ checkT(list1.equal(list2));
+ checkT(list2.equal(list1));
+
+ list2.remove(3);
+ checkEqu(3, list1.firstDiff(list2));
+ checkEqu(3, list2.firstDiff(list1));
+ checkF(list1.equal(list2));
+ checkF(list2.equal(list1));
+
+ list1.replace(0, "");
+ checkEqu(0, list1.firstDiff(list2));
+ checkEqu(0, list2.firstDiff(list1));
+ checkF(list1.equal(list2));
+ checkF(list2.equal(list1));
+
+ list1.clear();
+ list2.clear();
+ checkEqu(-1, list1.firstDiff(list2));
+ checkEqu(-1, list2.firstDiff(list1));
+ checkT(list1.equal(list2));
+ checkT(list2.equal(list1));
+
+ list1.append("fjkdajfdkla");
+ checkEqu(0, list1.firstDiff(list2));
+ checkEqu(0, list2.firstDiff(list1));
+ checkF(list1.equal(list2));
+ checkF(list2.equal(list1));
+ }
+ void testJoin(){
+ ReStringList list;
+ const char* str = "1;abc;xyz;4;;99";
+ list.split(str, ';');
+ checkEqu(6U, list.getCount());
+ checkEqu("1", list.strOf(0));
+ checkEqu("abc", list.strOf(1));
+ checkEqu("xyz", list.strOf(2));
+ checkEqu("4", list.strOf(3));
+ checkEqu("", list.strOf(4));
+ checkEqu("99", list.strOf(5));
+ ReByteBuffer value;
+ list.join(";", value);
+ checkEqu(str, value.str());
+
+ list.split("1\r\n2\n\r3", '\n');
+ checkEqu(3U, list.getCount());
+ checkEqu("1", list.strOf(0));
+ checkEqu("2", list.strOf(1));
+ checkEqu("3", list.strOf(2));
+
+ list.split("xyz\tXYZ", '\t', true);
+ checkEqu(5U, list.getCount());
+ checkEqu("1", list.strOf(0));
+ checkEqu("2", list.strOf(1));
+ checkEqu("3", list.strOf(2));
+ checkEqu("xyz", list.strOf(3));
+ checkEqu("XYZ", list.strOf(4));
+
+
+ }
+ void testFile(){
+ createTestDir();
+ ReByteBuffer file;
+ file.set(getTestDir(), -1).append("abc.csv", -1);
+
+ ReStringList list;
+ const char* str = "1;abc;xyz;4;;99";
+ list.split(str, ';');
+ list.writeToFile(file.str(), "\n");
+
+ ReStringList list2;
+ list2.readFromFile(file.str(), true);
+
+ checkEqu(-1, list2.firstDiff(list2));
+ }
+ void testBase(){
+ ReStringList list;
+ ReByteBuffer value;
+
+ list.append("123", 100);
+ checkEqu(0U, list.indexOf("123"));
+ list.append("a", 200);
+ list.append("vwxyz", 300);
+
+ checkEqu(3U, list.getCount());
+ int index = 0;
+ checkEqu("123", list.strOf(index));
+ checkEqu(4U, list.sizeOf(index));
+ checkEqu((int64_t) 100, list.tagOf(index));
+
+ index++;
+ checkEqu("a", list.strOf(index));
+ checkEqu(2U, list.sizeOf(index));
+ checkEqu((int64_t) 200, list.tagOf(index));
+
+ index++;
+ checkEqu("vwxyz", list.strOf(index));
+ checkEqu(6U, list.sizeOf(index));
+ checkEqu((int64_t) 300, list.tagOf(index));
+
+ checkEqu(12U, list.sumOfSizes());
+
+ list.insert(0, "0", 50);
+ checkEqu(4U, list.getCount());
+ checkEqu(14U, list.sumOfSizes());
+
+ index = 0;
+ checkEqu("0", list.strOf(index));
+ checkEqu(2U, list.sizeOf(index));
+ checkEqu((int64_t) 50, list.tagOf(index));
+
+ index++;
+ checkEqu("123", list.strOf(index));
+ checkEqu(4U, list.sizeOf(index));
+ checkEqu((int64_t) 100, list.tagOf(index));
+
+ index++;
+ checkEqu("a", list.strOf(index));
+ checkEqu(2U, list.sizeOf(index));
+ checkEqu((int64_t) 200, list.tagOf(index));
+
+ index++;
+ checkEqu("vwxyz", list.strOf(index));
+ checkEqu(6U, list.sizeOf(index));
+ checkEqu((int64_t) 300, list.tagOf(index));
+
+ checkEqu(0U, list.indexOf("0"));
+ checkEqu(1U, list.indexOf("123"));
+ checkEqu(2u, list.indexOf("a"));
+ checkEqu(2u, list.indexOf("A", true));
+ checkEqu(3u, list.indexOf("vwxyz"));
+ checkEqu(3u, list.indexOf("VwXyz", true));
+
+ checkEqu(0u, list.indexOf("0", false, 0));
+ checkEqu(1u, list.indexOf("123", false, 1));
+ checkEqu(2u, list.indexOf("a", false, 1));
+ checkEqu(2u, list.indexOf("a", false, 2));
+ checkEqu(2u, list.indexOf("A", true, 2));
+ checkEqu(3u, list.indexOf("vwxyz", false, 2));
+ checkEqu(3u, list.indexOf("vwxyz", false, 3));
+ checkEqu(3u, list.indexOf("VwXyz", true, 3));
+
+ checkEqu((ReStringList::Index) -1, list.indexOf("A"));
+ checkEqu((ReStringList::Index) -1, list.indexOf("0123"));
+ checkEqu((ReStringList::Index) -1, list.indexOf("a", false, 3));
+ checkEqu((ReStringList::Index) -1, list.indexOf("A", true, 3));
+
+ checkEqu(0u, list.nextStartingWith(0, "0"));
+ checkEqu(1u, list.nextStartingWith(0, "12"));
+ checkEqu(2u, list.nextStartingWith(0, "a"));
+ checkEqu(2u, list.nextStartingWith(1, "a"));
+ checkEqu(2u, list.nextStartingWith(2, "a"));
+ checkEqu(2u, list.nextStartingWith(0, "A", true));
+ checkEqu((ReStringList::Index) -1, list.nextStartingWith(2, "Ab", true));
+ checkEqu((ReStringList::Index) -1, list.nextStartingWith(0, "b", true));
+
+ checkEqu(3u, list.nextStartingWith(0, "vwxy", false));
+ checkEqu(3u, list.nextStartingWith(0, "vwxy", true));
+ checkEqu((ReStringList::Index) -1, list.nextStartingWith(0, "vWxY", false));
+
+ ReStringList list2;
+ list2.append("a", 100);
+ list2.append("b", 200);
+ list2.append("c", 300);
+ ReStringList list3;
+ list3.append("x", 1000);
+ list3.append("y", 2000);
+
+ list2.append(list3);
+ checkEqu(5u, list2.getCount());
+ checkEqu("a", list2.strOf(0));
+ checkEqu(100ll, list2.tagOf(0));
+ checkEqu("b", list2.strOf(1));
+ checkEqu(200ll, list2.tagOf(1));
+ checkEqu("c", list2.strOf(2));
+ checkEqu(300ll, list2.tagOf(2));
+ checkEqu("x", list2.strOf(3));
+ checkEqu(1000ll, list2.tagOf(3));
+ checkEqu("y", list2.strOf(4));
+ checkEqu(2000ll, list2.tagOf(4));
+ }
+};
+extern void testReStringList(void);
+
+void testReStringList(void){
+ TestReStringList unit;
+}
+
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReStringUtils : public ReTestUnit {
+public:
+ TestReStringUtils() : ReTestUnit("ReStringUtils", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ testStrnicmp();
+ testIsInList();
+ testSplitPath();
+ }
+ void testStrnicmp(){
+ checkT(ReStringUtils::strnicmp("abc", "abc", 3) == 0);
+ checkT(ReStringUtils::strnicmp("abc", "ab", 3) > 0);
+ checkT(ReStringUtils::strnicmp("ab", "abc", 3) < 0);
+
+ checkT(ReStringUtils::strnicmp("aBc", "Abc", 3) == 0);
+ checkT(ReStringUtils::strnicmp("Abc", "aB", 3) > 0);
+ checkT(ReStringUtils::strnicmp("AB", "abc", 3) < 0);
+
+ checkT(ReStringUtils::strnicmp("ABC", "ABD", 2) == 0);
+ checkT(ReStringUtils::strnicmp("abC", "ABD", 2) == 0);
+
+ checkT(ReStringUtils::strnicmp("AAC", "ABD", 2) < 0);
+ checkT(ReStringUtils::strnicmp("aaC", "ABD", 2) < 0);
+
+ checkT(ReStringUtils::strnicmp("", "x", 99) < 0);
+ checkT(ReStringUtils::strnicmp("x", "", 99) > 0);
+
+ checkT(ReStringUtils::strnicmp("abc", "abc", 99) == 0);
+ checkT(ReStringUtils::strnicmp("abc", "ab", 99) > 0);
+ checkT(ReStringUtils::strnicmp("ab", "abc", 99) < 0);
+ }
+ void testIsInList(){
+ checkT(ReStringUtils::isInList("abc", ";abc;def", true));
+ checkT(ReStringUtils::isInList("aBc", ";abc;def", true));
+ checkF(ReStringUtils::isInList("aBc", ";abc;def", false));
+
+ checkF(ReStringUtils::isInList("aBc", ";abc;def", false));
+
+ checkT(ReStringUtils::isInList("abc", ";a;abc;def", true));
+ checkT(ReStringUtils::isInList("aBc", ";b;abc;def", true));
+ checkF(ReStringUtils::isInList("aBc", ";c;abc;def", false));
+
+ checkF(ReStringUtils::isInList("aBc", ";a;abcabc;def", false));
+
+ checkT(ReStringUtils::isInList("abc", ";abc", true));
+ checkT(ReStringUtils::isInList("aBc", ";abc", true));
+ checkF(ReStringUtils::isInList("aBc", ";abc", false));
+
+ checkF(ReStringUtils::isInList("aBc", ";abc", false));
+
+ }
+ void testSplitPath(){
+ ReByteBuffer fullname, protocol, path, name, ext;
+ const char* fn = "file:/etc/samba/smb.cnf";
+
+ ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
+ checkEqu("file:", protocol.str());
+ checkEqu("/etc/samba/", path.str());
+ checkEqu("smb", name.str());
+ checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
+ checkEqu(fn, fullname.str());
+
+ fn = "/etc/samba/smb.cnf";
+
+ ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
+ checkEqu("", protocol.str());
+ checkEqu("/etc/samba/", path.str());
+ checkEqu("smb", name.str());
+ checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
+ checkEqu(fn, fullname.str());
+
+ fn = "smb.cnf";
+
+ ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
+ checkEqu("", protocol.str());
+ checkEqu("", path.str());
+ checkEqu("smb", name.str());
+ checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
+ checkEqu(fn, fullname.str());
+
+ fn = "smb";
+
+ ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
+ checkEqu("", protocol.str());
+ checkEqu("", path.str());
+ checkEqu("smb", name.str());
+ checkEqu("", ext.str());
+
+ ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
+ checkEqu(fn, fullname.str());
+
+ fn = "file:smb.003.cnf";
+
+ ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
+ checkEqu("file:", protocol.str());
+ checkEqu("", path.str());
+ checkEqu("smb.003", name.str());
+ checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
+ checkEqu(fn, fullname.str());
+
+ fn = "file:/etc.bak/smb";
+
+ ReStringUtils::splitPath(fn, &protocol, &path, &name, &ext);
+ checkEqu("file:", protocol.str());
+ checkEqu("/etc.bak/", path.str());
+ checkEqu("smb", name.str());
+ checkEqu("", ext.str());
+
+ ReStringUtils::joinPath(fullname, &protocol, &path, &name, &ext);
+ checkEqu(fn, fullname.str());
+
+ fn = "file:/etc/samba/smb.cnf";
+
+ ReStringUtils::splitPath(fn, NULL, &path, &name, &ext);
+ checkEqu("file:", protocol.str());
+ checkEqu("smb", name.str());
+ checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, &protocol, NULL, &name, &ext);
+ checkEqu("file:smb.cnf", fullname.str());
+
+ fn = "file:/etc/samba/smb.cnf";
+
+ ReStringUtils::splitPath(fn, NULL, NULL, &name, &ext);
+ checkEqu("smb", name.str());
+ checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, NULL, NULL, &name, &ext);
+ checkEqu("smb.cnf", fullname.str());
+
+ fn = "file:/etc/samba/smb.cnf";
+
+ ReStringUtils::splitPath(fn, NULL, NULL, &name, NULL);
+ //checkEqu("", protocol.str());
+ //checkEqu("/etc/samba/", path.str());
+ checkEqu("smb", name.str());
+ //checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, NULL, NULL, &name, NULL);
+ checkEqu("smb", fullname.str());
+
+ fn = "file:/etc/samba/smb.cnf";
+
+ ReStringUtils::splitPath(fn, NULL, &path, NULL, &ext);
+ //checkEqu("", protocol.str());
+ checkEqu("/etc/samba/", path.str());
+ //checkEqu("smb", name.str());
+ checkEqu(".cnf", ext.str());
+
+ ReStringUtils::joinPath(fullname, NULL, &path, NULL, &ext);
+ checkEqu("/etc/samba/.cnf", fullname.str());
+
+ ReStringUtils::joinPath(fullname, "http:", "//any.de/", "name", ".ext");
+ checkEqu("http://any.de/name.ext", fullname.str());
+
+ ReStringUtils::joinPath(fullname, NULL, "/any.de/", "name", ".ext");
+ checkEqu("/any.de/name.ext", fullname.str());
+
+ ReStringUtils::joinPath(fullname, NULL, NULL, "name", ".ext");
+ checkEqu("name.ext", fullname.str());
+
+ ReStringUtils::joinPath(fullname, NULL, NULL, "name", NULL);
+ checkEqu("name", fullname.str());
+
+ ReStringUtils::joinPath(fullname, "file:", "/", NULL, NULL);
+ checkEqu("file:/", fullname.str());
+ }
+};
+extern void testReStringUtils(void);
+
+void testReStringUtils(void){
+ TestReStringUtils unit;
+}
ReTraverser traverser("/tmp/test");
int level = 0;
const DirStatus_t* entry = traverser.nextFile(level);
- checkEqu("xy12.ab", nameOfEntry(entry));
+ //checkEqu("xy12.ab", nameOfEntry(entry));
}
};
extern void testReTraverser(void);
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReVarArgs : public ReTestUnit, public ReVarArgTrigger {
+public:
+ TestReVarArgs()
+ :
+ ReTestUnit("ReVarArgs", __FILE__),
+ m_argNo(0),
+ m_maxNo(0)
+ {
+ run();
+ }
+ virtual void newArg(int no, int maxNo){
+ m_argNo = no;
+ m_maxNo = maxNo;
+ }
+private:
+ void run(){
+ ReVarArgs list("$1 $$ $2");
+ list.registerTrigger(this);
+
+ list.arg(0).arg(9, "%03u");
+ checkEqu(m_argNo, 2);
+ checkEqu(m_maxNo, 2);
+ checkEqu("0 $ 009", list.asCString());
+
+
+ list.reset("x$1y$2");
+ list.arg(1.5);
+ checkEqu(m_argNo, 1);
+ checkEqu(m_maxNo, 2);
+ list.arg(2.45,"%7.3f");
+ checkEqu(m_argNo, 2);
+ checkEqu(m_maxNo, 2);
+ checkEqu("x1.500000y 2.450", list.asCString());
+
+ list.reset("$2,$1!$3;$4");
+ list.arg("1").arg("ab", 4);
+ list.arg("xy", 0, 1);
+ checkEqu(m_argNo, 3);
+ checkEqu(m_maxNo, 4);
+ list.arg("ww", 5, 0, true);
+ checkEqu(m_argNo, 4);
+ checkEqu(m_maxNo, 4);
+ checkEqu("ab ,1!x; ww", list.asCString());
+ }
+private:
+ int m_argNo;
+ int m_maxNo;
+};
+extern void testReVarArgs(void);
+
+void testReVarArgs(void){
+ TestReVarArgs unit;
+}
--- /dev/null
+#include "base/rebase.hpp"
+
+class TestReConfigFile : public ReTestUnit {
+ typedef ReHashList::Byte Byte;
+public:
+ TestReConfigFile() : ReTestUnit("ReConfigFile", __FILE__){
+ run();
+ }
+private:
+ void run(){
+ testBasic();
+ }
+ void testBasic(){
+ createTestDir();
+ ReByteBuffer fn;
+ fn.append(getTestDir(), -1).append("reconfigfile.cfg", -1);
+ 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());
+ checkEqu(1, config.getInteger("x.int", 2));
+ checkEqu(2, config.getInteger("x.int2", 2));
+
+ checkT(config.getBool("x.bool", true));
+ checkT(config.getBool("x.bool", false));
+ checkT(config.getBool("y.bool", true));
+ checkF(config.getBool("y.bool", false));
+
+ checkF(config.getBool("x.bool2", true));
+ checkF(config.getBool("x.bool2", false));
+
+ ReByteBuffer buffer;
+ config.getString("string", buffer, "x");
+ checkEqu("abc", buffer.str());
+ config.getString("string1", buffer, "x");
+ checkEqu("x", buffer.str());
+ }
+};
+extern void testReConfigFile(void);
+
+void testReConfigFile(void){
+ TestReConfigFile unit;
+}
*/
#include "base/rebase.hpp"
#include "os/reos.hpp"
+#ifdef __RE_TEST__
#include "net/renet.hpp"
+#endif
void testBase(){
extern void testReByteBuffer();
testReStringUtils();
extern void testReString(void);
testReString();
+ extern void testReMatcher();
+ testReMatcher();
}
void testOs(){
void testReTraverser();
- testReTraverser();
+ //testReTraverser();
}
void testAll(){
try
*
* @return The IP address as string.
*/
-const char* ReUdpConnection::getAddress() const {
+const char* ReUdpConnection::address() const {
const char* rc = inet_ntoa(m_address.sin_addr);
return rc;
}
doRead = FD_ISSET(m_socket, &rdset);
}
buffer->ensureSize(8096 + 1);
- size_t size = buffer->getSize();
+ size_t size = buffer->capacity();
buffer->setLength(size);
if (!doRead)
m_logger->sayF(LOG_WARNING|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_RECEIVE_2,
else {
int length = recvfrom(
m_socket,
- buffer->getBuffer(), size - 1, 0,
+ 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(getAddress()).arg(m_port)
- .arg(buffer->getBuffer()).end();
+ "$1:$2 $3").arg(address()).arg(m_port)
+ .arg(buffer->buffer()).end();
}
- return buffer->getLength();
+ return buffer->length();
}
/** @brief Sends a message.
*
if (rc <= 0)
m_logger->sayF(LOG_ERROR|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_SEND_1,
i18n("Sending failed: $1:$2 $3"))
- .arg(getAddress()).arg(m_port).arg(strerror(errno)).end();
+ .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();
*
* @return The internal buffer.
*/
-ReByteBuffer& ReUdpConnection::getBuffer(){
+ReByteBuffer& ReUdpConnection::buffer(){
return m_buffer;
}
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(getAddress()).arg(m_port).end();
+ 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();
answer.setLength(0);
if (canLog(m_buffer))
m_logger->sayF(LOG_INFO|GRAN_USER|CAT_NETWORK, LC_UDPCONNECTION_RUN_1,
- "$1:$2 $3").arg(getAddress()).arg(m_port)
- .arg(m_buffer.getBuffer()).end();
+ "$1:$2 $3").arg(address()).arg(m_port)
+ .arg(m_buffer.buffer()).end();
again = handlePage(m_buffer, answer, *this);
- if (answer.getLength() > 0){
- send(answer.getBuffer(), answer.getLength());
+ if (answer.length() > 0){
+ send(answer.buffer(), answer.length());
}
}
}
ReUdpConnection(bool isServer, ReLogger* logger);
virtual ~ReUdpConnection();
public:
- const char* getAddress() const;
- int getPort() const
+ const char* address() const;
+ 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& getBuffer();
+ ReByteBuffer& buffer();
protected:
int m_socket;
struct sockaddr_in m_address;
-/*
- * ReTraverser.cpp
- *
- * Created on: 23.12.2014
- * Author: hm
- */
-
-#include "../base/rebase.hpp"
-#include "os/reos.hpp"
-
-#ifdef __LINUX__
-#define isUndefHandle(handle) ((handle) == NULL)
-#define findFirstEntry(path, data) opendir(path)
-#define findNextEntry(handle,data) (((data) = readdir(handle)) != NULL)
-#define closeDir(handle) closedir(handle)
-#define initEntryBuffer(entry)
-#define setHandleUndef(h) ((h) = NULL)
-#else
-#define isUndefHandle(handle) ((handle) == INVALID_HANDLE_VALUE)
-#define setHandleUndef(h) ((h) = INVALID_HANDLE_VALUE)
-#define findFirstEntry(path, pattern, data) FindFirstFileA(path, pattern, data)
-#define findNextEntry(handle, data) (FindNextFileA(handle, data) != 0)
-#define closeDir(handle) FindClose(handle)
-#define initEntryBuffer(entry) ((entry)->m_data = &(entry)->m_buffer)
-#endif
-
-/**
- * Constructor.
- */
-ReMatcher::ReMatcher() :
- m_prefix(1),
- m_suffix(1),
- m_tokens(0),
- m_findAll(false),
- m_ignoreCase(true),
- m_notPattern(false)
-{
- memset((void*) m_tokenStart, 0, sizeof m_tokenStart);
- memset((void*) m_tokenEnd, 0, sizeof m_tokenEnd);
- memset((void*) m_tokenLength, 0, sizeof m_tokenLength);
- memset((void*) m_type, 0, sizeof m_type);
-}
-/**
- * Constructor.
- *
- * @param pattern the search pattern
- */
-ReMatcher::ReMatcher(const char* pattern) :
- m_prefix(1),
- m_suffix(1),
- m_tokens(0),
- m_findAll(false),
- m_ignoreCase(true),
- m_notPattern(false)
-{
- memset((void*) m_tokenStart, 0, sizeof m_tokenStart);
- memset((void*) m_tokenEnd, 0, sizeof m_tokenEnd);
- memset((void*) m_tokenLength, 0, sizeof m_tokenLength);
- memset((void*) m_type, 0, sizeof m_type);
- compile(pattern);
-}
-/**
- * Destructor.
- */
-ReMatcher::~ReMatcher(){
-}
-
-/**
- * Compiles the pattern into a internal structure.
- *
- * @param pattern pattern to compile
- * @return <code>true</code>: success<br>
- * <code>false</code>: error occurred
- */
-bool ReMatcher::compile(const char* pattern){
- bool rc = true;
- const char* start = strchr(pattern, '*');
- size_t length = strlen(pattern);
- if (start == NULL){
- m_prefix = pattern;
- m_suffix = pattern;
- } else {
- if (length == 1)
- m_findAll = true;
- else{
- size_t ix = size_t(start - pattern);
- if (start != pattern){
- m_prefix.append(pattern, ix);
- }
- if (ix < length - 1){
- m_suffix.append(start + 1, length - ix);
- }
- }
- }
- return rc;
-}
-/**
- * Tests whether a name matches the pattern stored in the instance.
- *
- * @param name the name to test
- * @return <code>true</code>: ! m_notPattern: the name matches<br>
- * m_notPattern: the name matches not<br>
- * <code>false</code>: otherwise
- */
-bool ReMatcher::match(const char* name){
- bool rc = m_findAll;
- if (! rc){
- size_t width = m_prefix.getLength();
- if (width == 0)
- rc = true;
- else {
- rc = m_ignoreCase ? strncasecmp(name, m_prefix.str(), width) == 0
- : strncmp(name, m_prefix.str(), width) == 0;
- }
- if (rc && (width = m_suffix.getLength()) != 0){
- size_t length = strlen(name);
- rc = length >= m_suffix.getLength();
- if (rc){
- const char* tail = name + length - width;
- rc = m_ignoreCase ? strncasecmp(tail, m_suffix.str(), width) == 0
- : strncmp(tail, m_suffix.str(), width) == 0;
- }
- }
- }
- if (m_notPattern)
- rc = ! rc;
- return rc;
-}
-
-/**
- * Constructor.
- */
-RePatternList::RePatternList() :
- m_patterns(NULL),
- m_count(0)
-{
-}
-/**
- * Destructor.
- */
-RePatternList::~RePatternList(){
- destroy();
-}
-void RePatternList::destroy(){
- if (m_patterns != NULL){
- for (int ix = 0; ix < m_count; ix++){
- delete m_patterns[ix];
- m_patterns[ix] = NULL;
- }
- }
- delete[] m_patterns;
- m_patterns = NULL;
-}
-/**
- * Tests whether a name matches at least one of the patterns.
- * @param name name to test
- * @return <code>true</code>: at least one pattern matches<br>
- * <code>false</code>: no pattern matches
- */
-bool RePatternList::match(const char* name){
- bool rc = false;
- for (int ix = 0; ix < m_count; ix++)
- if (m_patterns[ix]->match(name)){
- rc = true;
- break;
- }
- return rc;
-}
-/**
- * Sets the pattern list from a string.
- *
- * @param patterns a string with one or more patterns
- * @param separator NULL: the first char of <code>patterns</code> is the the separator<br>
- * otherwise: the separator between the patterns
- */
-void RePatternList::set(const char* patterns, const char* separator){
- char buffer[2];
- destroy();
- if (separator == NULL){
- buffer[0] = patterns[0];
- buffer[1] = '\0';
- separator = buffer;
- patterns++;
- }
- const char* start = patterns;
- m_count = 1;
- size_t length = strlen(separator);
- while( (start = strstr(start, separator)) != NULL){
- m_count++;
- start += length;
- }
- m_patterns = new ReMatcher*[m_count];
- int ix = 0;
- start = patterns;
- const char* end;
- while( (end = strstr(start, separator)) != NULL){
- setOne(ix, start, end - start);
- start = end + length;
- ix++;
- }
- setOne(ix, start, strlen(start));
-}
-
-/**
- * Sets one pattern in the pattern list.
- *
- * @param ix index of the pattern in the list
- * @param pattern the pattern string
- * @param patternLength the length of <code>pattern</code>
- */
-void RePatternList::setOne(int ix, const char* pattern, size_t patternLength){
- ReByteBuffer buffer;
- buffer.append(pattern, patternLength);
- m_patterns[ix] = new ReMatcher(buffer.str());
-}
-/**
- * Constructor.
- */
-DirEntryFilter_t::DirEntryFilter_t() :
- m_regulars(true),
- m_specials(true),
- m_directories(true),
- m_nodePatterns(),
- m_pathPatterns(),
- m_minSize(0),
- m_maxSize(-1),
- m_minAge(0),
- m_maxAge(0)
-{
-}
-/**
- *
- */
-bool DirEntryFilter_t::match(DirStatus_t& entry){
- bool rc = false;
- do {
- if (! m_directories && isDirEntry(&entry))
- break;
- if (m_specials && (isDirEntry(&entry) || isRegularEntry(&entry)))
- break;
- if (m_regulars && ! isRegularEntry(&entry))
- break;
- if (m_minSize > 0 && sizeOfEntry(&entry) > m_minSize)
- break;
- if (m_maxSize >= 0 && sizeOfEntry(&entry) < m_maxSize)
- break;
- if (m_minAge != 0 && modifiedOfEntry(&entry) < m_minAge)
- break;
- if (m_maxAge != 0 && modifiedOfEntry(&entry) > m_maxAge)
- break;
- if (m_nodePatterns != NULL && ! m_nodePatterns->match(nameOfEntry(&entry)))
- break;
- if (m_pathPatterns != NULL && ! m_pathPatterns->match(entry.m_path.str()))
- break;
- rc = true;
- } while(false);
- return rc;
-};
-
-/**
- * Returns the status of the current file (lazy loading).
- *
- * @return the status of the current file
- */
-struct stat* DirStatus_t::getStatus() {
- if (m_status.st_ino == 0)
- if (stat(m_data->d_name, &m_status) != 0)
- memset((void*) &m_status, 0, sizeof m_status);
- return &m_status;
-}
-
-/**
- * Constructor.
- *
- * @param base the base directory. The traversal starts at this point
- */
-ReTraverser::ReTraverser(const char* base) :
- m_level(-1),
- m_base(base)
-{
- initEntry(base, 0);
-}
-
-/**
- * Destructor.
- */
-ReTraverser::~ReTraverser() {
-}
-
-/**
- * Returns the info about the next file in the directory tree traversal.
- *
- * @param level OUT: the level relative to the base.<br>
- * 0 means the file is inside the base.<br>
- * Not defined if the result is NULL
- * @return NULL no more files<br>
- * otherwise: the stack entry with the next file in the
- * directory tree. May be a directory too
- */
-DirStatus_t* ReTraverser::rawNextFile(int& level)
-{
- DirStatus_t* rc = NULL;
- bool again = false;
- do{
- if (m_level < 0){
- initEntry(m_base.str(), 0);
- if (! isUndefHandle(m_dirs[0].m_handle))
- rc = &m_dirs[0];
- } else {
- DirStatus_t* current = &m_dirs[level];
- if (findNextEntry(current->m_handle, current->m_data)){
- if (current->m_passNo != m_passNoForDirSearch){
- rc = &m_dirs[m_level];
- } else {
-
- }
- } else {
- if (current->m_passNo == 1){
- initEntry(m_base.str(), m_level);
- current->m_passNo = 2;
- if (! isUndefHandle(m_dirs[0].m_handle))
- rc = &m_dirs[0];
- }
- }
- }
- } while(again);
- return rc;
-}
-/**
- * Returns the info about the next file matching the filter options.
- *
- * @param level OUT: the level relative to the base.<br>
- * 0 means the file is inside the base.<br>
- * Not defined if the result is NULL
- * @param filter NULL: every file matches<br>
- * otherwise: each found file must match this filter conditions
- * @return NULL no more files<br>
- * otherwise: the info about the next file in the
- * directory tree
- */
-DirStatus_t* ReTraverser::nextFile(int& level, DirEntryFilter_t* filter){
- DirStatus_t* rc = rawNextFile(level);
- while (rc != NULL){
- if (filter == NULL || filter->match(*rc)){
- break;
- }
- }
- return rc;
-}
-
-/**
- * Initializes an entry in the directory entry stack.
- *
- * @param path the name of the directory belonging to the entry
- * @param level the index of the entry in the stack
- */
-void ReTraverser::initEntry(const char* path, int level){
- if (level < MAX_ENTRY_STACK_DEPTH){
- DirStatus_t* current = &m_dirs[level];
- initEntryBuffer(current);
- current->m_handle = findFirstEntry(path, &m_current->m_data);
- m_level = level;
- }
-}
-
-/**
- * Frees the resources of an entry of the directory entry stack.
- *
- * @param level the index of the entry in the stack
- */
-void ReTraverser::freeEntry(int level){
- if (level < MAX_ENTRY_STACK_DEPTH){
- DirStatus_t* current = &m_dirs[level];
- if (! isUndefHandle(current->m_handle)){
- closeDir(current->m_handle);
- setHandleUndef(current->m_handle);
- }
- current->m_path.setLength(0);
- }
-}
-
+/*\r
+ * ReTraverser.cpp\r
+ *\r
+ * Created on: 23.12.2014\r
+ * Author: hm\r
+ */\r
+\r
+#include "base/rebase.hpp"\r
+#include "os/reos.hpp"\r
+\r
+#ifdef __linux__\r
+const char ReTraverser::m_separator = '/';\r
+const char* const ReTraverser::m_separatorStr = "/";\r
+#elif defined __WIN32__\r
+const char ReTraverser::m_separator = '\\';\r
+const char* const ReTraverser::m_separatorStr = "\\";\r
+#endif\r
+\r
+#ifdef __linux__\r
+#define isUndefHandle(handle) ((handle) == NULL)\r
+#define findFirstEntry(path, data) opendir(path)\r
+#define findNextEntry(handle,data) (((data) = readdir(handle)) != NULL)\r
+#define closeDir(handle) closedir(handle)\r
+#define initEntryBuffer(entry)\r
+#define setHandleUndef(h) ((h) = NULL)\r
+#else\r
+#define isUndefHandle(handle) ((handle) == INVALID_HANDLE_VALUE)\r
+#define setHandleUndef(h) ((h) = INVALID_HANDLE_VALUE)\r
+HANDLE findFirstEntry(const char* path, DirInfoStruct_t* data){\r
+ ReByteBuffer thePath(path);\r
+ thePath.append("\\*");\r
+ HANDLE rc = FindFirstFileA(thePath.str(), data);\r
+ return rc;\r
+}\r
+#define findNextEntry(handle, data) (FindNextFileA(handle, data) != 0)\r
+#define closeDir(handle) FindClose(handle)\r
+#define initEntryBuffer(entry) ((entry)->m_data = &(entry)->m_dataBuffer)\r
+#endif\r
+\r
+const char* DirStatus_t::nameOfEntry() const{\r
+#ifdef __linux__\r
+ return m_data->d_name;\r
+#elif defined __WIN32__\r
+ return m_data->cFileName;\r
+#endif\r
+}\r
+bool DirStatus_t::isDirectory() {\r
+#ifdef __linux__\r
+ return (m_data->d_type != DT_UNKNOWN && m_data->d_type == DT_DIR) || S_ISDIR(getStatus()->st_mode);\r
+#elif defined __WIN32__\r
+ return 0 != (m_dataBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);\r
+#endif\r
+}\r
+bool DirStatus_t::isLink() {\r
+ bool rc;\r
+#ifdef __linux__\r
+ rc = (m_data->d_type != DT_UNKNOWN && m_data->d_type == DT_LNK) || S_ISLNK(getStatus()->st_mode);\r
+#elif defined __WIN32__\r
+ rc = 0 != (m_dataBuffer.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT);\r
+#endif\r
+ return rc;\r
+}\r
+bool DirStatus_t::isRegular() {\r
+#ifdef __linux__\r
+ return (m_data->d_type != DT_UNKNOWN && m_data->d_type == DT_REG) || S_ISREG(getStatus()->st_mode);\r
+#elif defined __WIN32__\r
+ return 0 != (m_dataBuffer.dwFileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE));\r
+#endif\r
+}\r
+FileSize_t DirStatus_t::fileSize() {\r
+#ifdef __linux__\r
+ return getStatus()->st_size;\r
+#elif defined __WIN32__\r
+ return ((int64_t) m_dataBuffer.nFileSizeHigh << 32) + m_dataBuffer.nFileSizeLow;\r
+#endif\r
+}\r
+const FileTime_t* DirStatus_t::modified() {\r
+#ifdef __linux__\r
+ return &(getStatus()->st_mtime);\r
+#elif defined __WIN32__\r
+ return &m_dataBuffer.ftLastWriteTime;\r
+#endif\r
+}\r
+\r
+time_t DirStatus_t::filetimeToTime(const FileTime_t* filetime){\r
+#ifdef __linux__\r
+ return *filetime;\r
+#elif defined __WIN32__\r
+ // takes the last modified date\r
+ LARGE_INTEGER date, adjust;\r
+ date.HighPart = filetime->dwHighDateTime;\r
+ date.LowPart = filetime->dwLowDateTime;\r
+ // 100-nanoseconds = milliseconds * 10000\r
+ adjust.QuadPart = 11644473600000 * 10000;\r
+ // removes the diff between 1970 and 1601\r
+ date.QuadPart -= adjust.QuadPart;\r
+ // converts back from 100-nanoseconds to seconds\r
+ return (time_t) (date.QuadPart / 10000000);\r
+#endif\r
+}\r
+\r
+void DirStatus_t::timeToFiletime(time_t time, FileTime_t& filetime){\r
+#ifdef __linux__\r
+ filetime = time;\r
+#elif defined __WIN32__\r
+ LONGLONG ll = Int32x32To64(time, 10000000) + 116444736000000000;\r
+ filetime.dwLowDateTime = (DWORD)ll;\r
+ filetime.dwHighDateTime = ll >> 32;;\r
+#endif\r
+}\r
+\r
+/**\r
+ * Constructor.\r
+ */\r
+DirEntryFilter_t::DirEntryFilter_t() :\r
+ m_regulars(true),\r
+ m_specials(true),\r
+ m_directories(true),\r
+ m_nodePatterns(),\r
+ m_pathPatterns(),\r
+ m_minSize(0),\r
+ m_maxSize(-1),\r
+ m_minAge(),\r
+ m_maxAge()\r
+{\r
+}\r
+/**\r
+ *\r
+ */\r
+bool DirEntryFilter_t::match(DirStatus_t& entry){\r
+ bool rc = false;\r
+ do {\r
+ if (! m_directories && entry.isDirectory())\r
+ break;\r
+ if (m_specials && (entry.isDirectory() || entry.isRegular()))\r
+ break;\r
+ if (m_regulars && ! entry.isRegular())\r
+ break;\r
+ if (m_minSize > 0 && entry.fileSize() > m_minSize)\r
+ break;\r
+ if (m_maxSize >= 0 && entry.fileSize() < m_maxSize)\r
+ break;\r
+ if (m_minAge != 0 && DirStatus_t::filetimeToTime(entry.modified()) < m_minAge)\r
+ break;\r
+ if (m_maxAge != 0 && DirStatus_t::filetimeToTime(entry.modified()) > m_maxAge)\r
+ break;\r
+ if (m_nodePatterns != NULL && ! m_nodePatterns->match(entry.nameOfEntry()))\r
+ break;\r
+ if (m_pathPatterns != NULL && ! m_pathPatterns->match(entry.m_path.str()))\r
+ break;\r
+ rc = true;\r
+ } while(false);\r
+ return rc;\r
+};\r
+\r
+#ifdef __linux__\r
+/**\r
+ * Returns the status of the current file (lazy loading).\r
+ *\r
+ * @return the status of the current file\r
+ */\r
+struct stat* DirStatus_t::getStatus() {\r
+ if (m_status.st_ino == 0)\r
+ if (stat(m_data->d_name, &m_status) != 0)\r
+ memset((void*) &m_status, 0, sizeof m_status);\r
+ return &m_status;\r
+}\r
+#endif\r
+\r
+/**\r
+ * Constructor.\r
+ *\r
+ * @param base the base directory. The traversal starts at this point\r
+ */\r
+ReTraverser::ReTraverser(const char* base) :\r
+ m_level(-1),\r
+ m_base(base)\r
+{\r
+ initEntry(base, 0);\r
+}\r
+\r
+/**\r
+ * Destructor.\r
+ */\r
+ReTraverser::~ReTraverser() {\r
+}\r
+\r
+/**\r
+ * Returns the info about the next file in the directory tree traversal.\r
+ *\r
+ * @param level OUT: the level relative to the base.<br>\r
+ * 0 means the file is inside the base.<br>\r
+ * Not defined if the result is NULL\r
+ * @return NULL no more files<br>\r
+ * otherwise: the stack entry with the next file in the\r
+ * directory tree. May be a directory too\r
+ */\r
+DirStatus_t* ReTraverser::rawNextFile(int& level)\r
+{\r
+ DirStatus_t* rc = NULL;\r
+ bool again = false;\r
+ do{\r
+ if (m_level < 0){\r
+ // first call:\r
+ initEntry(m_base.str(), 0);\r
+ if (! isUndefHandle(m_dirs[0].m_handle))\r
+ rc = &m_dirs[0];\r
+ } else {\r
+ DirStatus_t* current = &m_dirs[level];\r
+ if (findNextEntry(current->m_handle, current->m_data)){\r
+ // a file or directory found:\r
+ if (current->m_passNo != m_passNoForDirSearch){\r
+ // we search for any file:\r
+ rc = &m_dirs[m_level];\r
+ } else {\r
+ // we are interested only in subdirectories:\r
+ again = true;\r
+ if (rc->isDirectory()){\r
+ // open a new level:\r
+ level++;\r
+ m_base.append(ReTraverser::m_separatorStr);\r
+ m_base.append(rc->nameOfEntry());\r
+ initEntry(m_base.str(), level + 1);\r
+ }\r
+ }\r
+ } else {\r
+ // the current subdir does not have more files:\r
+ if (current->m_passNo == 1){\r
+ // we start the second pass:\r
+ initEntry(m_base.str(), m_level);\r
+ current->m_passNo = 2;\r
+ if (! isUndefHandle(m_dirs[0].m_handle))\r
+ rc = &m_dirs[0];\r
+ else\r
+ again = true;\r
+ } else {\r
+ // this subdirectory is complete. We go to the parent directory:\r
+ closeDir(current->m_handle);\r
+ setHandleUndef(current->m_handle);\r
+ if (--level > 0){\r
+ again = true;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ } while(again);\r
+ return rc;\r
+}\r
+/**\r
+ * Returns the info about the next file matching the filter options.\r
+ *\r
+ * @param level OUT: the level relative to the base.<br>\r
+ * 0 means the file is inside the base.<br>\r
+ * Not defined if the result is NULL\r
+ * @param filter NULL: every file matches<br>\r
+ * otherwise: each found file must match this filter conditions\r
+ * @return NULL no more files<br>\r
+ * otherwise: the info about the next file in the\r
+ * directory tree\r
+ */\r
+DirStatus_t* ReTraverser::nextFile(int& level, DirEntryFilter_t* filter){\r
+ DirStatus_t* rc = rawNextFile(level);\r
+ while (rc != NULL){\r
+ if (filter == NULL || filter->match(*rc)){\r
+ break;\r
+ }\r
+ rc = rawNextFile(level);\r
+ }\r
+ return rc;\r
+}\r
+\r
+/**\r
+ * Initializes an entry in the directory entry stack.\r
+ *\r
+ * @param path the name of the directory belonging to the entry\r
+ * @param level the index of the entry in the stack\r
+ */\r
+void ReTraverser::initEntry(const char* path, int level){\r
+ if (level < MAX_ENTRY_STACK_DEPTH){\r
+ DirStatus_t* current = &m_dirs[level];\r
+ initEntryBuffer(current);\r
+ current->m_handle = findFirstEntry(path, current->m_data);\r
+ if (! isUndefHandle(current->m_handle)){\r
+ current->m_path.set(path, -1);\r
+ }\r
+ m_level = level;\r
+ }\r
+}\r
+\r
+/**\r
+ * Frees the resources of an entry of the directory entry stack.\r
+ *\r
+ * @param level the index of the entry in the stack\r
+ */\r
+void ReTraverser::freeEntry(int level){\r
+ if (level < MAX_ENTRY_STACK_DEPTH){\r
+ DirStatus_t* current = &m_dirs[level];\r
+ if (! isUndefHandle(current->m_handle)){\r
+ closeDir(current->m_handle);\r
+ setHandleUndef(current->m_handle);\r
+ }\r
+ current->m_path.setLength(0);\r
+ }\r
+}\r
+\r
#ifndef OS_RETRAVERSER_HPP_
#define OS_RETRAVERSER_HPP_
-#ifdef __LINUX__
+#include "string/ReMatcher.hpp"
+#ifdef __linux__
#include <sys/types.h>
#include <sys/stat.h>
typedef DIR* FindFileHandle_t;
typedef __off_t FileSize_t;
typedef struct dirent DirInfoStruct_t;
+typedef time_t FileTime_t;
+#if 0
#define nameOfEntry(entry) ((entry)->m_data->d_name)
#define isDirEntry(entry) (((entry)->m_data->d_type != DT_UNKNOWN && (entry)->m_data->d_type == DT_DIR) \
|| S_ISDIR((entry)->getStatus()->st_mode))
|| S_ISREG((entry)->getStatus()->st_mode))
#define sizeOfEntry(entry) ((entry)->getStatus()->st_size)
#define modifiedOfEntry(entry) ((entry)->getStatus()->st_mtime)
+#endif
#else
typedef int64_t FileSize_t;
+typedef FILETIME FileTime_t;
typedef HANDLE FindFileHandle_t;
typedef WIN32_FIND_DATAA DirInfoStruct_t;
-#define nameOfEntry(entry) ((entry)->m_data->d_name)
-#define isDirEntry(data) (data.getStatus()) & )
#endif
class DirStatus_t{
+public:
+ const char* nameOfEntry() const;
+ bool isDirectory();
+ bool isLink();
+ bool isRegular();
+ FileSize_t fileSize();
+ const FileTime_t* modified();
public:
ReByteBuffer m_path;
DirInfoStruct_t* m_data;
FindFileHandle_t m_handle;
int m_passNo;
-#if defined __LINUX__
+#if defined __linux__
struct stat m_status;
public:
struct stat* getStatus();
#elif defined WIN32
- DirInfoStruct_t m_buffer;
+ // the buffer for m_data:
+ DirInfoStruct_t m_dataBuffer;
#endif
-
-};
-#define MAX_MATCHER_TOKEN 32
-class ReMatcher {
-public:
- enum TokenType_t {
- TT_UNDEF,
- TT_STRING,
- TT_STAR,
- TT_ONE_CHAR,
- TT_CHAR_CLASS
- };
public:
- ReMatcher();
- ReMatcher(const char* pattern);
- ~ReMatcher();
-public:
- bool compile(const char* pattern);
- bool match(const char* name);
-private:
- ReByteBuffer m_prefix;
- ReByteBuffer m_suffix;
- ReByteBuffer m_pattern;
- int m_tokenStart[MAX_MATCHER_TOKEN];
- int m_tokenEnd[MAX_MATCHER_TOKEN];
- int m_tokenLength[MAX_MATCHER_TOKEN];
- TokenType_t m_type[MAX_MATCHER_TOKEN];
- int m_tokens;
- bool m_findAll;
- bool m_ignoreCase;
- bool m_notPattern;
-};
-class RePatternList{
-public:
- RePatternList();
- ~RePatternList();
-public:
- void destroy();
- bool match(const char* pattern);
- void set(const char* patterns, const char* separator = NULL);
-private:
- void setOne(int ix, const char* pattern, size_t patternLength);
-private:
- ReMatcher** m_patterns;
- int m_count;
+ static time_t filetimeToTime(const FileTime_t* time);
+ static void timeToFiletime(time_t time, FileTime_t& filetime);
};
class DirEntryFilter_t {
public:
/// each directory will be passed twice: for all files + for directories only
/// 1: depth first 2: breadth first
int m_passNoForDirSearch;
+public:
+ static const char m_separator;
+ static const char* const m_separatorStr;
};
#endif /* OS_RETRAVERSER_HPP_ */
#ifndef OS_REOS_HPP_
#define OS_REOS_HPP_
-#define __LINUX__
-#if defined __LINUX__
+
+#if defined __linux__
#include "unistd.h"
#include <dirent.h>
-#elif defined WIN32
+#elif defined __WIN32__
#include <tchar.h>
#include "windows.h"
+#include <winnt.h>
#else
#error "unknown os"
#endif
--- /dev/null
+/*
+ * ReMatcher.cpp
+ *
+ * Created on: 25.12.2014
+ * Author: hm
+ */
+
+#include "base/rebase.hpp"
+#include "string/ReMatcher.hpp"
+
+#ifdef __linux__
+extern int strncasecmp (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);
+#endif
+
+/**
+ * Constructor.
+ */
+ReMatcher::ReMatcher() :
+ m_findAll(false),
+ m_ignoreCase(true),
+ m_notPattern(false)
+{
+}
+
+/**
+ * Destructor
+ */
+ReMatcher::~ReMatcher() {
+}
+
+/**
+ * Constructor.
+ */
+ReSimpleMatcher::ReSimpleMatcher() :
+ ReMatcher(),
+ m_pattern(),
+ m_tokens()
+{
+}
+
+
+/**
+ * Constructor.
+ *
+ * @param pattern the search pattern
+ */
+ReSimpleMatcher::ReSimpleMatcher(const char* pattern) :
+ ReMatcher(),
+ m_pattern(),
+ m_tokens()
+{
+ compile(pattern);
+}
+/**
+ * Destructor.
+ */
+ReSimpleMatcher::~ReSimpleMatcher(){
+}
+
+/**
+ * Compiles the pattern into a internal structure.
+ *
+ * @param pattern pattern to compile
+ * @return <code>true</code>: success<br>
+ * <code>false</code>: error occurred
+ */
+bool ReSimpleMatcher::compile(const char* pattern){
+ bool rc = true;
+ m_pattern.set(pattern, -1);
+ if (strcmp(pattern, "*") == 0){
+ m_findAll = true;
+ } else {
+ m_tokens.split(pattern, '*');
+ }
+ return rc;
+}
+/**
+ * Tests whether a name matches the pattern stored in the instance.
+ *
+ * This method is anchored: search always starts at the begin of <code>name</code>.
+ * @param toTest the string to test
+ * @param hit OUT: hit data. May be NULL
+ * @return <code>true</code>: ! m_notPattern: the name matches<br>
+ * m_notPattern: the name matches not<br>
+ * <code>false</code>: otherwise
+ */
+bool ReSimpleMatcher::match(const ReByteBuffer& toTest, ReHit* hit) const{
+ bool rc = m_findAll;
+ if (! rc){
+ do {
+ size_t length0 = m_tokens.strLengthOf(0);
+ // Does the anchor match?
+ if (length0 > 0 && ! toTest.startsWith(m_tokens.strOf(0), length0,
+ m_ignoreCase)){
+ break;
+ }
+ // Does the tail match?
+ int last = m_tokens.getCount() - 1;
+ if (last == 0){
+ rc = true;
+ break;
+ }
+ size_t lengthLast = m_tokens.strLengthOf(last);
+ if (lengthLast > 0 && ! toTest.endsWith(m_tokens.strOf(last),
+ lengthLast, m_ignoreCase)){
+ break;
+ }
+ // only anchor and tail?
+ if (last == 1){
+ rc = true;
+ break;
+ }
+ rc = searchTokens(toTest, 1, last - 1, hit, false);
+ } while(false);
+ }
+ if (m_notPattern)
+ rc = ! rc;
+ return rc;
+}
+
+/**
+ * Search all tokens from a given index.
+ *
+ * This method may be recursive (if greedy).
+ *
+ * @param name the name to test
+ * @param index the index of the first token to find
+ * @param hit OUT: hit data. May be NULL
+ * @param greedy <code>true</code>: the longest possible match will be found<br>
+ * <code>false</code>: the shortest possible match will be found
+ * @return <code>true</code>: ! m_notPattern: the name matches<br>
+ * m_notPattern: the name matches not<br>
+ * <code>false</code>: otherwise
+ */
+bool ReSimpleMatcher::searchTokens(const ReByteBuffer& toTest, int from, int to,
+ ReHit* hit, bool greedy) const{
+ bool rc = true;
+ if (! greedy){
+ int current = 0;
+ for (int ix = from; ix <= to; ix++){
+ size_t length = m_tokens.strLengthOf(ix);
+ if (length == 0)
+ continue;
+ current = toTest.indexOf(m_tokens.strOf(ix), length, current, -1,
+ m_ignoreCase);
+ if (current < 0){
+ rc = false;
+ break;
+ }
+ if (hit != NULL){
+ hit->setStart(current);
+ hit->setEnd(current + length);
+ }
+ }
+ } else {
+ assert(false);
+ }
+ return rc;
+}
+/**
+ * Tests whether a name matches the pattern stored in the instance.
+ *
+ * This method is not anchored: the pattern may be located anywhere
+ * in the <code>name</code>.
+ * @param name the name to test
+ * @param hit OUT: hit data. May be NULL
+ * @param greedy <code>true</code>: the longest possible match will be found<br>
+ * <code>false</code>: the shortest possible match will be found
+ * @return <code>true</code>: ! m_notPattern: the name matches<br>
+ * m_notPattern: the name matches not<br>
+ * <code>false</code>: otherwise
+ */
+bool ReSimpleMatcher::search(const ReByteBuffer& toTest, ReHit* hit, bool greedy) const{
+ bool rc = m_findAll;
+ if (! rc){
+ size_t last = m_tokens.getCount();
+ size_t length0 = m_tokens.strLengthOf(0);
+ size_t lengthLast = m_tokens.strLengthOf(last);
+ rc = searchTokens(toTest, length0 == 0 ? 1 : 0,
+ lengthLast == 0 ? last - 1 : last, hit, greedy);
+ }
+ if (m_notPattern)
+ rc = ! rc;
+ return rc;
+}
+
+/**
+ * Constructor.
+ */
+RePatternList::RePatternList() :
+ m_patterns(NULL),
+ m_count(0)
+{
+}
+/**
+ * Destructor.
+ */
+RePatternList::~RePatternList(){
+ destroy();
+}
+void RePatternList::destroy(){
+ if (m_patterns != NULL){
+ for (int ix = 0; ix < m_count; ix++){
+ delete m_patterns[ix];
+ m_patterns[ix] = NULL;
+ }
+ }
+ delete[] m_patterns;
+ m_patterns = NULL;
+}
+/**
+ * Tests whether a name matches at least one of the patterns.
+ *
+ * <pre>Examples:
+ * list: ";*.cpp;^test*;*.hpp"
+ * returns true: "a.cpp" "xy.hpp"
+ * returns false: "x.img", "test.cpp"
+ * </pre>
+ *
+ * @param name name to test
+ * @return <code>true</code>: at least one pattern matches and no
+ * "not-pattern" matches<br>
+ * <code>false</code>: no pattern matches or at least one
+ * "not-pattern" matches
+ */
+bool RePatternList::match(const char* name){
+ bool rc = false;
+ int count = m_startNot < 0 ? m_count : m_count - m_startNot + 1;
+ // matches at least one positive pattern?
+ for (int ix = 0; ix < count; ix++)
+ if (m_patterns[ix]->match(name)){
+ rc = true;
+ break;
+ }
+ if (rc && m_startNot >= 0){
+ for (int ix = m_startNot; ix < m_count; ix++)
+ if (m_patterns[ix]->match(name)){
+ rc = false;
+ break;
+ }
+ }
+ return rc;
+}
+/**
+ * Sets the pattern list from a string.
+ *
+ * @param patterns a string with one or more patterns
+ * @param ignoreCase <code>true</code>: the search will be case insensitive<br>
+ * <code>false</code>: the search will be case sensitive
+ * @param separator NULL: the first char of <code>patterns</code> is the the separator<br>
+ * otherwise: the separator between the patterns
+ * @param notPrefix if this prefix starts a pattern, the result of a search
+ * will be reversed: found returns <code>false</code><br>
+ * NULL: no not prefix exists
+ */
+void RePatternList::set(const char* patterns, bool ignoreCase,
+ const char* separator, const char* notPrefix){
+ char buffer[2];
+ destroy();
+ if (separator == NULL){
+ buffer[0] = patterns[0];
+ buffer[1] = '\0';
+ separator = buffer;
+ patterns++;
+ }
+ int sepLength = strlen(separator);
+ ReByteBuffer theNotPattern(notPrefix == NULL ? "" : notPrefix);
+ ReByteBuffer thePatterns(patterns);
+ if (thePatterns.endsWith(separator)){
+ thePatterns.setLength(thePatterns.length() - sepLength);
+ }
+ m_count = thePatterns.count(separator) + 1;
+ m_patterns = new ReSimpleMatcher*[m_count];
+ m_startNot = m_count;
+ int ixInsert = 0;
+ int current = 0;
+ int last = 0;
+ while( (current = thePatterns.indexOf(separator, sepLength, last)) != -1){
+ ixInsert = setOne(ixInsert, thePatterns.str() + last, current - last, ignoreCase,
+ theNotPattern);
+ last = current + sepLength;
+ }
+ setOne(ixInsert, patterns + last, strlen(thePatterns.str() + last),
+ ignoreCase, theNotPattern);
+ if (m_startNot >= m_count)
+ m_startNot = -1;
+}
+
+/**
+ * Sets one pattern in the pattern list.
+ *
+ * @param index index of the pattern in the list (if not a "not pattern")
+ * @param pattern the pattern string
+ * @param patternLength the length of <code>pattern</code>
+ * @param ignoreCase <code>true</code>: the search will be case insensitive<br>
+ * <code>false</code>: the search will be case sensitive
+ * @param notPrefix if this prefix starts a pattern, the result of a search
+ * will be reversed: found returns <code>false</code><br>
+ * NULL: no not prefix exists
+ * @return ix: the pattern was a "not pattern"<br>
+ * ix + 1: otherwise
+ */
+int RePatternList::setOne(int index, const char* pattern, size_t patternLength,
+ bool ignoreCase, const ReByteBuffer& notPrefix){
+ ReByteBuffer thePattern (pattern, patternLength);
+ bool isNotPattern = (notPrefix.length() > 0
+ && thePattern.startsWith(notPrefix.str(), notPrefix.length()));
+ int start = isNotPattern ? notPrefix.length() : 0;
+ // not patterns will be inserted at the bottom:
+ int ix = isNotPattern ? --m_startNot : index;
+ m_patterns[ix] = new ReSimpleMatcher(thePattern.str() + start);
+ m_patterns[ix]->setIgnoreCase(ignoreCase);
+ return isNotPattern ? index: index + 1;
+}
--- /dev/null
+/*
+ * ReMatcher.hpp
+ *
+ * Created on: 25.12.2014
+ * Author: hm
+ */
+
+#ifndef STRING_REMATCHER_HPP_
+#define STRING_REMATCHER_HPP_
+
+class ReHit {
+public:
+ ReHit();
+
+ inline int getEnd() const {
+ return m_end;
+ }
+
+ inline void setEnd(int end) {
+ m_end = end;
+ }
+
+ inline int getStart() const {
+ return m_start;
+ }
+
+ inline void setStart(int start) {
+ m_start = start;
+ }
+private:
+ int m_start;
+ int m_end;
+};
+
+class ReMatcher {
+public:
+ ReMatcher();
+ virtual ~ReMatcher();
+public:
+ virtual bool compile(const char* pattern) = 0;
+ virtual bool match(const ReByteBuffer& toTest, ReHit* hit = NULL) const = 0;
+ virtual bool search(const ReByteBuffer& toTest, ReHit* hit = NULL,
+ bool greedy = false) const = 0;
+public:
+ inline bool isIgnoreCase() const {
+ return m_ignoreCase;
+ }
+
+ inline void setIgnoreCase(bool ignoreCase) {
+ m_ignoreCase = ignoreCase;
+ }
+
+ inline bool isNotPattern() const {
+ return m_notPattern;
+ }
+
+ inline void setNotPattern(bool notPattern) {
+ m_notPattern = notPattern;
+ }
+
+protected:
+ bool m_findAll;
+ bool m_ignoreCase;
+ bool m_notPattern;
+};
+
+class ReSimpleMatcher: public ReMatcher {
+public:
+ ReSimpleMatcher();
+ ReSimpleMatcher(const char* pattern);
+ virtual ~ReSimpleMatcher();
+public:
+ virtual bool compile(const char* pattern);
+ virtual bool match(const ReByteBuffer& toTest, ReHit* hit = NULL) const;
+ virtual bool search(const ReByteBuffer& toTest, ReHit* hit = NULL,
+ bool greedy = false) const;
+protected:
+ bool searchTokens(const ReByteBuffer& toTest, int from, int to,
+ ReHit* hit, bool greedy) const;
+private:
+ ReByteBuffer m_pattern;
+ ReStringList m_tokens;
+};
+
+class RePatternList{
+public:
+ RePatternList();
+ ~RePatternList();
+public:
+ void destroy();
+ bool match(const char* pattern);
+ void set(const char* patterns, bool ignoreCase = false,
+ const char* separator = NULL, const char* notPrefix = "^");
+private:
+ int setOne(int index, const char* pattern, size_t patternLength,
+ bool ignoreCase, const ReByteBuffer& notPrefix);
+private:
+ // store of all patterns: the not patterns are at the bottom
+ ReSimpleMatcher** m_patterns;
+ // count of all patterns (including not patterns:
+ int m_count;
+ // index of the first not pattern. If -1: not "not pattern":
+ int m_startNot;
+};
+
+#endif /* STRING_REMATCHER_HPP_ */
--- /dev/null
+/*
+ * restring.hpp
+ *
+ * Created on: 25.12.2014
+ * Author: hm
+ */
+
+#ifndef STRING_RESTRING_HPP_
+#define STRING_RESTRING_HPP_
+
+#include "string/ReMatcher.hpp"
+
+#endif /* STRING_RESTRING_HPP_ */