#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 _memcmp (const void* s1, const void* s2, size_t n);
extern int snprintf (char* s, size_t maxlen, const char* format, ...);
#endif
m_capacity = size;
}
}
+
+/** @brief Checks for the index of the first different byte.
+ *
+ * @param source source to inspect
+ * @param length -1 or the length of <code>source</code>
+ * @param start the first index to inspect
+ * @param ignoreCase <code>true</code>: the comparison is case insensitive
+ * @return -1: both byte sequences are equal<br>
+ * otherwise: the index of the first difference
+ */
+int ReByteBuffer::firstDifference(const Byte* source, size_t length, int start, bool ignoreCase){
+ int rc = -1;
+ if (start < 0)
+ rc = 0;
+ else if (start < m_length){
+ if (length == -1)
+ length = strlen(source);
+ int count = length > m_length - start ? m_length - start : length;
+ const Byte* ptr = m_buffer + start;
+ for (int ix = 0; rc < 0 && ix < count; ix++){
+ if ((! ignoreCase && *ptr++ != *source++)
+ || ignoreCase && (tolower(*ptr++) != tolower(*source++)))
+ rc = start + ix;
+ }
+ if (rc < 0 && length > m_length - start)
+ rc = start + count;
+ }
+ return rc;
+}
+
/** @brief Searches for a byte sequence in the internal buffer.
*
* Finds the first occurrence of a byte sequence in a given range.
if (start >= 0 && start <= int(m_length - toFindLength)
&& end >= (int) toFindLength && end <= (int) m_length){
while(rc < 0 && start <= int(end - toFindLength)){
- if (ignoreCase ? memicmp((void*) toFind, (void*) (m_buffer + start),
+ if (ignoreCase ? _memicmp((void*) toFind, (void*) (m_buffer + start),
toFindLength) == 0
- : memcmp(toFind, m_buffer + start, toFindLength) == 0)
+ : _memcmp(toFind, m_buffer + start, toFindLength) == 0)
rc = start;
else
start++;
&& 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)
+ if (ignoreCase ? _strnicmp(toFind, m_buffer + current, toFindLength) != 0
+ : _memcmp(toFind, m_buffer + current, toFindLength) != 0)
current--;
else{
rc = current;
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* buffer() const{
return m_buffer;
}
+ /**@brief Returns the current size of the internal buffer.
+ * @return The current size of the internal buffer.
+ */
+ inline size_t capacity() const{
+ return m_capacity;
+ }
int count(const char* toCount, size_t lengthToCount = -1);
/**@brief Returns the minimum allocation unit.
* @return The minimum of bytes to allocate.
inline size_t delta() const{
return m_delta;
}
+ bool endsWith(const Byte* tail, size_t tailLength = -1,
+ bool ignoreCase = false) const;
+ void ensureSize(size_t size);
/** @brief Tests whether another instance is equal to this instance.
* @param buffer the buffer to compare
* @return <code>true</code>: the buffer's contents are equal
*/
inline bool equals(const ReByteBuffer& buffer){
- bool rc = buffer.length() == m_length && memcmp(buffer.str(), m_buffer, m_length) == 0;
+ bool rc = buffer.length() == m_length && _memcmp(buffer.str(), m_buffer, m_length) == 0;
return rc;
}
- /**@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 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 capacity() const{
- return m_capacity;
- }
+ int firstDifference(const Byte* source, size_t length, int start = 0, bool ignoreCase = false);
/** @brief Finds the index of the first occurrence of a given byte.
* @param toFind This byte will be searched.
* @param start The first index for searching.
inline bool insert(size_t ix, const Byte* source, size_t length){
return splice(ix, 0, source, length);
}
+ /**@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 length() const{
+ return m_length;
+ }
/** @brief Cuts a sequence from the internal buffer.
*
* @param ix The index where the cut/insertion takes place.
void replaceSubstring(char* start, size_t bufferSize, size_t lengthReplaced,
const char* newString);
#if defined __linux__
-int memicmp(const void* region1, const void* region2, int size);
+int _memicmp(const void* region1, const void* region2, int size);
#endif
#endif /* RESTRING_H_ */
ReSeqList::Sequence* seq = m_keys.getInfo(ii);
if (seq->m_length == length){
const Byte* ptr = m_keys.getContent() + seq->m_index;
- if (memcmp(ptr, key, length) == 0)
+ if (_memcmp(ptr, key, length) == 0)
rc = ii;
}
}
const char* item = strOf(start);
int rc2;
if (ignoreCase)
- rc2 = strcasecmp(item, toFind);
+ rc2 = _stricmp(item, toFind);
else
rc2 = strcmp(item, toFind);
if (rc2 == 0)
const char* item = strOf(start);
int rc2;
if (ignoreCase)
- rc2 = strncasecmp(item, prefix, length);
+ rc2 = _strnicmp(item, prefix, length);
else
rc2 = strncmp(item, prefix, length);
if (rc2 == 0)
ReStringList& append(const char* source, Tag tag = 0);
ReStringList& append(const ReByteBuffer& source, Tag tag = 0);
ReStringList& append(ReStringList& source);
+ bool equal(const ReStringList& toCompare) const;
+ int firstDiff(const ReStringList& toCompare) const;
Index indexOf(const char* toFind, bool ignoreCase = false, Index start = 0) const;
void insert(Index index, const char* source, Tag tag = 0);
ReByteBuffer& join(const char* separator, ReByteBuffer& result) const;
Index nextStartingWith(Index index, const char* prefix, bool ignoreCase = false);
+ bool readFromFile(const char* filename, bool cutNewline = true);
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;
+ const char* strOf(Index index) const;
size_t sumOfSizes() const;
size_t sumOfStrLengths() const;
Tag tagOf(Index index) const;
-
-
-
- int firstDiff(const ReStringList& toCompare) const;
- bool equal(const ReStringList& toCompare) const;
-
bool writeToFile(const char* filename, const char* separator = "\n", const char* mode = "w");
- bool readFromFile(const char* filename, bool cutNewline = true);
};
#endif /* RESTRINGLIST_H_ */
#include "base/rebase.hpp"
/** @brief Constructor.
*
- * @param name The name of the test class.
- * @param sourceFile The file where contain the tests.
- * This will be used for error messages.
+ * @param name the name of the test class
+ * @param sourceFile the file where contain the tests
+ * this will be used for error messages
*/
ReTestUnit::ReTestUnit(const char* name, const char* sourceFile)
:
}
/** @brief Checks a boolean expression. A false value will be logged.
*
- * @param condition This expression will be tested.
- * If false an error messsage will be issued.
- * @param lineNo The line number of the test (for the error messge).
+ * @param condition this expression will be tested
+ * if false an error messsage will be issued
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertTrue(bool condition, int lineNo)
{
}
/** @brief Checks a boolean expression. A true value will be logged.
*
- * @param condition This expression will be tested.
- * If tre an error messsage will be issued.
- * @param lineNo The line number of the test (for the error messge).
+ * @param condition this expression will be tested
+ * if true an error messsage will be issued
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertFalse(bool condition, int lineNo)
{
}
/** @brief Checks a pointer expression. A not <code>null</code> value will be logged.
*
- * @param pointer This expression will be tested.
- * If not <code>null</code> an error messsage will be issued.
- * @param lineNo The line number of the test (for the error messge).
+ * @param pointer this expression will be tested
+ * if not <code>null</code> an error messsage will be issued
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertNull(void* pointer, int lineNo){
if (pointer != NULL){
}
/** @brief Checks a pointer expression. A <code>null</code> value will be logged.
*
- * @param pointer This expression will be tested.
- * If <code>null</code> an error messsage will be issued.
- * @param lineNo The line number of the test (for the error messge).
+ * @param pointer this expression will be tested
+ * if <code>null</code> an error messsage will be issued
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertNotNull(void* pointer, int lineNo){
if (pointer == NULL){
}
/** @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).
+ * @param expected the expected value
+ * @param current the current value
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertEqual(int expected, int current, int lineNo){
if (expected != current){
}
/** @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).
+ * @param expected the expected value
+ * @param current the current value
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertEqual(unsigned int expected, unsigned int current, int lineNo){
if (expected != current){
}
/** @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).
+ * @param expected the expected value
+ * @param current the current value
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertEqual(int64_t expected, int64_t current, int lineNo){
if (expected != current){
}
/** @brief Compares two string 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).
+ * @param expected the expected value
+ * @param current the current value
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertEqual(const char* expected, const char* current, int lineNo){
if (current == NULL || strcmp(expected, current) != 0){
}
/** @brief Checks whether a file exists. If not this will be logged.
*
- * @param name The filename.
- * @param lineNo The line number of the test (for the error messge).
+ * @param name the filename
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertFileExists(const char* name, int lineNo){
struct stat info;
m_sourceFile, lineNo, name);
}
}
+/** @brief Checks whether two files have the same content. If not this will be logged.
+ *
+ * @param name1 name of the first file
+ * @param name2 name of the 2nd file
+ * @param lineNo the line number of the test (for the error message)
+ */
+void ReTestUnit::assertEqualFiles(const char* name1, const char* name2, int lineNo){
+ ReByteBuffer buffer;
+ ReStringList list1;
+ ReStringList list2;
+ list1.readFromFile(name1);
+ list2.readFromFile(name2);
+ int ix = list1.firstDiff(list2);
+ if (ix < 0){
+ ReByteBuffer line1(list1.strOf(ix), list1.strLengthOf(ix));
+ int ixLine = line1.firstDifference(list2.strOf(ix), list2.strLengthOf(ix));
+ logF(true, i18n("%s-%d: Files differ in line %d-%d\%s\n%s\n%s"),
+ m_sourceFile, lineNo, ix, ixLine, list1.strOf(ix), list2.strOf(ix),
+ colMarker(ixLine));
+ }
+
+}
+
+/**
+ * Returns a string usable as a marker of a given column.
+ *
+ * @param col the column to mark. 0: the first column ...
+ * @return a line marking the given column, e.g. "---^"
+ */
+const char* ReTestUnit::colMarker(int col){
+ if (col > 0)
+ m_buffer.setLengthAndFill(col - 1, '-');
+ else
+ m_buffer.setLength(0);
+ m_buffer.append("^", 1);
+ return m_buffer.str();
+}
+
/** @brief Creates an empty temporary directory.
- * The name can be retrieved by <code>getTestDir()</code>.
+ * the name can be retrieved by <code>getTestDir()</code>.
*/
void ReTestUnit::createTestDir(){
char name[512];
}
strcpy(m_tempDir, name);
}
-/** @brief Returns The temporary directory.
+/** @brief Returns the temporary directory.
*
- * @return The name of a temporary directory.
+ * @return the name of a temporary directory
*/
const char* ReTestUnit::getTestDir(){
return (const char*) m_tempDir;
}
/** @brief Creates a file and fills it with an given content.
*
- * @param filename The name of the file.
- * @param content The content of the file. If NULL the file will be empty.
+ * @param filename the name of the file
+ * @param content the content of the file. If NULL the file will be empty
*/
void ReTestUnit::createFile(const char* filename, const char* content){
FILE* fp = fopen(filename, "w");
}
/** @brief Creates a file and fills it with an given content.
*
- * @param filename The name of the file.
- * @param content The content of the file. If NULL the file will be empty.
+ * @param filename the name of the file
+ * @param content the content of the file. If NULL the file will be empty
*/
void ReTestUnit::createDir(const char* filename){
_mkdir(filename);
/** @brief Checks whether a directory exists. If not this will be logged.
*
- * @param dir The name of the directory.
- * @param lineNo The line number of the test (for the error messge).
+ * @param dir the name of the directory
+ * @param lineNo the line number of the test (for the error message)
*/
void ReTestUnit::assertDirExists(const char* dir, int lineNo){
struct stat info;
/** @brief Logs a message.
*
- * It can be used to inform the user about coming (error-) messages.
+ * It can be used to inform the user about coming (error-) messages
*
- * @param isError true: The message is an error message. false: Otherwise.
- * @param message The message to issue.
+ * @param isError true: the message is an error message. false: Otherwise
+ * @param message the message to issue
*
* @return <code>! isError</code>
*/
}
/** @brief Logs a formated message with placeholders.
*
- * It can be used to inform the user about coming (error-) messages.
+ * It can be used to inform the user about coming (error-) messages
*
- * @param isError true: The message is an error message. false: Otherwise.
- * @param format The message with placeholders like <code>printf</code>.
- * @param ... A variable number of arguments which replace the placeholders.
+ * @param isError true: the message is an error message. false: Otherwise
+ * @param format the message with placeholders like <code>printf</code>
+ * @param ... a variable number of arguments which replace the placeholders
*
- * @return <code>! isError</code>
+ * @return <code>! isError</code>
*/
bool ReTestUnit::logF(bool isError, const char* format, ...){
char buffer[2048];
}
#if defined RE_TESTUNIT
-class TestTestUnit : public ReTestUnit {
-public:
- TestTestUnit() : ReTestUnit("TestTest", __FILE__){
- run();
- }
-private:
- void run(){
- checkT(true);
- checkF(false);
- checkN(NULL);
- checkNN("");
- checkEqu(1, 1);
- checkEqu("abc", "abc");
- checkDirExists("/etc/");
- checkFileExists("/etc/passwd");
- log(false, "8 errors follow:");
- checkT(false);
- checkF(true);
- checkN("");
- checkNN(NULL);
- checkEqu(1, 2);
- checkEqu("abc", "abcd");
- checkDirExists("/etc!/");
- checkFileExists("/etc!/passwd");
- log(false, "8 errors expected!");
- }
-};
-extern void testReTestUnit(void);
-
-void testReTestUnit(void){
- TestTestUnit unit;
-}
#endif /*RE_TESTUNIT*/
// Not accessible, not implemented!
ReTestUnit& operator =(const ReTestUnit& source);
public:
- void assertTrue(bool conditon, int lineNo);
- void assertFalse(bool conditon, int lineNo);
- void assertNull(void* pointer, int lineNo);
- void assertNotNull(void* pointer, int lineNo);
+ void assertDirExists(const char* dir, 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 assertEqualFiles(const char* name1, const char* name2, int lineNo);
+ void assertFileExists(const char* name, int lineNo);
+ void assertFalse(bool conditon, int lineNo);
+ void assertNotNull(void* pointer, int lineNo);
+ void assertNull(void* pointer, int lineNo);
+ void assertTrue(bool conditon, int lineNo);
+ void createDir(const char* filename);
+ void createFile(const char* filename, const char* content);
void createTestDir();
+ const char* colMarker(int col);
const char* getTestDir();
- void createFile(const char* filename, const char* content);
- void createDir(const char* filename);
-
- void assertFileExists(const char* name, int lineNo);
- void assertDirExists(const char* dir, int lineNo);
-
virtual bool log(bool isError, const char* message);
virtual bool logF(bool isError, const char* format, ...);
protected:
int m_errorCount;
const char* m_sourceFile;
char m_tempDir[512];
+ ReByteBuffer m_buffer;
};
#define checkT(cond) assertTrue(cond, __LINE__)
#define checkF(cond) assertFalse(cond, __LINE__)
#define checkEqu(exp, cur) assertEqual(exp, cur, __LINE__)
#define checkFileExists(fn) assertFileExists(fn, __LINE__)
#define checkDirExists(fn) assertDirExists(fn, __LINE__)
+#define checkFileEqu(f1, f2) assertEqualFiles(f1, f2, __LINE__)
#endif /* RETESTUNIT_H_ */
#if defined __linux__
-#include <stddef.h>
-#include <dirent.h>
-#include <fnmatch.h>
-#include <regex.h>
-#include <unistd.h>
-#include <inttypes.h>
-
-#define _strdup strdup
-#define _unlink unlink
-#define _mkdir(path) mkdir(path, ALLPERMS)
-//#define _
+# include <stddef.h>
+# include <dirent.h>
+# include <fnmatch.h>
+# include <regex.h>
+# include <unistd.h>
+# include <inttypes.h>
+
+# define _strdup strdup
+# define _unlink unlink
+# define _strnicmp(s1, s2, n) strncasecmp(s1, s2, n)
+# define _stricmp(s1, s2) strcasecmp(s1, s2)
+# define _snprintf snprintf
+# define _memcmp(t,s,n) memcmp(t,s,n)
+# define _mkdir(path) mkdir(path, ALLPERMS)
#elif defined __WIN32__
-
-#include <direct.h>
-#include <windows.h>
-typedef _int64 int64_t;
+# include <direct.h>
+# include <windows.h>
+ typedef _int64 int64_t;
+# define S_ISDIR(mode) (((mode) & _S_IFDIR) != 0)
#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_ */
}
private:
void run(){
+ testFirstDiff();
testCount();
testEnsureSizeGetLength();
testIndexOf();
testSplice();
testReplace();
}
+ void testFirstDiff(){
+ ReByteBuffer buf("abcd");
+ // firstDifference(const Byte* source, size_t length, int start, bool ignoreCase)
+ // ignoreCase == false:
+ // start == 0, length == -1, same length:
+ checkEqu(-1, buf.firstDifference("abcd", -1));
+ checkEqu(0, buf.firstDifference("xbcd", -1));
+ checkEqu(1, buf.firstDifference("aBcd", -1));
+ // start == 2, length == -1, same length:
+ checkEqu(-1, buf.firstDifference("cd", -1, 2));
+ checkEqu(2, buf.firstDifference("xd", -1, 2));
+ checkEqu(3, buf.firstDifference("cD", -1, 2));
+ // start == 0, length > 0, same length:
+ checkEqu(-1, buf.firstDifference("axcd", 1));
+ checkEqu(0, buf.firstDifference("xbcd", 2));
+ checkEqu(1, buf.firstDifference("aBcd", 2));
+ // start == 2, length > 0, same length:
+ checkEqu(-1, buf.firstDifference("cdx", 1, 2));
+ checkEqu(2, buf.firstDifference("xd", 1, 2));
+ checkEqu(3, buf.firstDifference("cD", 2, 2));
+
+ // ignoreCase == true:
+ // start == 0, length == -1, same length:
+ checkEqu(-1, buf.firstDifference("Abcd", -1, 0, true));
+ checkEqu(0, buf.firstDifference("xbcd", -1, 0, true));
+ checkEqu(-1, buf.firstDifference("aBcd", -1, 0, true));
+ checkEqu(1, buf.firstDifference("aXcd", -1, 0, true));
+ // start == 2, length == -1, same length:
+ checkEqu(-1, buf.firstDifference("cd", -1, 2, true));
+ checkEqu(2, buf.firstDifference("xd", -1, 2, true));
+ checkEqu(-1, buf.firstDifference("cD", -1, 2, true));
+ checkEqu(3, buf.firstDifference("CX", -1, 2, true));
+ // start == 0, length > 0, same length:
+ checkEqu(-1, buf.firstDifference("Axcd", 1, 0, true));
+ checkEqu(0, buf.firstDifference("xbcd", 2, 0, true));
+ checkEqu(-1, buf.firstDifference("AXcd", 1, 0, true));
+ // start == 2, length > 0, same length:
+ checkEqu(-1, buf.firstDifference("cDx", 1, 2, true));
+ checkEqu(2, buf.firstDifference("xd", 1, 2, true));
+ checkEqu(-1, buf.firstDifference("cD", 1, 2, true));
+ checkEqu(3, buf.firstDifference("cX", 2, 2, true));
+
+ // larger length:
+ checkEqu(4, buf.firstDifference("abcde", -1, 0, false));
+ checkEqu(4, buf.firstDifference("cde", -1, 2, false));
+ // wrong indexe:
+ checkEqu(0, buf.firstDifference("cdx", 1, -1, true));
+ checkEqu(0, buf.firstDifference("cdx", 1, -1, false));
+ }
void testCount(){
ReByteBuffer buffer("aabbaabb");
checkEqu(4, buffer.count("a"));
ReByteBuffer trg(getTestDir());
trg.append("copy_x1.txt");
ReByteBuffer buffer;
+ buffer.ensureSize(5);
ReDirSync::copyFile(src.str(), 0, -1ll, trg.str(), buffer, ReLogger::globalLogger());
+ //checkFile();
}
void checkRelDate(time_t absTime, int relTime){
int diff = int(time(NULL) - relTime - absTime);
#endif
void testBase(){
+ extern void testReTestUnit();
+ testReTestUnit();
extern void testReByteBuffer();
testReByteBuffer();
extern void testReSeqList(void);
testReProgramArgs();
extern void testReLogger(void);
testReLogger();
+
}
void testString(){
extern void testReStringList(void);
buffer2[bufferLength] = '\0';
rand.setSeed(0x4711);
obf.decode(buffer2, bufferLength);
- if (memcmp(buffer2, src, bufferLength) != 0)
+ if (_memcmp(buffer2, src, bufferLength) != 0)
printf("%3d:%s\n -> %s\n -> %s\n", (int) obf.getCharSet(), src, buffer, buffer2);
}
static void testIt(const char* src, int bufferLength,
#include "string/ReMatcher.hpp"
#ifdef __linux__
-extern int strncasecmp (const char* s1, const char* s2, size_t n);
+extern int _strnicmp (const char* s1, const char* s2, size_t n);
extern int strncmp (const char* s1, const char* s2, size_t n);
extern void* memset (void *s, int c, size_t n);
#endif