aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--.travis.yml26
-rw-r--r--CMakeLists.txt117
-rw-r--r--SConstruct8
-rw-r--r--doc/book/net.tex11
-rw-r--r--src/address.cpp28
-rw-r--r--src/addressList.cpp2
-rw-r--r--src/headerField.cpp2
-rw-r--r--src/mailboxField.cpp2
-rw-r--r--src/mailboxGroup.cpp7
-rw-r--r--src/mediaType.cpp2
-rw-r--r--src/net/smtp/SMTPCommandSet.cpp2
-rw-r--r--src/parameter.cpp17
-rw-r--r--src/parameterizedHeaderField.cpp8
-rw-r--r--src/utility/streamUtils.cpp2
-rw-r--r--src/word.cpp10
-rw-r--r--src/wordEncoder.cpp2
-rw-r--r--tests/charset/Makefile5
-rw-r--r--tests/charset/main.cpp44
-rwxr-xr-xtests/charset/run-test.sh47
-rw-r--r--tests/charset/test-suites/gnu.in.utf-848
-rw-r--r--tests/charset/test-suites/gnu.out.iso-8859-148
-rw-r--r--tests/misc/importanceHelperTest.cpp6
-rw-r--r--tests/net/maildir/maildirStoreTest.cpp6
-rw-r--r--tests/net/pop3/POP3ResponseTest.cpp6
-rw-r--r--tests/net/pop3/POP3UtilsTest.cpp6
-rw-r--r--tests/net/smtp/SMTPCommandSetTest.cpp6
-rw-r--r--tests/net/smtp/SMTPCommandTest.cpp6
-rw-r--r--tests/net/smtp/SMTPResponseTest.cpp6
-rw-r--r--tests/net/smtp/SMTPTransportTest.cpp6
-rw-r--r--tests/parser/attachmentHelperTest.cpp6
-rw-r--r--tests/parser/bodyPartTest.cpp6
-rw-r--r--tests/parser/charsetFilteredOutputStreamTest.cpp205
-rw-r--r--tests/parser/charsetTest.cpp270
-rw-r--r--tests/parser/charsetTestSuites.hpp103
-rw-r--r--tests/parser/datetimeTest.cpp6
-rw-r--r--tests/parser/dispositionTest.cpp6
-rw-r--r--tests/parser/emailAddressTest.cpp6
-rw-r--r--tests/parser/headerFieldTest.cpp23
-rw-r--r--tests/parser/headerTest.cpp6
-rw-r--r--tests/parser/htmlTextPartTest.cpp6
-rw-r--r--tests/parser/mailboxGroupTest.cpp97
-rw-r--r--tests/parser/mailboxTest.cpp24
-rw-r--r--tests/parser/mediaTypeTest.cpp6
-rw-r--r--tests/parser/messageIdSequenceTest.cpp6
-rw-r--r--tests/parser/messageIdTest.cpp6
-rw-r--r--tests/parser/parameterTest.cpp18
-rw-r--r--tests/parser/pathTest.cpp6
-rw-r--r--tests/parser/textTest.cpp6
-rw-r--r--tests/parser/wordEncoderTest.cpp6
-rw-r--r--tests/security/digest/md5Test.cpp6
-rw-r--r--tests/security/digest/sha1Test.cpp6
-rw-r--r--tests/testRunner.cpp49
-rw-r--r--tests/testUtils.cpp36
-rw-r--r--tests/testUtils.hpp21
-rw-r--r--tests/utility/datetimeUtilsTest.cpp6
-rw-r--r--tests/utility/encoder/b64EncoderTest.cpp145
-rw-r--r--tests/utility/encoder/encoderTestUtils.hpp65
-rw-r--r--tests/utility/encoder/qpEncoderTest.cpp (renamed from tests/utility/encoderTest.cpp)158
-rw-r--r--tests/utility/filteredStreamTest.cpp6
-rw-r--r--tests/utility/outputStreamByteArrayAdapterTest.cpp6
-rw-r--r--tests/utility/outputStreamSocketAdapterTest.cpp6
-rw-r--r--tests/utility/outputStreamStringAdapterTest.cpp6
-rw-r--r--tests/utility/pathTest.cpp6
-rw-r--r--tests/utility/seekableInputStreamRegionAdapterTest.cpp6
-rw-r--r--tests/utility/smartPtrTest.cpp6
-rw-r--r--tests/utility/stringProxyTest.cpp6
-rw-r--r--tests/utility/stringUtilsTest.cpp6
-rw-r--r--tests/utility/urlTest.cpp6
-rw-r--r--vmime/address.hpp4
-rw-r--r--vmime/context.hpp2
-rw-r--r--vmime/headerField.hpp25
-rw-r--r--vmime/net/smtp/SMTPCommandSet.hpp2
73 files changed, 1061 insertions, 832 deletions
diff --git a/.gitignore b/.gitignore
index c3be379d..94f66b35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,10 @@ doc/html/*
/COPYING.txt
/build/
+# CTest-generated files
+/CTestTestfile.cmake
+/Testing/
+
# Mac
._DS_Store
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..650c27f0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,26 @@
+# Travis-CI build file for VMime
+# See http://travis-ci.org for details
+
+language: cpp
+
+compiler:
+ - gcc
+ - clang
+
+# Settings
+env:
+ - CTEST_OUTPUT_ON_FAILURE=1 OPTIONS="-DVMIME_SENDMAIL_PATH=/path/to/sendmail -DCMAKE_BUILD_TYPE=Debug -DVMIME_BUILD_TESTS=ON"
+
+# Make sure some required tools/libraries are installed
+install:
+ - sudo apt-get update >/dev/null
+ - sudo apt-get -q install cmake libcppunit-dev valgrind
+ - sudo apt-get -q install libgsasl7-dev libgnutls-dev libssl-dev
+
+# Run the build script
+script:
+ - mkdir _build
+ - cd _build
+ - cmake .. -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS
+ - cmake --build . --target install
+ - ctest
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c37407e0..e8a57791 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -26,6 +26,7 @@ INCLUDE(CheckLibraryExists)
# CMake configuration
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY build/bin)
SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY build/lib)
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY build/lib)
SET(CMAKE_VERBOSE_MAKEFILE ON)
@@ -83,13 +84,6 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
)
-# Automatically set lib suffix
-IF(UNIX AND NOT APPLE AND NOT CMAKE_CROSSCOMPILING AND NOT EXISTS "/etc/debian_version")
- IF(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT LIB_SUFFIX)
- SET(LIB_SUFFIX 64)
- ENDIF()
-ENDIF()
-
# Shared library
OPTION(
VMIME_BUILD_SHARED_LIBRARY
@@ -109,8 +103,8 @@ IF(VMIME_BUILD_SHARED_LIBRARY)
SET_TARGET_PROPERTIES(
${VMIME_LIBRARY_NAME}
PROPERTIES
- VERSION "${VMIME_VERSION}"
- SOVERSION "${VMIME_API_VERSION}"
+ VERSION "${VMIME_API_VERSION}"
+ SOVERSION "${VMIME_API_VERSION_CURRENT}"
)
ENDIF()
@@ -158,20 +152,55 @@ ENDIF()
SET(CMAKE_INSTALL_LIBDIR lib CACHE PATH "Output directory for libraries")
+# Automatically set lib suffix
+IF(UNIX AND NOT APPLE AND NOT CMAKE_CROSSCOMPILING AND NOT EXISTS "/etc/debian_version")
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT LIB_SUFFIX)
+ # ...only if LIB_SUFFIX is not defined...
+ IF(NOT DEFINED LIB_SUFFIX)
+ # ...and if CMAKE_INSTALL_LIBDIR does not already contain the suffix
+ IF(NOT "${CMAKE_INSTALL_LIBDIR}" MATCHES ".*64.*")
+ SET(LIB_SUFFIX 64)
+ ENDIF()
+ ENDIF()
+ ENDIF()
+ENDIF()
+
+# Determine library installation dir, in this order:
+# 1) use VMIME_INSTALL_LIBDIR if set
+# 2) use LIB_INSTALL_DIR if defined
+# 3) use CMAKE_INSTALL_LIBDIR if set
+# if it is a relative path, prepend CMAKE_INSTALL_PREFIX to it
+# 4) use CMAKE_INSTALL_PREFIX/lib
+IF(NOT DEFINED VMIME_INSTALL_LIBDIR)
+ IF(DEFINED LIB_INSTALL_DIR)
+ SET(VMIME_INSTALL_LIBDIR ${LIB_INSTALL_DIR})
+ # respect CMAKE_INSTALL_LIBDIR if set
+ ELSEIF(DEFINED CMAKE_INSTALL_LIBDIR)
+ SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR})
+ IF(IS_ABSOLUTE ${VMIME_INSTALL_LIBDIR})
+ SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX})
+ ELSE()
+ SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}${LIB_SUFFIX})
+ ENDIF()
+ ELSE()
+ SET(VMIME_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
+ ENDIF()
+ENDIF()
+
# Installation of libraries
IF(VMIME_BUILD_SHARED_LIBRARY)
INSTALL(
TARGETS ${VMIME_LIBRARY_NAME}
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT sharedlibs
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT sharedlibs
+ LIBRARY DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT sharedlibs
+ ARCHIVE DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT sharedlibs
)
ENDIF()
IF(VMIME_BUILD_STATIC_LIBRARY)
INSTALL(
TARGETS ${VMIME_LIBRARY_NAME}-static
- LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT staticlibs
- ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT staticlibs
+ LIBRARY DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT staticlibs
+ ARCHIVE DESTINATION "${VMIME_INSTALL_LIBDIR}" COMPONENT staticlibs
)
ENDIF()
@@ -196,21 +225,57 @@ OPTION(
IF(VMIME_BUILD_TESTS)
+ ENABLE_TESTING()
+
+ INCLUDE(cmake/FindCppUnit.cmake)
+ INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIR})
+
FILE(
GLOB_RECURSE
VMIME_TESTS_SRC_FILES
- tests/*Test.cpp tests/testRunner.cpp tests/testUtils.cpp
+ ${CMAKE_SOURCE_DIR}/tests/*Test.cpp
)
+ # Build one file for each test
+ FOREACH(VMIME_TEST_SRC_FILE ${VMIME_TESTS_SRC_FILES})
+
+ # "/path/to/vmime/tests/module/testFile.cpp" --> "module_testFile"
+ GET_FILENAME_COMPONENT(VMIME_TEST_SRC_PATH "${VMIME_TEST_SRC_FILE}" PATH)
+ STRING(REPLACE "${CMAKE_SOURCE_DIR}" "" VMIME_TEST_SRC_PATH "${VMIME_TEST_SRC_PATH}")
+ GET_FILENAME_COMPONENT(VMIME_TEST_NAME "${VMIME_TEST_SRC_FILE}" NAME_WE)
+ SET(VMIME_TEST_NAME "${VMIME_TEST_SRC_PATH}/${VMIME_TEST_NAME}")
+ STRING(REPLACE "/" "_" VMIME_TEST_NAME "${VMIME_TEST_NAME}")
+ STRING(REPLACE "_tests_" "" VMIME_TEST_NAME "${VMIME_TEST_NAME}")
+
+ ADD_EXECUTABLE(
+ ${VMIME_TEST_NAME}
+ ${VMIME_TEST_SRC_FILE} ${CMAKE_SOURCE_DIR}/tests/testRunner.cpp ${CMAKE_SOURCE_DIR}/tests/testUtils.cpp
+ )
+
+ TARGET_LINK_LIBRARIES(
+ ${VMIME_TEST_NAME}
+ ${VMIME_LIBRARY_NAME}
+ ${CPPUNIT_LIBRARY}
+ )
+
+ ADD_DEPENDENCIES(
+ ${VMIME_TEST_NAME}
+ ${VMIME_LIBRARY_NAME}
+ )
+
+ ADD_TEST(
+ ${VMIME_TEST_NAME}
+ ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${VMIME_TEST_NAME}
+ )
+
+ ENDFOREACH()
+
+ # Build one file for all tests
ADD_EXECUTABLE(
"run-tests"
- ${VMIME_TESTS_SRC_FILES}
+ ${VMIME_TESTS_SRC_FILES} ${CMAKE_SOURCE_DIR}/tests/testRunner.cpp ${CMAKE_SOURCE_DIR}/tests/testUtils.cpp
)
- INCLUDE(cmake/FindCppUnit.cmake)
-
- INCLUDE_DIRECTORIES(${CPPUNIT_INCLUDE_DIR})
-
TARGET_LINK_LIBRARIES(
"run-tests"
${VMIME_LIBRARY_NAME}
@@ -290,18 +355,12 @@ ADD_CUSTOM_TARGET(
SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(exec_prefix ${CMAKE_INSTALL_PREFIX}/bin)
SET(includedir ${CMAKE_INSTALL_PREFIX}/include/vmime)
+SET(libdir ${VMIME_INSTALL_LIBDIR})
SET(VMIME_PKGCONFIG_LIBS "")
SET(VMIME_PKGCONFIG_CFLAGS "")
SET(VMIME_PKGCONFIG_REQUIRES "")
-IF(${UNIX})
- SET(libdir ${CMAKE_INSTALL_PREFIX}/lib${LIB_SUFFIX})
-ENDIF(${UNIX})
-IF(${WIN32})
- SET(libdir ${CMAKE_INSTALL_PREFIX}/bin)
-ENDIF(${WIN32})
-
##############################################################################
# Build type
@@ -625,6 +684,8 @@ IF(WIN32)
${TARGET_LINK_LIBRARIES}
"ws2_32"
)
+ ELSE()
+ SET(VMIME_PKGCONFIG_LIBS "${VMIME_PKGCONFIG_LIBS} -lws2_32")
ENDIF()
ENDIF()
@@ -763,11 +824,11 @@ ENDIF()
# Set our configure file
-CONFIGURE_FILE(cmake/config.hpp.cmake vmime/config.hpp)
+CONFIGURE_FILE(cmake/config.hpp.cmake ${CMAKE_SOURCE_DIR}/vmime/config.hpp)
# PkgConfig post-configuration
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/libvmime.pc.in ${CMAKE_BINARY_DIR}/libvmime.pc @ONLY)
-INSTALL(FILES ${CMAKE_BINARY_DIR}/libvmime.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig COMPONENT headers)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/libvmime.pc DESTINATION "${VMIME_INSTALL_LIBDIR}/pkgconfig" COMPONENT headers)
INCLUDE(CPack)
diff --git a/SConstruct b/SConstruct
index 1db0d2e2..60ee5159 100644
--- a/SConstruct
+++ b/SConstruct
@@ -346,7 +346,8 @@ libvmime_tests = [
]
libvmimetest_common = [
- 'tests/testUtils.hpp'
+ 'tests/testUtils.hpp',
+ 'tests/utility/encoder/encoderTestUtils.hpp'
]
libvmimetest_sources = [
@@ -356,12 +357,14 @@ libvmimetest_sources = [
'tests/parser/attachmentHelperTest.cpp',
'tests/parser/bodyPartTest.cpp',
'tests/parser/charsetTest.cpp',
+ 'tests/parser/charsetFilteredOutputStreamTest.cpp',
'tests/parser/datetimeTest.cpp',
'tests/parser/dispositionTest.cpp',
'tests/parser/emailAddressTest.cpp',
'tests/parser/headerTest.cpp',
'tests/parser/headerFieldTest.cpp',
'tests/parser/htmlTextPartTest.cpp',
+ 'tests/parser/mailboxGroupTest.cpp',
'tests/parser/mailboxTest.cpp',
'tests/parser/mediaTypeTest.cpp',
'tests/parser/messageIdTest.cpp',
@@ -378,7 +381,8 @@ libvmimetest_sources = [
'tests/utility/pathTest.cpp',
'tests/utility/urlTest.cpp',
'tests/utility/smartPtrTest.cpp',
- 'tests/utility/encoderTest.cpp',
+ 'tests/utility/encoder/qpEncoderTest.cpp',
+ 'tests/utility/encoder/b64EncoderTest.cpp',
'tests/utility/outputStreamStringAdapterTest.cpp',
'tests/utility/outputStreamSocketAdapterTest.cpp',
'tests/utility/outputStreamByteArrayAdapterTest.cpp',
diff --git a/doc/book/net.tex b/doc/book/net.tex
index 6977c290..7653b48e 100644
--- a/doc/book/net.tex
+++ b/doc/book/net.tex
@@ -701,10 +701,13 @@ class timeoutHandler : public object
\end{lstlisting}
While the operation runs, the service calls {\vcode isTimeout()} at variable
-intervals. If the function returns {\vcode true}, then
-{\vcode handleTimeout()} is called. If it also returns {\vcode true}, the
-operation is cancelled and an {\vcode operation\_timed\_out} exception is
-thrown. The function {\vcode resetTimeout()} is called each time data has
+intervals. If the {\vcode isTimeout()} function returns {\vcode true},
+then {\vcode handleTimeout()} is called. If the {\vcode handleTimeout()}
+function returns {\vcode false}, the operation is cancelled and
+an {\vcode operation\_timed\_out} exception is thrown. Else, if
+{\vcode handleTimeout()} returns true, the operation continues and the
+time-out count is reset.
+The function {\vcode resetTimeout()} is called each time data has
been received from the server to reset time-out delay.
The following example shows how to implement a simple time-out handler:
diff --git a/src/address.cpp b/src/address.cpp
index ab207cf6..b57892d5 100644
--- a/src/address.cpp
+++ b/src/address.cpp
@@ -68,7 +68,7 @@ address-list = (address *("," address)) / obs-addr-list
ref <address> address::parseNext
(const parsingContext& ctx, const string& buffer, const string::size_type position,
- const string::size_type end, string::size_type* newPosition)
+ const string::size_type end, string::size_type* newPosition, bool *isLastAddressOfGroup)
{
bool escaped = false;
bool quoted = false;
@@ -76,6 +76,10 @@ ref <address> address::parseNext
bool inRouteAddr = false;
bool isGroup = false;
bool stop = false;
+ int commentLevel = 0;
+
+ if (isLastAddressOfGroup)
+ *isLastAddressOfGroup = false;
string::size_type pos = position;
@@ -106,9 +110,22 @@ ref <address> address::parseNext
case '>':
inRouteAddr = false;
break;
+
+ case '(':
+
+ ++commentLevel;
+ break;
+
+ case ')':
+
+ if (commentLevel > 0)
+ --commentLevel;
+
+ break;
+
case '=':
- if (!quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?')
+ if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?')
{
++pos;
quotedRFC2047 = true;
@@ -118,7 +135,7 @@ ref <address> address::parseNext
case '?':
- if (quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=')
+ if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=')
{
++pos;
quotedRFC2047 = false;
@@ -128,7 +145,7 @@ ref <address> address::parseNext
default:
{
- if (!quoted && !quotedRFC2047 && !inRouteAddr)
+ if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr)
{
switch (buffer[pos])
{
@@ -140,6 +157,9 @@ ref <address> address::parseNext
++pos;
}
+ if (isLastAddressOfGroup)
+ *isLastAddressOfGroup = true;
+
stop = true;
break;
diff --git a/src/addressList.cpp b/src/addressList.cpp
index 5e033f38..326a54e3 100644
--- a/src/addressList.cpp
+++ b/src/addressList.cpp
@@ -60,7 +60,7 @@ void addressList::parseImpl
while (pos < end)
{
- ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos);
+ ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL);
if (parsedAddress != NULL)
m_list.push_back(parsedAddress);
diff --git a/src/headerField.cpp b/src/headerField.cpp
index 59b10e76..7d23ce84 100644
--- a/src/headerField.cpp
+++ b/src/headerField.cpp
@@ -142,7 +142,7 @@ ref <headerField> headerField::parseNext
++pos;
const string::size_type contentsStart = pos;
- string::size_type contentsEnd = 0;
+ string::size_type contentsEnd = end;
// Extract the field value
while (pos < end)
diff --git a/src/mailboxField.cpp b/src/mailboxField.cpp
index 1f11f49c..4eb9d734 100644
--- a/src/mailboxField.cpp
+++ b/src/mailboxField.cpp
@@ -52,7 +52,7 @@ void mailboxField::parse
// Here, we cannot simply call "m_mailbox.parse()" because it
// may have more than one address specified (even if this field
// should contain only one). We are never too much careful...
- ref <address> parsedAddress = address::parseNext(ctx, buffer, position, end, newPosition);
+ ref <address> parsedAddress = address::parseNext(ctx, buffer, position, end, newPosition, NULL);
if (parsedAddress)
{
diff --git a/src/mailboxGroup.cpp b/src/mailboxGroup.cpp
index 65611b33..9da16653 100644
--- a/src/mailboxGroup.cpp
+++ b/src/mailboxGroup.cpp
@@ -78,10 +78,11 @@ void mailboxGroup::parseImpl
string::size_type pos = position + (p - pstart);
+ bool isLastAddressOfGroup = false;
- while (pos < end)
+ while (pos < end && !isLastAddressOfGroup)
{
- ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos);
+ ref <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, &isLastAddressOfGroup);
if (parsedAddress)
{
@@ -103,7 +104,7 @@ void mailboxGroup::parseImpl
}
}
- text::decodeAndUnfold(ctx, name, &m_name);
+ text::decodeAndUnfold(ctx, utility::stringUtils::trim(name), &m_name);
setParsedBounds(position, end);
diff --git a/src/mediaType.cpp b/src/mediaType.cpp
index 62d65c23..123c8cee 100644
--- a/src/mediaType.cpp
+++ b/src/mediaType.cpp
@@ -49,7 +49,7 @@ mediaType::mediaType(const string& type, const string& subType)
void mediaType::parseImpl
- (const parsingContext& ctx, const string& buffer, const string::size_type position,
+ (const parsingContext& /* ctx */, const string& buffer, const string::size_type position,
const string::size_type end, string::size_type* newPosition)
{
const string::value_type* const pend = buffer.data() + end;
diff --git a/src/net/smtp/SMTPCommandSet.cpp b/src/net/smtp/SMTPCommandSet.cpp
index 0454e184..a967c3a6 100644
--- a/src/net/smtp/SMTPCommandSet.cpp
+++ b/src/net/smtp/SMTPCommandSet.cpp
@@ -124,7 +124,7 @@ const string SMTPCommandSet::getText() const
}
-const bool SMTPCommandSet::isFinished() const
+bool SMTPCommandSet::isFinished() const
{
return (m_pipeline && m_started) || (m_commands.size() == 0 && m_started);
}
diff --git a/src/parameter.cpp b/src/parameter.cpp
index 37a59890..b86d4815 100644
--- a/src/parameter.cpp
+++ b/src/parameter.cpp
@@ -234,7 +234,7 @@ void parameter::parse(const parsingContext& ctx, const std::vector <valueChunk>&
// This syntax is non-standard (expressly prohibited
// by RFC-2047), but is used by Mozilla:
//
- // Content-Type: image/png;
+ // Content-Type: image/png;
// name="=?us-ascii?Q?Logo_VMime=2Epng?="
// Using 'vmime::text' to parse the data is safe even
@@ -248,7 +248,20 @@ void parameter::parse(const parsingContext& ctx, const std::vector <valueChunk>&
value << t.getWholeBuffer();
if (!foundCharsetChunk)
- ch = t.getWordAt(0)->getCharset();
+ {
+ // This is still wrong. Each word can have it's own charset, and can
+ // be mixed (eg. iso-8859-1 and iso-2022-jp), but very unlikely. Real
+ // fix is to have parameters store a vmime::text instead of a
+ // vmime::word in m_value. But that changes the interface.
+ for (size_t i = 0 ; i < t.getWordCount() ; ++i)
+ {
+ if (t.getWordAt(i)->getCharset() != ch && ch == charsets::US_ASCII)
+ {
+ ch = t.getWordAt(i)->getCharset();
+ break;
+ }
+ }
+ }
}
}
}
diff --git a/src/parameterizedHeaderField.cpp b/src/parameterizedHeaderField.cpp
index 619fe7cf..c4e0b368 100644
--- a/src/parameterizedHeaderField.cpp
+++ b/src/parameterizedHeaderField.cpp
@@ -98,7 +98,7 @@ void parameterizedHeaderField::parseImpl
// Advance up to ';', if any
string::size_type valueLength = 0;
- while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text
+ while (p < pend && *p != ';' && (!parserHelpers::isSpace(*p))) // FIXME: support ";" inside quoted or RFC-2047-encoded text
{
++p;
++valueLength;
@@ -119,6 +119,12 @@ void parameterizedHeaderField::parseImpl
{
std::map <string, paramInfo> params;
+ if (*p != ';')
+ {
+ while (p < pend && *p != ';') // FIXME: support ";" inside quoted or RFC-2047-encoded text
+ ++p;
+ }
+
while (*p == ';')
{
// Skip ';'
diff --git a/src/utility/streamUtils.cpp b/src/utility/streamUtils.cpp
index 72916547..06ea17a1 100644
--- a/src/utility/streamUtils.cpp
+++ b/src/utility/streamUtils.cpp
@@ -68,7 +68,7 @@ stream::size_type bufferedStreamCopyRange(inputStream& is, outputStream& os,
while (!is.eof() && total < length)
{
const stream::size_type remaining = std::min(length - total, blockSize);
- const stream::size_type read = is.read(buffer, blockSize);
+ const stream::size_type read = is.read(buffer, remaining);
if (read != 0)
{
diff --git a/src/word.cpp b/src/word.cpp
index b558b842..8e254865 100644
--- a/src/word.cpp
+++ b/src/word.cpp
@@ -125,7 +125,7 @@ ref <word> word::parseNext
if (!unencoded.empty())
{
- if (prevIsEncoded)
+ if (prevIsEncoded && !isFirst)
unencoded = whiteSpaces + unencoded;
ref <word> w = vmime::create <word>(unencoded, defaultCharset);
@@ -200,11 +200,13 @@ ref <word> word::parseNext
++pos;
}
- if (startPos != end && !isFirst && prevIsEncoded)
- unencoded += whiteSpaces;
-
if (startPos != end)
+ {
+ if (prevIsEncoded && !isFirst)
+ unencoded = whiteSpaces + unencoded;
+
unencoded += buffer.substr(startPos, end - startPos);
+ }
// Treat unencoded text at the end of the buffer
if (!unencoded.empty())
diff --git a/src/wordEncoder.cpp b/src/wordEncoder.cpp
index 82a74cff..332f9bf2 100644
--- a/src/wordEncoder.cpp
+++ b/src/wordEncoder.cpp
@@ -247,7 +247,7 @@ bool wordEncoder::isEncodingNeeded
return true;
// If any RFC-2047 sequence is found in the buffer, encode it
- if (buffer.find("=?") != string::npos)
+ if (buffer.find("=?") != string::npos || buffer.find("?=") != string::npos)
return true;
return false;
diff --git a/tests/charset/Makefile b/tests/charset/Makefile
deleted file mode 100644
index e46fafa5..00000000
--- a/tests/charset/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-main: main.cpp ../../libvmime-debug.a
- g++ -g -o main main.cpp -I../.. ../../libvmime-debug.a -lgnutls -lgsasl
-
diff --git a/tests/charset/main.cpp b/tests/charset/main.cpp
deleted file mode 100644
index d8523461..00000000
--- a/tests/charset/main.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
-//
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 3 of
-// the License, or (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Linking this library statically or dynamically with other modules is making
-// a combined work based on this library. Thus, the terms and conditions of
-// the GNU General Public License cover the whole combination.
-//
-
-#include <iostream>
-#include <ostream>
-
-#include "vmime/vmime.hpp"
-#include "vmime/platforms/posix/posixHandler.hpp"
-
-
-int main(int argc, char* argv[])
-{
- // VMime initialization
- vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
-
-
- const vmime::string from(argv[1]);
- const vmime::string to(argv[2]);
-
- vmime::utility::inputStreamAdapter in(std::cin);
- vmime::utility::outputStreamAdapter out(std::cout);
-
- vmime::charset::convert(in, out, from, to);
-}
diff --git a/tests/charset/run-test.sh b/tests/charset/run-test.sh
deleted file mode 100755
index 95846c06..00000000
--- a/tests/charset/run-test.sh
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/sh
-
-TEST_DIR="./test-suites"
-TEMP_DIR="/tmp"
-PROGRAM="./main"
-
-
-testFiles=`cd $TEST_DIR ; find . -maxdepth 1 -regex '\./[^\.]*\.in\..*' -type f`
-
-echo
-echo Testing charset conversions
-echo =====================================================================
-
-for testFile in $testFiles ; do
-
- testName=`echo $testFile | sed 's/^\.\/\([^\.]*\).*/\1/'`
- sourceCharset=`echo $testFile | sed 's/^\.\/[^\.]*\.[^\.]*\.\(.*\)/\1/'`
-
- testOutFiles=`cd $TEST_DIR ; find . -maxdepth 1 -regex "\./$testName\.out\..*" -type f`
-
- for testOutFile in $testOutFiles ; do
-
- destCharset=`echo $testOutFile | sed 's/^\.\/[^\.]*\.[^\.]*\.\(.*\)/\1/'`
-
- printf %20s "$testName "
- printf %30s "$sourceCharset --> $destCharset : "
-
- $PROGRAM $sourceCharset $destCharset < $TEST_DIR/$testFile > $TEMP_DIR/vmime_result
-
- diff="diff $TEMP_DIR/vmime_result $TEST_DIR/$testOutFile"
- res=`$diff`
-
- if [ "$res" = "" ]
- then
- echo "[OK]"
- else
- diffFile=$TEMP_DIR/vmime.charset.$testName.$sourceCharset.$destCharset.diff
- echo "[NO: diff file is $diffFile]"
- $diff > $diffFile
- fi
-
- done
-
-done
-
-echo
-
diff --git a/tests/charset/test-suites/gnu.in.utf-8 b/tests/charset/test-suites/gnu.in.utf-8
deleted file mode 100644
index 782bb84e..00000000
--- a/tests/charset/test-suites/gnu.in.utf-8
+++ /dev/null
@@ -1,48 +0,0 @@
-Korean Part.
-GNU 프로젝트의 웹서버인 www.gnu.org에 오신 것을 환영합니다. GNU 프로젝트는
-GNU 시스템이라고 불리는 유닉스 형태의 완벽한 자유 소프트웨어 운영체제를
-개발하기 위해서 1984년부터 시작되었습니다. (GNU라는 단어는 ``GNU's Not
-Unix''를 의미하는 재귀적 약어이며 ``그-뉴"라고 발음합니다.) GNU
-시스템으로부터 연유한 다양한 종류의 운영체제들이 현재 ``리눅스''라는
-이름으로 사용되고 있지만, 시스템 커널로 리눅스를 탑재한 운영체제의 보다
-정확한 이름은 GNU/리눅스 시스템입니다.
-
-Japanese Part
-
-GNU プロジェクトのウェブサーバ、www.gnu.org へようこそ。1984 年のプロジェクト
-開始以来、GNU プロジェクトでは、Unix に似た フリーソフトウェアの完全なオペレー
-ティングシステム、GNU システムを開発して来ました(GNU とは「GNU's Not Unix(GNU
-は Unix ではない)」の再帰頭字語であり、「グニュー」と発音されます)。現在、カーネ
-ルとして Linux を用いた GNU システムのさまざまな変種が広く使われています。これ
-らのシステムは「Linux」と呼ばれることが多いのですが、より正確には GNU/Linux
-システム と呼ばれるものなのです。
-
-Chinese Part.
-
-歡迎來到GNU 專案的伺服主機,www.gnu.org。 GNU 專案 開始於1984年,旨在發展一
-個 Unix-like 且為 自由軟體 的作業系統: GNU 系統。(GNU 是由``GNU's Not
-Unix''所遞迴定義出的頭字語);它的發音為"guh-NEW"。各種使用 Linux 作為核心的 GNU
-作業系統正被廣泛的使用著;雖然這些系統通常被稱作 ``Linux'',但是它們應該更精
-確地被稱為 GNU/Linux 系統。
-
-English Part.
-
-Welcome to the GNU Project web server, www.gnu.org. The GNU Project was
-launched in 1984 to develop a complete Unix-like operating system which is
-free software: the GNU system. (GNU is a recursive acronym for ``GNU's Not
-Unix''; it is pronounced "guh-NEW".) Variants of the GNU operating system,
-which use the kernel Linux, are now widely used; though these systems are
-often referred to as ``Linux'', they are more accurately called GNU/Linux
-systems.
-
-French Part.
-Bienvenue sur le serveur web du projet GNU, www.gnu.org. Le projet GNU a été
-lancé en 1984 afin de développer un système d'exploitation complet,
-semblable à Unix et qui soit un logiciel libre: le système GNU. (« GNU »
-est l'acronyme récursif the « GNU's Not Unix »; on le prononce « gnou »
-avec un G audible) Des variantes du système d'exploitation GNU, basées sur
-le noyau « Linux », sont utilisées largement à présent; bien que ces
-systèmes soient communément appelés par le terme « Linux », ils le
-seraient plus exactement par « GNU/Linux ».
-
-
diff --git a/tests/charset/test-suites/gnu.out.iso-8859-1 b/tests/charset/test-suites/gnu.out.iso-8859-1
deleted file mode 100644
index bc11399e..00000000
--- a/tests/charset/test-suites/gnu.out.iso-8859-1
+++ /dev/null
@@ -1,48 +0,0 @@
-Korean Part.
-GNU ??????????????? ???????????? www.gnu.org??? ?????? ?????? ???????????????. GNU ???????????????
-GNU ?????????????????? ????????? ????????? ????????? ????????? ?????? ??????????????? ???????????????
-???????????? ????????? 1984????????? ?????????????????????. (GNU?????? ????????? ``GNU's Not
-Unix''??? ???????????? ????????? ???????????? ``???-???"?????? ???????????????.) GNU
-????????????????????? ????????? ????????? ????????? ?????????????????? ?????? ``?????????''??????
-???????????? ???????????? ?????????, ????????? ????????? ???????????? ????????? ??????????????? ??????
-????????? ????????? GNU/????????? ??????????????????.
-
-Japanese Part
-
-GNU ??????????????????????????????????????????www.gnu.org ??????????????????1984 ????????????????????????
-???????????????GNU ???????????????????????????Unix ????????? ???????????????????????????????????????????????????
-???????????????????????????GNU ???????????????????????????????????????(GNU ?????????GNU's Not Unix(GNU
-??? Unix ????????????)????????????????????????????????????????????????????????????????????????)?????????????????????
-???????????? Linux ???????????? GNU ???????????????????????????????????????????????????????????????????????????
-????????????????????????Linux?????????????????????????????????????????????????????????????????? GNU/Linux
-???????????? ????????????????????????????????????
-
-Chinese Part.
-
-????????????GNU ????????????????????????www.gnu.org??? GNU ?????? ?????????1984?????????????????????
-??? Unix-like ?????? ???????????? ?????????????????? GNU ????????????GNU ??????``GNU's Not
-Unix''???????????????????????????????????????????????????"guh-NEW"??????????????? Linux ??????????????? GNU
-???????????????????????????????????????????????????????????????????????? ``Linux''???????????????????????????
-??????????????? GNU/Linux ?????????
-
-English Part.
-
-Welcome to the GNU Project web server, www.gnu.org. The GNU Project was
-launched in 1984 to develop a complete Unix-like operating system which is
-free software: the GNU system. (GNU is a recursive acronym for ``GNU's Not
-Unix''; it is pronounced "guh-NEW".) Variants of the GNU operating system,
-which use the kernel Linux, are now widely used; though these systems are
-often referred to as ``Linux'', they are more accurately called GNU/Linux
-systems.
-
-French Part.
-Bienvenue sur le serveur web du projet GNU, www.gnu.org. Le projet GNU a �t�
-lanc� en 1984 afin de d�velopper un syst�me d'exploitation complet,
-semblable � Unix et qui soit un logiciel libre: le syst�me GNU. (� GNU �
-est l'acronyme r�cursif the � GNU's Not Unix �; on le prononce � gnou �
-avec un G audible) Des variantes du syst�me d'exploitation GNU, bas�es sur
-le noyau � Linux �, sont utilis�es largement � pr�sent; bien que ces
-syst�mes soient commun�ment appel�s par le terme � Linux �, ils le
-seraient plus exactement par � GNU/Linux �.
-
-
diff --git a/tests/misc/importanceHelperTest.cpp b/tests/misc/importanceHelperTest.cpp
index 1227cb40..f4696efb 100644
--- a/tests/misc/importanceHelperTest.cpp
+++ b/tests/misc/importanceHelperTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/misc/importanceHelper.hpp"
-#define VMIME_TEST_SUITE importanceHelperTest
-#define VMIME_TEST_SUITE_MODULE "Misc"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(importanceHelperTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testResetImportance)
diff --git a/tests/net/maildir/maildirStoreTest.cpp b/tests/net/maildir/maildirStoreTest.cpp
index d908d471..10de80df 100644
--- a/tests/net/maildir/maildirStoreTest.cpp
+++ b/tests/net/maildir/maildirStoreTest.cpp
@@ -29,10 +29,6 @@
#include "vmime/net/maildir/maildirFormat.hpp"
-#define VMIME_TEST_SUITE maildirStoreTest
-#define VMIME_TEST_SUITE_MODULE "Net/Maildir"
-
-
// Shortcuts and helpers
typedef vmime::utility::file::path fspath;
typedef vmime::utility::file::path::component fspathc;
@@ -142,7 +138,7 @@ static const vmime::string TEST_MAILDIRFILES_COURIER[] = // files to create and
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(maildirStoreTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testDetectFormat_KMail)
diff --git a/tests/net/pop3/POP3ResponseTest.cpp b/tests/net/pop3/POP3ResponseTest.cpp
index 54c36274..1541ce8b 100644
--- a/tests/net/pop3/POP3ResponseTest.cpp
+++ b/tests/net/pop3/POP3ResponseTest.cpp
@@ -26,14 +26,10 @@
#include "vmime/net/pop3/POP3Response.hpp"
-#define VMIME_TEST_SUITE POP3ResponseTest
-#define VMIME_TEST_SUITE_MODULE "Net/POP3"
-
-
using namespace vmime::net::pop3;
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(POP3ResponseTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testSingleLineResponseOK)
diff --git a/tests/net/pop3/POP3UtilsTest.cpp b/tests/net/pop3/POP3UtilsTest.cpp
index f1e4f597..ac92056a 100644
--- a/tests/net/pop3/POP3UtilsTest.cpp
+++ b/tests/net/pop3/POP3UtilsTest.cpp
@@ -27,14 +27,10 @@
#include "vmime/net/pop3/POP3Response.hpp"
-#define VMIME_TEST_SUITE POP3UtilsTest
-#define VMIME_TEST_SUITE_MODULE "Net/POP3"
-
-
using namespace vmime::net::pop3;
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(POP3UtilsTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParseMultiListOrUidlResponse)
diff --git a/tests/net/smtp/SMTPCommandSetTest.cpp b/tests/net/smtp/SMTPCommandSetTest.cpp
index a315d678..0cf4b03b 100644
--- a/tests/net/smtp/SMTPCommandSetTest.cpp
+++ b/tests/net/smtp/SMTPCommandSetTest.cpp
@@ -30,11 +30,7 @@
using namespace vmime::net::smtp;
-#define VMIME_TEST_SUITE SMTPCommandSetTest
-#define VMIME_TEST_SUITE_MODULE "Net/SMTP"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(SMTPCommandSetTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testCreate)
diff --git a/tests/net/smtp/SMTPCommandTest.cpp b/tests/net/smtp/SMTPCommandTest.cpp
index 0ff52741..10052f3f 100644
--- a/tests/net/smtp/SMTPCommandTest.cpp
+++ b/tests/net/smtp/SMTPCommandTest.cpp
@@ -29,11 +29,7 @@
using namespace vmime::net::smtp;
-#define VMIME_TEST_SUITE SMTPCommandTest
-#define VMIME_TEST_SUITE_MODULE "Net/SMTP"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(SMTPCommandTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testCreateCommand)
diff --git a/tests/net/smtp/SMTPResponseTest.cpp b/tests/net/smtp/SMTPResponseTest.cpp
index 17c7774c..7d8a13c9 100644
--- a/tests/net/smtp/SMTPResponseTest.cpp
+++ b/tests/net/smtp/SMTPResponseTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/net/smtp/SMTPResponse.hpp"
-#define VMIME_TEST_SUITE SMTPResponseTest
-#define VMIME_TEST_SUITE_MODULE "Net/SMTP"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(SMTPResponseTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testSingleLineResponse)
diff --git a/tests/net/smtp/SMTPTransportTest.cpp b/tests/net/smtp/SMTPTransportTest.cpp
index 4f34f71f..4ffda792 100644
--- a/tests/net/smtp/SMTPTransportTest.cpp
+++ b/tests/net/smtp/SMTPTransportTest.cpp
@@ -24,15 +24,11 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE SMTPTransportTest
-#define VMIME_TEST_SUITE_MODULE "Net/SMTP"
-
-
class greetingErrorSMTPTestSocket;
class MAILandRCPTSMTPTestSocket;
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(SMTPTransportTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testGreetingError)
diff --git a/tests/parser/attachmentHelperTest.cpp b/tests/parser/attachmentHelperTest.cpp
index c043db23..0ddf2448 100644
--- a/tests/parser/attachmentHelperTest.cpp
+++ b/tests/parser/attachmentHelperTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE attachmentHelperTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(attachmentHelperTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testAddAttachment1)
diff --git a/tests/parser/bodyPartTest.cpp b/tests/parser/bodyPartTest.cpp
index 1c5545a2..487b3160 100644
--- a/tests/parser/bodyPartTest.cpp
+++ b/tests/parser/bodyPartTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE bodyPartTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(bodyPartTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
diff --git a/tests/parser/charsetFilteredOutputStreamTest.cpp b/tests/parser/charsetFilteredOutputStreamTest.cpp
new file mode 100644
index 00000000..fdfed2c6
--- /dev/null
+++ b/tests/parser/charsetFilteredOutputStreamTest.cpp
@@ -0,0 +1,205 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#include "tests/testUtils.hpp"
+
+#include "vmime/charset.hpp"
+#include "vmime/charsetConverter.hpp"
+
+#include "charsetTestSuites.hpp"
+
+
+VMIME_TEST_SUITE_BEGIN(charsetFilteredOutputStreamTest)
+
+ VMIME_TEST_LIST_BEGIN
+ VMIME_TEST(testInputBufferUnderflow)
+ VMIME_TEST(testInvalidInput1)
+ VMIME_TEST(testStreamCopy)
+ VMIME_TEST(testOneByteAtTime)
+ VMIME_TEST(testVariableInputChunk)
+ VMIME_TEST_LIST_END
+
+
+ void testInputBufferUnderflow()
+ {
+ vmime::ref <vmime::charsetConverter> cc =
+ vmime::charsetConverter::create("utf-8", "iso-8859-1");
+
+ vmime::string output;
+ vmime::utility::outputStreamStringAdapter os(output);
+ vmime::ref <vmime::utility::filteredOutputStream> cfos = cc->getFilteredOutputStream(os);
+
+ // føo = 66 c3 b8 6f [UTF8]
+ // føo = 66 c3 b8 6f [latin1]
+
+ cfos->write("\x66\xc3", 2);
+
+ // Incomplete UTF-8 sequence was not converted
+ VASSERT_EQ("chunk 1", toHex("f"), toHex(output));
+
+ // Write second byte of UTF-8 sequence
+ cfos->write("\xb8\x6f", 2);
+
+ VASSERT_EQ("chunk 2", toHex("f\xf8o"), toHex(output));
+ }
+
+ void testInvalidInput1()
+ {
+ vmime::string in("foo\xab\xcd\xef bar");
+ vmime::string expectedOut("foo??? bar");
+
+ vmime::string actualOut;
+ vmime::utility::outputStreamStringAdapter osa(actualOut);
+
+ vmime::ref <vmime::charsetConverter> conv =
+ vmime::charsetConverter::create
+ (vmime::charset("utf-8"),
+ vmime::charset("iso-8859-1"));
+
+ vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
+ conv->getFilteredOutputStream(osa);
+
+ vmime::utility::inputStreamStringAdapter is(in);
+
+ vmime::utility::stream::value_type buffer[16];
+
+ for (int i = 0 ; !is.eof() ; ++i)
+ os->write(buffer, is.read(buffer, 1));
+
+ os->flush();
+
+ VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
+ }
+
+ // Using 'bufferedStreamCopy'
+ void testStreamCopy()
+ {
+ for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i)
+ {
+ const charsetTestSuiteStruct& entry = charsetTestSuites[i];
+
+ std::ostringstream testName;
+ testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset;
+
+ const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength);
+ vmime::string in(entry.fromBytes, entry.fromBytes + inLength);
+
+ const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength);
+ vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength);
+
+ vmime::string actualOut;
+ vmime::utility::outputStreamStringAdapter osa(actualOut);
+
+ vmime::ref <vmime::charsetConverter> conv =
+ vmime::charsetConverter::create(entry.fromCharset, entry.toCharset);
+
+ vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
+ conv->getFilteredOutputStream(osa);
+
+ vmime::utility::inputStreamStringAdapter is(in);
+
+ vmime::utility::bufferedStreamCopy(is, *os);
+
+ os->flush();
+
+ VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut));
+ }
+ }
+
+ // One byte at a time
+ void testOneByteAtTime()
+ {
+ for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i)
+ {
+ const charsetTestSuiteStruct& entry = charsetTestSuites[i];
+
+ std::ostringstream testName;
+ testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset;
+
+ const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength);
+ vmime::string in(entry.fromBytes, entry.fromBytes + inLength);
+
+ const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength);
+ vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength);
+
+ vmime::string actualOut;
+ vmime::utility::outputStreamStringAdapter osa(actualOut);
+
+ vmime::ref <vmime::charsetConverter> conv =
+ vmime::charsetConverter::create(entry.fromCharset, entry.toCharset);
+
+ vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
+ conv->getFilteredOutputStream(osa);
+
+ vmime::utility::inputStreamStringAdapter is(in);
+
+ vmime::utility::stream::value_type buffer[16];
+
+ for (int i = 0 ; !is.eof() ; ++i)
+ os->write(buffer, is.read(buffer, 1));
+
+ os->flush();
+
+ VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut));
+ }
+ }
+
+ // Variable chunks
+ void testVariableInputChunk()
+ {
+ for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i)
+ {
+ const charsetTestSuiteStruct& entry = charsetTestSuites[i];
+
+ std::ostringstream testName;
+ testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset;
+
+ const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength);
+ vmime::string in(entry.fromBytes, entry.fromBytes + inLength);
+
+ const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength);
+ vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength);
+
+ vmime::string actualOut;
+ vmime::utility::outputStreamStringAdapter osa(actualOut);
+
+ vmime::ref <vmime::charsetConverter> conv =
+ vmime::charsetConverter::create(entry.fromCharset, entry.toCharset);
+
+ vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
+ conv->getFilteredOutputStream(osa);
+
+ vmime::utility::inputStreamStringAdapter is(in);
+
+ vmime::utility::stream::value_type buffer[16];
+
+ for (int i = 0 ; !is.eof() ; ++i)
+ os->write(buffer, is.read(buffer, (i % 5) + 1));
+
+ os->flush();
+
+ VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut));
+ }
+ }
+
+VMIME_TEST_SUITE_END
diff --git a/tests/parser/charsetTest.cpp b/tests/parser/charsetTest.cpp
index eaedb218..8725c530 100644
--- a/tests/parser/charsetTest.cpp
+++ b/tests/parser/charsetTest.cpp
@@ -23,230 +23,76 @@
#include "tests/testUtils.hpp"
+#include "charsetTestSuites.hpp"
-#define VMIME_TEST_SUITE charsetTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-// Excerpt from http://www.gnu.org/
-static const vmime::charset inputCharset("gb2312");
-static const char inputBytes[] =
- "\xbb\xb6\xd3\xad\xc0\xb4\xb5\xbd\x20\x47\x4e\x55\x20\xb9\xa4\xb3"
- "\xcc\xb5\xc4\xcd\xf8\xd2\xb3\xcb\xc5\xb7\xfe\xd6\xf7\xbb\xfa\x20"
- "\x77\x77\x77\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xa1\xa3\x20\x47"
- "\x4e\x55\x20\xb9\xa4\xb3\xcc\x20\xbf\xaa\xca\xbc\xec\xb6\xd2\xbb"
- "\xbe\xc5\xb0\xcb\xcb\xc4\xc4\xea\xa3\xac\xd6\xbc\xd4\xda\xb7\xa2"
- "\xd5\xb9\xd2\xbb\xb8\xf6\xc0\xe0\xcb\xc6\x20\x55\x6e\x69\x78\x20"
- "\xa3\xac\xc7\xd2\xce\xaa\x20\xd7\xd4\xd3\xc9\xc8\xed\xbc\xfe\x20"
- "\xb5\xc4\xcd\xea\xd5\xfb\xb2\xd9\xd7\xf7\xcf\xb5\xcd\xb3\xa3\xba"
- "\x20\x47\x4e\x55\x20\xcf\xb5\xcd\xb3\xa1\xa3\xa3\xa8\x47\x4e\x55"
- "\x20\xca\xc7\xd3\xc9\xa1\xb0\x47\x4e\x55\x27\x73\x20\x4e\x6f\x74"
- "\x20\x55\x6e\x69\x78\xa1\xb1\xcb\xf9\xb5\xdd\xbb\xd8\xb6\xa8\xd2"
- "\xe5\xb3\xf6\xb5\xc4\xca\xd7\xd7\xd6\xc4\xb8\xcb\xf5\xd0\xb4\xd3"
- "\xef\xa3\xbb\xcb\xfc\xb5\xc4\xb7\xa2\xd2\xf4\xce\xaa\xa1\xb0\x67"
- "\x75\x68\x2d\x4e\x45\x57\xa1\xb1\xa3\xa9\xa1\xa3\xb8\xf7\xd6\xd6"
- "\xca\xb9\xd3\xc3\x20\x4c\x69\x6e\x75\x78\x20\xd7\xf7\xce\xaa\xc4"
- "\xda\xba\xcb\xb5\xc4\x20\x47\x4e\x55\x20\xb2\xd9\xd7\xf7\xcf\xb5"
- "\xcd\xb3\xd5\xfd\xb1\xbb\xb9\xe3\xb7\xba\xb5\xd8\xca\xb9\xd3\xc3"
- "\xd6\xf8\xa3\xbb\xcb\xe4\xc8\xbb\xd5\xe2\xd0\xa9\xcf\xb5\xcd\xb3"
- "\xcd\xa8\xb3\xa3\xb1\xbb\xb3\xc6\xd7\xf7\xce\xaa\xa1\xb0\x4c\x69"
- "\x6e\x75\x78\xa1\xb1\xa3\xac\xb5\xab\xca\xc7\xcb\xfc\xc3\xc7\xd3"
- "\xa6\xb8\xc3\xb8\xfc\xbe\xab\xc8\xb7\xb5\xd8\xb1\xbb\xb3\xc6\xce"
- "\xaa\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xcf\xb5\xcd\xb3"
- "\x20\xa1\xa3\x0a";
-
-static const vmime::charset outputCharset("utf-8");
-static const char outputBytes[] =
- "\xe6\xac\xa2\xe8\xbf\x8e\xe6\x9d\xa5\xe5\x88\xb0\x20\x47\x4e\x55"
- "\x20\xe5\xb7\xa5\xe7\xa8\x8b\xe7\x9a\x84\xe7\xbd\x91\xe9\xa1\xb5"
- "\xe4\xbc\xba\xe6\x9c\x8d\xe4\xb8\xbb\xe6\x9c\xba\x20\x77\x77\x77"
- "\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xe3\x80\x82\x20\x47\x4e\x55"
- "\x20\xe5\xb7\xa5\xe7\xa8\x8b\x20\xe5\xbc\x80\xe5\xa7\x8b\xe6\x96"
- "\xbc\xe4\xb8\x80\xe4\xb9\x9d\xe5\x85\xab\xe5\x9b\x9b\xe5\xb9\xb4"
- "\xef\xbc\x8c\xe6\x97\xa8\xe5\x9c\xa8\xe5\x8f\x91\xe5\xb1\x95\xe4"
- "\xb8\x80\xe4\xb8\xaa\xe7\xb1\xbb\xe4\xbc\xbc\x20\x55\x6e\x69\x78"
- "\x20\xef\xbc\x8c\xe4\xb8\x94\xe4\xb8\xba\x20\xe8\x87\xaa\xe7\x94"
- "\xb1\xe8\xbd\xaf\xe4\xbb\xb6\x20\xe7\x9a\x84\xe5\xae\x8c\xe6\x95"
- "\xb4\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xef\xbc\x9a"
- "\x20\x47\x4e\x55\x20\xe7\xb3\xbb\xe7\xbb\x9f\xe3\x80\x82\xef\xbc"
- "\x88\x47\x4e\x55\x20\xe6\x98\xaf\xe7\x94\xb1\xe2\x80\x9c\x47\x4e"
- "\x55\x27\x73\x20\x4e\x6f\x74\x20\x55\x6e\x69\x78\xe2\x80\x9d\xe6"
- "\x89\x80\xe9\x80\x92\xe5\x9b\x9e\xe5\xae\x9a\xe4\xb9\x89\xe5\x87"
- "\xba\xe7\x9a\x84\xe9\xa6\x96\xe5\xad\x97\xe6\xaf\x8d\xe7\xbc\xa9"
- "\xe5\x86\x99\xe8\xaf\xad\xef\xbc\x9b\xe5\xae\x83\xe7\x9a\x84\xe5"
- "\x8f\x91\xe9\x9f\xb3\xe4\xb8\xba\xe2\x80\x9c\x67\x75\x68\x2d\x4e"
- "\x45\x57\xe2\x80\x9d\xef\xbc\x89\xe3\x80\x82\xe5\x90\x84\xe7\xa7"
- "\x8d\xe4\xbd\xbf\xe7\x94\xa8\x20\x4c\x69\x6e\x75\x78\x20\xe4\xbd"
- "\x9c\xe4\xb8\xba\xe5\x86\x85\xe6\xa0\xb8\xe7\x9a\x84\x20\x47\x4e"
- "\x55\x20\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xe6\xad"
- "\xa3\xe8\xa2\xab\xe5\xb9\xbf\xe6\xb3\x9b\xe5\x9c\xb0\xe4\xbd\xbf"
- "\xe7\x94\xa8\xe8\x91\x97\xef\xbc\x9b\xe8\x99\xbd\xe7\x84\xb6\xe8"
- "\xbf\x99\xe4\xba\x9b\xe7\xb3\xbb\xe7\xbb\x9f\xe9\x80\x9a\xe5\xb8"
- "\xb8\xe8\xa2\xab\xe7\xa7\xb0\xe4\xbd\x9c\xe4\xb8\xba\xe2\x80\x9c"
- "\x4c\x69\x6e\x75\x78\xe2\x80\x9d\xef\xbc\x8c\xe4\xbd\x86\xe6\x98"
- "\xaf\xe5\xae\x83\xe4\xbb\xac\xe5\xba\x94\xe8\xaf\xa5\xe6\x9b\xb4"
- "\xe7\xb2\xbe\xe7\xa1\xae\xe5\x9c\xb0\xe8\xa2\xab\xe7\xa7\xb0\xe4"
- "\xb8\xba\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xe7\xb3\xbb"
- "\xe7\xbb\x9f\x20\xe3\x80\x82\x0a";
-
-
-
-VMIME_TEST_SUITE_BEGIN
+
+VMIME_TEST_SUITE_BEGIN(charsetTest)
VMIME_TEST_LIST_BEGIN
// Test valid input
VMIME_TEST(testConvertStringValid)
VMIME_TEST(testConvertStreamValid)
- VMIME_TEST(testFilterValid1)
- VMIME_TEST(testFilterValid2)
- VMIME_TEST(testFilterValid3)
VMIME_TEST(testEncodingHebrew1255)
- // Test invalid input
- VMIME_TEST(testFilterInvalid1)
-
// IDNA
VMIME_TEST(testEncodeIDNA)
VMIME_TEST(testDecodeIDNA)
- // TODO: more tests
+ VMIME_TEST(testUTF7Support)
VMIME_TEST_LIST_END
void testConvertStringValid()
{
- vmime::string in(inputBytes, sizeof(inputBytes) - 1);
- vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1);
- vmime::string actualOut;
-
- vmime::charset::convert
- (in, actualOut, inputCharset, outputCharset);
-
- VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
- }
-
- void testConvertStreamValid()
- {
- vmime::string in(inputBytes, sizeof(inputBytes) - 1);
- vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1);
-
- vmime::string actualOut;
- vmime::utility::outputStreamStringAdapter os(actualOut);
-
- vmime::utility::inputStreamStringAdapter is(in);
-
- vmime::charset::convert
- (is, os, inputCharset, outputCharset);
-
- os.flush();
-
- VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
- }
-
- // Using 'bufferedStreamCopy'
- void testFilterValid1()
- {
- vmime::string in(inputBytes, sizeof(inputBytes) - 1);
- vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1);
-
- vmime::string actualOut;
- vmime::utility::outputStreamStringAdapter osa(actualOut);
-
- vmime::ref <vmime::charsetConverter> conv =
- vmime::charsetConverter::create(inputCharset, outputCharset);
-
- vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
- conv->getFilteredOutputStream(osa);
-
- vmime::utility::inputStreamStringAdapter is(in);
-
- vmime::utility::bufferedStreamCopy(is, *os);
-
- os->flush();
-
- VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
- }
-
- // One byte at a time
- void testFilterValid2()
- {
- vmime::string in(inputBytes, sizeof(inputBytes) - 1);
- vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1);
-
- vmime::string actualOut;
- vmime::utility::outputStreamStringAdapter osa(actualOut);
-
- vmime::ref <vmime::charsetConverter> conv =
- vmime::charsetConverter::create(inputCharset, outputCharset);
-
- vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
- conv->getFilteredOutputStream(osa);
-
- vmime::utility::inputStreamStringAdapter is(in);
-
- vmime::utility::stream::value_type buffer[16];
-
- for (int i = 0 ; !is.eof() ; ++i)
- os->write(buffer, is.read(buffer, 1));
-
- os->flush();
-
- VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
- }
-
- // Variable chunks
- void testFilterValid3()
- {
- vmime::string in(inputBytes, sizeof(inputBytes) - 1);
- vmime::string expectedOut(outputBytes, sizeof(outputBytes) - 1);
-
- vmime::string actualOut;
- vmime::utility::outputStreamStringAdapter osa(actualOut);
-
- vmime::ref <vmime::charsetConverter> conv =
- vmime::charsetConverter::create(inputCharset, outputCharset);
+ for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i)
+ {
+ const charsetTestSuiteStruct& entry = charsetTestSuites[i];
- vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
- conv->getFilteredOutputStream(osa);
+ std::ostringstream testName;
+ testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset;
- vmime::utility::inputStreamStringAdapter is(in);
+ const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength);
+ vmime::string in(entry.fromBytes, entry.fromBytes + inLength);
- vmime::utility::stream::value_type buffer[16];
+ const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength);
+ vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength);
- for (int i = 0 ; !is.eof() ; ++i)
- os->write(buffer, is.read(buffer, (i % 5) + 1));
+ vmime::string actualOut;
- os->flush();
+ vmime::charset::convert
+ (in, actualOut, entry.fromCharset, entry.toCharset);
- VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
+ VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut));
+ }
}
- void testFilterInvalid1()
+ void testConvertStreamValid()
{
- vmime::string in("foo\xab\xcd\xef bar");
- vmime::string expectedOut("foo??? bar");
+ for (unsigned int i = 0 ; i < charsetTestSuitesCount ; ++i)
+ {
+ const charsetTestSuiteStruct& entry = charsetTestSuites[i];
- vmime::string actualOut;
- vmime::utility::outputStreamStringAdapter osa(actualOut);
+ std::ostringstream testName;
+ testName << i << ": " << entry.fromCharset << " -> " << entry.toCharset;
- vmime::ref <vmime::charsetConverter> conv =
- vmime::charsetConverter::create
- (vmime::charset("utf-8"),
- vmime::charset("iso-8859-1"));
+ const unsigned int inLength = (entry.fromLength == 0 ? strlen(entry.fromBytes) : entry.fromLength);
+ vmime::string in(entry.fromBytes, entry.fromBytes + inLength);
- vmime::ref <vmime::utility::charsetFilteredOutputStream> os =
- conv->getFilteredOutputStream(osa);
+ const unsigned int outLength = (entry.toLength == 0 ? strlen(entry.toBytes) : entry.toLength);
+ vmime::string expectedOut(entry.toBytes, entry.toBytes + outLength);
- vmime::utility::inputStreamStringAdapter is(in);
+ vmime::string actualOut;
+ vmime::utility::outputStreamStringAdapter os(actualOut);
- vmime::utility::stream::value_type buffer[16];
+ vmime::utility::inputStreamStringAdapter is(in);
- for (int i = 0 ; !is.eof() ; ++i)
- os->write(buffer, is.read(buffer, 1));
+ vmime::charset::convert
+ (is, os, entry.fromCharset, entry.toCharset);
- os->flush();
+ os.flush();
- VASSERT_EQ("1", toHex(expectedOut), toHex(actualOut));
+ VASSERT_EQ(testName.str(), toHex(expectedOut), toHex(actualOut));
+ }
}
void testEncodingHebrew1255()
@@ -259,44 +105,6 @@ VMIME_TEST_SUITE_BEGIN
VASSERT_EQ("1", "=?windows-1255?B?6fn3+On5+Pfp6fk=?=", encoded);
}
- // Conversion to hexadecimal for easier debugging
- static const vmime::string toHex(const vmime::string str)
- {
- static const char hexChars[] = "0123456789abcdef";
-
- vmime::string res = "\n";
-
- for (unsigned int i = 0 ; i < str.length() ; i += 16)
- {
- unsigned int r = std::min
- (static_cast <size_t>(16), str.length() - i);
-
- vmime::string hex;
- vmime::string chr;
-
- for (unsigned int j = 0 ; j < r ; ++j)
- {
- const unsigned char c = str[i + j];
-
- hex += hexChars[c / 16];
- hex += hexChars[c % 16];
- hex += " ";
-
- if (c >= 32 && c <= 127)
- chr += c;
- else
- chr += '.';
- }
-
- for (unsigned int j = r ; j < 16 ; ++j)
- hex += " ";
-
- res += hex + " " + chr + "\n";
- }
-
- return res;
- }
-
static const vmime::string convertHelper
(const vmime::string& in, const vmime::charset& csrc, const vmime::charset& cdest)
{
@@ -330,5 +138,11 @@ VMIME_TEST_SUITE_BEGIN
VASSERT_EQ("3.2", "إختبار", convertHelper("xn--kgbechtv", "idna", "utf-8"));
}
+ void testUTF7Support()
+ {
+ // Ensure UTF-7 is supported, because it is used for IMAP
+ VASSERT_EQ("1", "VMime +ACY UTF-7 encoding", convertHelper("VMime & UTF-7 encoding", "utf-8", "utf-7"));
+ }
+
VMIME_TEST_SUITE_END
diff --git a/tests/parser/charsetTestSuites.hpp b/tests/parser/charsetTestSuites.hpp
new file mode 100644
index 00000000..b12b3e37
--- /dev/null
+++ b/tests/parser/charsetTestSuites.hpp
@@ -0,0 +1,103 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+
+struct charsetTestSuiteStruct
+{
+ const char* fromCharset;
+ const char* toCharset;
+ const char* fromBytes;
+ const unsigned int fromLength;
+ const char* toBytes;
+ const unsigned int toLength;
+};
+
+
+static const charsetTestSuiteStruct charsetTestSuites[] =
+{
+ // Test data 1 (excerpt from http://www.gnu.org)
+ {
+ "gb2312", "utf-8",
+
+ "\xbb\xb6\xd3\xad\xc0\xb4\xb5\xbd\x20\x47\x4e\x55\x20\xb9\xa4\xb3"
+ "\xcc\xb5\xc4\xcd\xf8\xd2\xb3\xcb\xc5\xb7\xfe\xd6\xf7\xbb\xfa\x20"
+ "\x77\x77\x77\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xa1\xa3\x20\x47"
+ "\x4e\x55\x20\xb9\xa4\xb3\xcc\x20\xbf\xaa\xca\xbc\xec\xb6\xd2\xbb"
+ "\xbe\xc5\xb0\xcb\xcb\xc4\xc4\xea\xa3\xac\xd6\xbc\xd4\xda\xb7\xa2"
+ "\xd5\xb9\xd2\xbb\xb8\xf6\xc0\xe0\xcb\xc6\x20\x55\x6e\x69\x78\x20"
+ "\xa3\xac\xc7\xd2\xce\xaa\x20\xd7\xd4\xd3\xc9\xc8\xed\xbc\xfe\x20"
+ "\xb5\xc4\xcd\xea\xd5\xfb\xb2\xd9\xd7\xf7\xcf\xb5\xcd\xb3\xa3\xba"
+ "\x20\x47\x4e\x55\x20\xcf\xb5\xcd\xb3\xa1\xa3\xa3\xa8\x47\x4e\x55"
+ "\x20\xca\xc7\xd3\xc9\xa1\xb0\x47\x4e\x55\x27\x73\x20\x4e\x6f\x74"
+ "\x20\x55\x6e\x69\x78\xa1\xb1\xcb\xf9\xb5\xdd\xbb\xd8\xb6\xa8\xd2"
+ "\xe5\xb3\xf6\xb5\xc4\xca\xd7\xd7\xd6\xc4\xb8\xcb\xf5\xd0\xb4\xd3"
+ "\xef\xa3\xbb\xcb\xfc\xb5\xc4\xb7\xa2\xd2\xf4\xce\xaa\xa1\xb0\x67"
+ "\x75\x68\x2d\x4e\x45\x57\xa1\xb1\xa3\xa9\xa1\xa3\xb8\xf7\xd6\xd6"
+ "\xca\xb9\xd3\xc3\x20\x4c\x69\x6e\x75\x78\x20\xd7\xf7\xce\xaa\xc4"
+ "\xda\xba\xcb\xb5\xc4\x20\x47\x4e\x55\x20\xb2\xd9\xd7\xf7\xcf\xb5"
+ "\xcd\xb3\xd5\xfd\xb1\xbb\xb9\xe3\xb7\xba\xb5\xd8\xca\xb9\xd3\xc3"
+ "\xd6\xf8\xa3\xbb\xcb\xe4\xc8\xbb\xd5\xe2\xd0\xa9\xcf\xb5\xcd\xb3"
+ "\xcd\xa8\xb3\xa3\xb1\xbb\xb3\xc6\xd7\xf7\xce\xaa\xa1\xb0\x4c\x69"
+ "\x6e\x75\x78\xa1\xb1\xa3\xac\xb5\xab\xca\xc7\xcb\xfc\xc3\xc7\xd3"
+ "\xa6\xb8\xc3\xb8\xfc\xbe\xab\xc8\xb7\xb5\xd8\xb1\xbb\xb3\xc6\xce"
+ "\xaa\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xcf\xb5\xcd\xb3"
+ "\x20\xa1\xa3\x0a",
+ 0,
+
+ "\xe6\xac\xa2\xe8\xbf\x8e\xe6\x9d\xa5\xe5\x88\xb0\x20\x47\x4e\x55"
+ "\x20\xe5\xb7\xa5\xe7\xa8\x8b\xe7\x9a\x84\xe7\xbd\x91\xe9\xa1\xb5"
+ "\xe4\xbc\xba\xe6\x9c\x8d\xe4\xb8\xbb\xe6\x9c\xba\x20\x77\x77\x77"
+ "\x2e\x67\x6e\x75\x2e\x6f\x72\x67\x20\xe3\x80\x82\x20\x47\x4e\x55"
+ "\x20\xe5\xb7\xa5\xe7\xa8\x8b\x20\xe5\xbc\x80\xe5\xa7\x8b\xe6\x96"
+ "\xbc\xe4\xb8\x80\xe4\xb9\x9d\xe5\x85\xab\xe5\x9b\x9b\xe5\xb9\xb4"
+ "\xef\xbc\x8c\xe6\x97\xa8\xe5\x9c\xa8\xe5\x8f\x91\xe5\xb1\x95\xe4"
+ "\xb8\x80\xe4\xb8\xaa\xe7\xb1\xbb\xe4\xbc\xbc\x20\x55\x6e\x69\x78"
+ "\x20\xef\xbc\x8c\xe4\xb8\x94\xe4\xb8\xba\x20\xe8\x87\xaa\xe7\x94"
+ "\xb1\xe8\xbd\xaf\xe4\xbb\xb6\x20\xe7\x9a\x84\xe5\xae\x8c\xe6\x95"
+ "\xb4\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xef\xbc\x9a"
+ "\x20\x47\x4e\x55\x20\xe7\xb3\xbb\xe7\xbb\x9f\xe3\x80\x82\xef\xbc"
+ "\x88\x47\x4e\x55\x20\xe6\x98\xaf\xe7\x94\xb1\xe2\x80\x9c\x47\x4e"
+ "\x55\x27\x73\x20\x4e\x6f\x74\x20\x55\x6e\x69\x78\xe2\x80\x9d\xe6"
+ "\x89\x80\xe9\x80\x92\xe5\x9b\x9e\xe5\xae\x9a\xe4\xb9\x89\xe5\x87"
+ "\xba\xe7\x9a\x84\xe9\xa6\x96\xe5\xad\x97\xe6\xaf\x8d\xe7\xbc\xa9"
+ "\xe5\x86\x99\xe8\xaf\xad\xef\xbc\x9b\xe5\xae\x83\xe7\x9a\x84\xe5"
+ "\x8f\x91\xe9\x9f\xb3\xe4\xb8\xba\xe2\x80\x9c\x67\x75\x68\x2d\x4e"
+ "\x45\x57\xe2\x80\x9d\xef\xbc\x89\xe3\x80\x82\xe5\x90\x84\xe7\xa7"
+ "\x8d\xe4\xbd\xbf\xe7\x94\xa8\x20\x4c\x69\x6e\x75\x78\x20\xe4\xbd"
+ "\x9c\xe4\xb8\xba\xe5\x86\x85\xe6\xa0\xb8\xe7\x9a\x84\x20\x47\x4e"
+ "\x55\x20\xe6\x93\x8d\xe4\xbd\x9c\xe7\xb3\xbb\xe7\xbb\x9f\xe6\xad"
+ "\xa3\xe8\xa2\xab\xe5\xb9\xbf\xe6\xb3\x9b\xe5\x9c\xb0\xe4\xbd\xbf"
+ "\xe7\x94\xa8\xe8\x91\x97\xef\xbc\x9b\xe8\x99\xbd\xe7\x84\xb6\xe8"
+ "\xbf\x99\xe4\xba\x9b\xe7\xb3\xbb\xe7\xbb\x9f\xe9\x80\x9a\xe5\xb8"
+ "\xb8\xe8\xa2\xab\xe7\xa7\xb0\xe4\xbd\x9c\xe4\xb8\xba\xe2\x80\x9c"
+ "\x4c\x69\x6e\x75\x78\xe2\x80\x9d\xef\xbc\x8c\xe4\xbd\x86\xe6\x98"
+ "\xaf\xe5\xae\x83\xe4\xbb\xac\xe5\xba\x94\xe8\xaf\xa5\xe6\x9b\xb4"
+ "\xe7\xb2\xbe\xe7\xa1\xae\xe5\x9c\xb0\xe8\xa2\xab\xe7\xa7\xb0\xe4"
+ "\xb8\xba\x20\x47\x4e\x55\x2f\x4c\x69\x6e\x75\x78\x20\xe7\xb3\xbb"
+ "\xe7\xbb\x9f\x20\xe3\x80\x82\x0a",
+ 0
+ }
+
+};
+
+static const unsigned int charsetTestSuitesCount = sizeof(charsetTestSuites) / sizeof(charsetTestSuites[0]);
diff --git a/tests/parser/datetimeTest.cpp b/tests/parser/datetimeTest.cpp
index 07d77301..90bbebbb 100644
--- a/tests/parser/datetimeTest.cpp
+++ b/tests/parser/datetimeTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE datetimeTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(datetimeTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
diff --git a/tests/parser/dispositionTest.cpp b/tests/parser/dispositionTest.cpp
index 81818dae..7b767caa 100644
--- a/tests/parser/dispositionTest.cpp
+++ b/tests/parser/dispositionTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE dispositionTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(dispositionTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
diff --git a/tests/parser/emailAddressTest.cpp b/tests/parser/emailAddressTest.cpp
index 0185c220..378cc065 100644
--- a/tests/parser/emailAddressTest.cpp
+++ b/tests/parser/emailAddressTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/platform.hpp"
-#define VMIME_TEST_SUITE emailAddressTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(emailAddressTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParseASCII)
diff --git a/tests/parser/headerFieldTest.cpp b/tests/parser/headerFieldTest.cpp
index 2c8a954c..9d8f9dfa 100644
--- a/tests/parser/headerFieldTest.cpp
+++ b/tests/parser/headerFieldTest.cpp
@@ -24,14 +24,11 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE headerFieldTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(headerFieldTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testBadValueType)
+ VMIME_TEST(testValueOnNextLine)
VMIME_TEST_LIST_END
@@ -53,4 +50,20 @@ VMIME_TEST_SUITE_BEGIN
custom->setValue(vmime::text("field value text")));
}
+ void testValueOnNextLine()
+ {
+ vmime::parsingContext ctx;
+
+ const vmime::string buffer = "Field: \r\n\tfield data";
+
+ vmime::ref <vmime::headerField> hfield =
+ vmime::headerField::parseNext(ctx, buffer, 0, buffer.size());
+
+ vmime::ref <vmime::text> hvalue =
+ hfield->getValue().dynamicCast <vmime::text>();
+
+ VASSERT_EQ("Field name", "Field", hfield->getName());
+ VASSERT_EQ("Field value", "field data", hvalue->getWholeBuffer());
+ }
+
VMIME_TEST_SUITE_END
diff --git a/tests/parser/headerTest.cpp b/tests/parser/headerTest.cpp
index 47bd0ebe..91eb03df 100644
--- a/tests/parser/headerTest.cpp
+++ b/tests/parser/headerTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE headerTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(headerTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testHas1)
diff --git a/tests/parser/htmlTextPartTest.cpp b/tests/parser/htmlTextPartTest.cpp
index 08754e72..732fcd8c 100644
--- a/tests/parser/htmlTextPartTest.cpp
+++ b/tests/parser/htmlTextPartTest.cpp
@@ -25,11 +25,7 @@
#include "vmime/htmlTextPart.hpp"
-#define VMIME_TEST_SUITE htmlTextPartTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(htmlTextPartTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParseText)
diff --git a/tests/parser/mailboxGroupTest.cpp b/tests/parser/mailboxGroupTest.cpp
new file mode 100644
index 00000000..49d22658
--- /dev/null
+++ b/tests/parser/mailboxGroupTest.cpp
@@ -0,0 +1,97 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#include "tests/testUtils.hpp"
+
+
+VMIME_TEST_SUITE_BEGIN(mailboxGroupTest)
+
+ VMIME_TEST_LIST_BEGIN
+ VMIME_TEST(testParseExtraWhitespaces)
+ VMIME_TEST(testParseNoEndDelimiter)
+ VMIME_TEST(testParseExtraChars)
+ VMIME_TEST(testEmptyGroup)
+ VMIME_TEST_LIST_END
+
+
+ void testParseExtraWhitespaces()
+ {
+ vmime::mailboxGroup mgrp;
+ mgrp.parse(" \t group : aaa <[email protected]>, bbb <[email protected]>");
+
+ VASSERT_EQ("name", "group", mgrp.getName().getWholeBuffer());
+ VASSERT_EQ("count", 2, mgrp.getMailboxCount());
+
+ VASSERT_EQ("mbox1.email", "[email protected]", mgrp.getMailboxAt(0)->getEmail());
+ VASSERT_EQ("mbox1.name", "aaa", mgrp.getMailboxAt(0)->getName());
+
+ VASSERT_EQ("mbox2.email", "[email protected]", mgrp.getMailboxAt(1)->getEmail());
+ VASSERT_EQ("mbox2.name", "bbb", mgrp.getMailboxAt(1)->getName());
+ }
+
+ void testParseNoEndDelimiter()
+ {
+ vmime::addressList addrs;
+ addrs.parse("group: aaa <[email protected]>, bbb <[email protected]>");
+
+ VASSERT_EQ("count", 1, addrs.getAddressCount());
+ VASSERT_TRUE("is group", addrs.getAddressAt(0)->isGroup());
+
+ vmime::ref <vmime::mailboxGroup> mgrp =
+ addrs.getAddressAt(0).dynamicCast <vmime::mailboxGroup>();
+
+ VASSERT_EQ("name", "group", mgrp->getName().getWholeBuffer());
+ VASSERT_EQ("count", 2, mgrp->getMailboxCount());
+
+ VASSERT_EQ("mbox1.email", "[email protected]", mgrp->getMailboxAt(0)->getEmail());
+ VASSERT_EQ("mbox1.name", "aaa", mgrp->getMailboxAt(0)->getName());
+
+ VASSERT_EQ("mbox2.email", "[email protected]", mgrp->getMailboxAt(1)->getEmail());
+ VASSERT_EQ("mbox2.name", "bbb", mgrp->getMailboxAt(1)->getName());
+ }
+
+ void testParseExtraChars()
+ {
+ vmime::mailboxGroup mgrp;
+ mgrp.parse("group: aaa <[email protected]>, bbb <[email protected]>; extra chars here...");
+
+ VASSERT_EQ("name", "group", mgrp.getName().getWholeBuffer());
+ VASSERT_EQ("count", 2, mgrp.getMailboxCount());
+
+ VASSERT_EQ("mbox1.email", "[email protected]", mgrp.getMailboxAt(0)->getEmail());
+ VASSERT_EQ("mbox1.name", "aaa", mgrp.getMailboxAt(0)->getName());
+
+ VASSERT_EQ("mbox2.email", "[email protected]", mgrp.getMailboxAt(1)->getEmail());
+ VASSERT_EQ("mbox2.name", "bbb", mgrp.getMailboxAt(1)->getName());
+ }
+
+ void testEmptyGroup()
+ {
+ vmime::mailboxGroup mgrp;
+ mgrp.parse("Undisclosed recipients:;");
+
+ VASSERT_EQ("name", "Undisclosed recipients", mgrp.getName().getWholeBuffer());
+ VASSERT_EQ("count", 0, mgrp.getMailboxCount());
+ }
+
+VMIME_TEST_SUITE_END
diff --git a/tests/parser/mailboxTest.cpp b/tests/parser/mailboxTest.cpp
index 9e48a235..e6e4a608 100644
--- a/tests/parser/mailboxTest.cpp
+++ b/tests/parser/mailboxTest.cpp
@@ -24,15 +24,12 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE mailboxTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(mailboxTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST(testEmptyEmailAddress)
+ VMIME_TEST(testSeparatorInComment)
VMIME_TEST_LIST_END
@@ -128,5 +125,22 @@ VMIME_TEST_SUITE_BEGIN
VASSERT_EQ("email", "", mbox->getEmail());
}
+ void testSeparatorInComment()
+ {
+ vmime::addressList addrList;
+ addrList.parse("aaa(comment,comment)@vmime.org, [email protected]");
+
+ VASSERT_EQ("count", 2, addrList.getAddressCount());
+
+ vmime::ref <vmime::mailbox> mbox1 = addrList.getAddressAt(0).dynamicCast <vmime::mailbox>();
+ vmime::ref <vmime::mailbox> mbox2 = addrList.getAddressAt(1).dynamicCast <vmime::mailbox>();
+
+ VASSERT_EQ("name1", vmime::text(), mbox1->getName());
+ VASSERT_EQ("email1", "[email protected]", mbox1->getEmail());
+
+ VASSERT_EQ("name2", vmime::text(), mbox2->getName());
+ VASSERT_EQ("email2", "[email protected]", mbox2->getEmail());
+ }
+
VMIME_TEST_SUITE_END
diff --git a/tests/parser/mediaTypeTest.cpp b/tests/parser/mediaTypeTest.cpp
index 462f6ae7..4002b714 100644
--- a/tests/parser/mediaTypeTest.cpp
+++ b/tests/parser/mediaTypeTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE mediaTypeTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(mediaTypeTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstructors)
diff --git a/tests/parser/messageIdSequenceTest.cpp b/tests/parser/messageIdSequenceTest.cpp
index e7dd7e01..ed6d0be3 100644
--- a/tests/parser/messageIdSequenceTest.cpp
+++ b/tests/parser/messageIdSequenceTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE messageIdSequenceTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(messageIdSequenceTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
diff --git a/tests/parser/messageIdTest.cpp b/tests/parser/messageIdTest.cpp
index be8be3f1..9863ae51 100644
--- a/tests/parser/messageIdTest.cpp
+++ b/tests/parser/messageIdTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE messageIdTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(messageIdTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
diff --git a/tests/parser/parameterTest.cpp b/tests/parser/parameterTest.cpp
index 91c5f076..3ebd6e35 100644
--- a/tests/parser/parameterTest.cpp
+++ b/tests/parser/parameterTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE parameterTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(parameterTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
@@ -39,6 +35,7 @@ VMIME_TEST_SUITE_BEGIN
VMIME_TEST(testParseNonSignificantWS)
VMIME_TEST(testEncodeTSpecials)
VMIME_TEST(testEncodeTSpecialsInRFC2231)
+ VMIME_TEST(testWhitespaceBreaksTheValue)
VMIME_TEST_LIST_END
@@ -352,5 +349,16 @@ VMIME_TEST_SUITE_BEGIN
vmime::create <vmime::parameter>("filename", "my_file_name_\xc3\xb6\xc3\xa4\xc3\xbc_(1).txt")->generate());
}
+ void testWhitespaceBreaksTheValue()
+ {
+ parameterizedHeaderField p;
+ p.parse("xxx yyy; param1=value1 \r\n");
+
+ VASSERT_EQ("count", 1, p.getParameterCount());
+ VASSERT_EQ("value", "xxx", FIELD_VALUE(p));
+ VASSERT_EQ("param1.name", "param1", PARAM_NAME(p, 0));
+ VASSERT_EQ("param1.value", "value1", PARAM_VALUE(p, 0));
+ }
+
VMIME_TEST_SUITE_END
diff --git a/tests/parser/pathTest.cpp b/tests/parser/pathTest.cpp
index caa6e0a0..f73dd0d4 100644
--- a/tests/parser/pathTest.cpp
+++ b/tests/parser/pathTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE pathTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(pathTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp
index 0261a72f..f4f30b1b 100644
--- a/tests/parser/textTest.cpp
+++ b/tests/parser/textTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE textTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(textTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstructors)
diff --git a/tests/parser/wordEncoderTest.cpp b/tests/parser/wordEncoderTest.cpp
index 269a01bd..9bc4dcfd 100644
--- a/tests/parser/wordEncoderTest.cpp
+++ b/tests/parser/wordEncoderTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/wordEncoder.hpp"
-#define VMIME_TEST_SUITE wordEncoderTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(wordEncoderTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testGetNextChunk)
diff --git a/tests/security/digest/md5Test.cpp b/tests/security/digest/md5Test.cpp
index 28220693..ec4e62b2 100644
--- a/tests/security/digest/md5Test.cpp
+++ b/tests/security/digest/md5Test.cpp
@@ -26,17 +26,13 @@
#include "vmime/security/digest/messageDigestFactory.hpp"
-#define VMIME_TEST_SUITE md5Test
-#define VMIME_TEST_SUITE_MODULE "Security/Digest"
-
-
#define INIT_DIGEST(var, algo) \
vmime::ref <vmime::security::digest::messageDigest> var = \
vmime::security::digest::messageDigestFactory::getInstance()->create(algo)
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(md5Test)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testRFC1321_1)
diff --git a/tests/security/digest/sha1Test.cpp b/tests/security/digest/sha1Test.cpp
index 5ad98e62..2accf8c7 100644
--- a/tests/security/digest/sha1Test.cpp
+++ b/tests/security/digest/sha1Test.cpp
@@ -26,17 +26,13 @@
#include "vmime/security/digest/messageDigestFactory.hpp"
-#define VMIME_TEST_SUITE sha1Test
-#define VMIME_TEST_SUITE_MODULE "Security/Digest"
-
-
#define INIT_DIGEST(var, algo) \
vmime::ref <vmime::security::digest::messageDigest> var = \
vmime::security::digest::messageDigestFactory::getInstance()->create(algo)
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(sha1Test)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testFIPS180_1)
diff --git a/tests/testRunner.cpp b/tests/testRunner.cpp
index b6c66850..fb40d3a2 100644
--- a/tests/testRunner.cpp
+++ b/tests/testRunner.cpp
@@ -192,6 +192,55 @@ void registerTestModule(const char* name_)
}
+const std::string getNormalizedPath(const std::string& path)
+{
+ std::string res = path;
+
+ for (std::string::size_type i = 0, n = res.length() ; i < n ; ++i)
+ {
+ if (res[i] == '\\')
+ res[i] = '/';
+ }
+
+ return res;
+}
+
+
+const std::string getFileNameFromPath(const std::string& path)
+{
+ const std::string::size_type pos = path.find_last_of('/');
+
+ if (pos == std::string::npos)
+ return "";
+
+ return path.substr(pos + 1);
+}
+
+
+const char* getTestModuleNameFromSourceFile(const char *path_)
+{
+ static std::string moduleName;
+
+ static const std::string testRunnerPath(getNormalizedPath(__FILE__));
+ static const std::string testRunnerFileName(getFileNameFromPath(testRunnerPath));
+
+ const std::string path = getNormalizedPath(path_);
+
+ // "/path/to/testRunner.cpp" --> "/path/to/"
+ const std::string basePath
+ (testRunnerPath.begin(), testRunnerPath.end() - testRunnerFileName.length());
+
+ // "/path/to/module/testFile.cpp" --> "module/testFile.cpp"
+ const std::string testFileName(getFileNameFromPath(path));
+ const std::string testPath(path.begin() + basePath.length(), path.end());
+
+ // "module/testFile.cpp" --> "module"
+ moduleName = testPath.substr(0, testPath.length() - testFileName.length() - 1);
+
+ return moduleName.c_str();
+}
+
+
int main(int argc, char* argv[])
{
// VMime initialization
diff --git a/tests/testUtils.cpp b/tests/testUtils.cpp
index 56117e07..d008ed94 100644
--- a/tests/testUtils.cpp
+++ b/tests/testUtils.cpp
@@ -270,3 +270,39 @@ std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
}
+const vmime::string toHex(const vmime::string str)
+{
+ static const char hexChars[] = "0123456789abcdef";
+
+ vmime::string res = "\n";
+
+ for (unsigned int i = 0 ; i < str.length() ; i += 16)
+ {
+ unsigned int r = std::min
+ (static_cast <size_t>(16), str.length() - i);
+
+ vmime::string hex;
+ vmime::string chr;
+
+ for (unsigned int j = 0 ; j < r ; ++j)
+ {
+ const unsigned char c = str[i + j];
+
+ hex += hexChars[c / 16];
+ hex += hexChars[c % 16];
+ hex += " ";
+
+ if (c >= 32 && c <= 127)
+ chr += c;
+ else
+ chr += '.';
+ }
+
+ for (unsigned int j = r ; j < 16 ; ++j)
+ hex += " ";
+
+ res += hex + " " + chr + "\n";
+ }
+
+ return res;
+}
diff --git a/tests/testUtils.hpp b/tests/testUtils.hpp
index 39d9e555..4fa6b457 100644
--- a/tests/testUtils.hpp
+++ b/tests/testUtils.hpp
@@ -33,8 +33,10 @@
// CppUnit
+#pragma GCC diagnostic ignored "-Wold-style-cast"
#include <cppunit/TestAssert.h>
#include <cppunit/extensions/HelperMacros.h>
+#pragma GCC diagnostic warning "-Wold-style-cast"
#define VASSERT(msg, cond) \
CPPUNIT_ASSERT_MESSAGE(std::string(msg), cond)
@@ -57,18 +59,24 @@
#define VASSERT_NO_THROW(msg, expression) \
CPPUNIT_ASSERT_NO_THROW(expression)
-#define VMIME_TEST_SUITE_BEGIN \
- class VMIME_TEST_SUITE : public CppUnit::TestFixture { public:
+#define VMIME_TEST_SUITE_BEGIN(testSuiteName) \
+ class testSuiteName; \
+ typedef testSuiteName VMIME_TEST_SUITE; \
+ class testSuiteName : public CppUnit::TestFixture { public:
#define VMIME_TEST_SUITE_END \
}; \
\
- static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry1); \
- static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry2)(VMIME_TEST_SUITE_MODULE); \
+ /*static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry1);*/ \
+ /*static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry2)(VMIME_TEST_SUITE_MODULE);*/ \
extern void registerTestModule(const char* name); \
+ extern const char* getTestModuleNameFromSourceFile(const char *path); \
template <typename T> \
struct AutoRegisterModule { \
AutoRegisterModule() { \
- registerTestModule(VMIME_TEST_SUITE_MODULE); \
+ static const char* moduleName = getTestModuleNameFromSourceFile(__FILE__); \
+ static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry1); \
+ static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry2)(moduleName); \
+ registerTestModule(moduleName); \
} \
}; \
static AutoRegisterModule <VMIME_TEST_SUITE> autoRegisterModule;
@@ -340,3 +348,6 @@ public:
// Exception helper
std::ostream& operator<<(std::ostream& os, const vmime::exception& e);
+
+// Conversion to hexadecimal for easier debugging
+const vmime::string toHex(const vmime::string str);
diff --git a/tests/utility/datetimeUtilsTest.cpp b/tests/utility/datetimeUtilsTest.cpp
index 608a0521..1e21c5f9 100644
--- a/tests/utility/datetimeUtilsTest.cpp
+++ b/tests/utility/datetimeUtilsTest.cpp
@@ -27,11 +27,7 @@
#include "vmime/utility/datetimeUtils.hpp"
-#define VMIME_TEST_SUITE datetimeUtilsTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(datetimeUtilsTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testIsLeapYear)
diff --git a/tests/utility/encoder/b64EncoderTest.cpp b/tests/utility/encoder/b64EncoderTest.cpp
new file mode 100644
index 00000000..589afaba
--- /dev/null
+++ b/tests/utility/encoder/b64EncoderTest.cpp
@@ -0,0 +1,145 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+#include "tests/testUtils.hpp"
+
+#include "encoderTestUtils.hpp"
+
+
+VMIME_TEST_SUITE_BEGIN(b64EncoderTest)
+
+ VMIME_TEST_LIST_BEGIN
+ VMIME_TEST(testBase64)
+ VMIME_TEST_LIST_END
+
+
+ void testBase64()
+ {
+ static const vmime::string testSuites[] =
+ {
+ // Test 1
+ "",
+
+ "",
+
+ // Test 2
+ "A",
+
+ "QQ==",
+
+ // Test 3
+ "AB",
+
+ "QUI=",
+
+ // Test 4
+ "ABC",
+
+ "QUJD",
+
+ // Test 5
+ "foo",
+
+ "Zm9v",
+
+ // Test 6
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+
+ "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx"
+ "MjM0NTY3ODk=",
+
+ // Test 7
+ vmime::string(
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+ "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+ "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+ "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+ "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+ "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+ "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+ "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+ "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+ "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+ "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+ "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+ "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+ "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
+ 256),
+
+ "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1"
+ "Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr"
+ "bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Ch"
+ "oqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX"
+ "2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="
+ };
+
+
+ for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i)
+ {
+ const vmime::string decoded = testSuites[i * 2];
+ const vmime::string encoded = testSuites[i * 2 + 1];
+
+ std::ostringstream oss;
+ oss << "[Base64] Test " << (i + 1) << ": ";
+
+ // Encoding
+ VASSERT_EQ(oss.str() + "encoding", encoded, encode("base64", decoded));
+
+ // Decoding
+ VASSERT_EQ(oss.str() + "decoding", decoded, decode("base64", encoded));
+
+ // Multiple and successive encoding/decoding
+ VASSERT_EQ(oss.str() + "multiple1", decoded,
+ decode("base64",
+ encode("base64", decoded)));
+
+ VASSERT_EQ(oss.str() + "multiple2", decoded,
+ decode("base64",
+ decode("base64",
+ encode("base64",
+ encode("base64", decoded)))));
+
+ VASSERT_EQ(oss.str() + "multiple3", decoded,
+ decode("base64",
+ decode("base64",
+ decode("base64",
+ encode("base64",
+ encode("base64",
+ encode("base64", decoded)))))));
+
+ VASSERT_EQ(oss.str() + "multiple4", decoded,
+ decode("base64",
+ decode("base64",
+ decode("base64",
+ decode("base64",
+ encode("base64",
+ encode("base64",
+ encode("base64",
+ encode("base64", decoded)))))))));
+ }
+ }
+
+VMIME_TEST_SUITE_END
+
diff --git a/tests/utility/encoder/encoderTestUtils.hpp b/tests/utility/encoder/encoderTestUtils.hpp
new file mode 100644
index 00000000..dd2484ed
--- /dev/null
+++ b/tests/utility/encoder/encoderTestUtils.hpp
@@ -0,0 +1,65 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 3 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// Linking this library statically or dynamically with other modules is making
+// a combined work based on this library. Thus, the terms and conditions of
+// the GNU General Public License cover the whole combination.
+//
+
+
+// Encoding helper function
+static const vmime::string encode(const vmime::string& name, const vmime::string& in,
+ int maxLineLength = 0, const vmime::propertySet props = vmime::propertySet())
+{
+ vmime::ref <vmime::utility::encoder::encoder> enc =
+ vmime::utility::encoder::encoderFactory::getInstance()->create(name);
+
+ enc->getProperties() = props;
+
+ if (maxLineLength != 0)
+ enc->getProperties()["maxlinelength"] = maxLineLength;
+
+ vmime::utility::inputStreamStringAdapter vin(in);
+
+ std::ostringstream out;
+ vmime::utility::outputStreamAdapter vout(out);
+
+ enc->encode(vin, vout);
+
+ return (out.str());
+}
+
+
+// Decoding helper function
+static const vmime::string decode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0)
+{
+ vmime::ref <vmime::utility::encoder::encoder> enc =
+ vmime::utility::encoder::encoderFactory::getInstance()->create(name);
+
+ if (maxLineLength != 0)
+ enc->getProperties()["maxlinelength"] = maxLineLength;
+
+ vmime::utility::inputStreamStringAdapter vin(in);
+
+ std::ostringstream out;
+ vmime::utility::outputStreamAdapter vout(out);
+
+ enc->decode(vin, vout);
+
+ return (out.str());
+}
diff --git a/tests/utility/encoderTest.cpp b/tests/utility/encoder/qpEncoderTest.cpp
index 24aba8ea..790c5fb3 100644
--- a/tests/utility/encoderTest.cpp
+++ b/tests/utility/encoder/qpEncoderTest.cpp
@@ -23,15 +23,12 @@
#include "tests/testUtils.hpp"
+#include "encoderTestUtils.hpp"
-#define VMIME_TEST_SUITE encoderTest
-#define VMIME_TEST_SUITE_MODULE "Parser"
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(qpEncoderTest)
VMIME_TEST_LIST_BEGIN
- VMIME_TEST(testBase64)
VMIME_TEST(testQuotedPrintable)
VMIME_TEST(testQuotedPrintable_SoftLineBreaks)
VMIME_TEST(testQuotedPrintable_CRLF)
@@ -39,156 +36,6 @@ VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_END
- // Encoding helper function
- static const vmime::string encode(const vmime::string& name, const vmime::string& in,
- int maxLineLength = 0, const vmime::propertySet props = vmime::propertySet())
- {
- vmime::ref <vmime::utility::encoder::encoder> enc =
- vmime::utility::encoder::encoderFactory::getInstance()->create(name);
-
- enc->getProperties() = props;
-
- if (maxLineLength != 0)
- enc->getProperties()["maxlinelength"] = maxLineLength;
-
- vmime::utility::inputStreamStringAdapter vin(in);
-
- std::ostringstream out;
- vmime::utility::outputStreamAdapter vout(out);
-
- enc->encode(vin, vout);
-
- return (out.str());
- }
-
- // Decoding helper function
- static const vmime::string decode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0)
- {
- vmime::ref <vmime::utility::encoder::encoder> enc =
- vmime::utility::encoder::encoderFactory::getInstance()->create(name);
-
- if (maxLineLength != 0)
- enc->getProperties()["maxlinelength"] = maxLineLength;
-
- vmime::utility::inputStreamStringAdapter vin(in);
-
- std::ostringstream out;
- vmime::utility::outputStreamAdapter vout(out);
-
- enc->decode(vin, vout);
-
- return (out.str());
- }
-
-
- void testBase64()
- {
- static const vmime::string testSuites[] =
- {
- // Test 1
- "",
-
- "",
-
- // Test 2
- "A",
-
- "QQ==",
-
- // Test 3
- "AB",
-
- "QUI=",
-
- // Test 4
- "ABC",
-
- "QUJD",
-
- // Test 5
- "foo",
-
- "Zm9v",
-
- // Test 6
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-
- "QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx"
- "MjM0NTY3ODk=",
-
- // Test 7
- vmime::string(
- "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
- "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
- "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
- "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
- "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
- "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
- "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
- "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
- "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
- "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
- "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
- "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
- "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
- "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
- "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
- "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
- 256),
-
- "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1"
- "Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr"
- "bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Ch"
- "oqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX"
- "2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="
- };
-
-
- for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i)
- {
- const vmime::string decoded = testSuites[i * 2];
- const vmime::string encoded = testSuites[i * 2 + 1];
-
- std::ostringstream oss;
- oss << "[Base64] Test " << (i + 1) << ": ";
-
- // Encoding
- VASSERT_EQ(oss.str() + "encoding", encoded, encode("base64", decoded));
-
- // Decoding
- VASSERT_EQ(oss.str() + "decoding", decoded, decode("base64", encoded));
-
- // Multiple and successive encoding/decoding
- VASSERT_EQ(oss.str() + "multiple1", decoded,
- decode("base64",
- encode("base64", decoded)));
-
- VASSERT_EQ(oss.str() + "multiple2", decoded,
- decode("base64",
- decode("base64",
- encode("base64",
- encode("base64", decoded)))));
-
- VASSERT_EQ(oss.str() + "multiple3", decoded,
- decode("base64",
- decode("base64",
- decode("base64",
- encode("base64",
- encode("base64",
- encode("base64", decoded)))))));
-
- VASSERT_EQ(oss.str() + "multiple4", decoded,
- decode("base64",
- decode("base64",
- decode("base64",
- decode("base64",
- encode("base64",
- encode("base64",
- encode("base64",
- encode("base64", decoded)))))))));
- }
- }
-
void testQuotedPrintable()
{
static const vmime::string testSuites[] =
@@ -353,4 +200,3 @@ VMIME_TEST_SUITE_BEGIN
// TODO: UUEncode
VMIME_TEST_SUITE_END
-
diff --git a/tests/utility/filteredStreamTest.cpp b/tests/utility/filteredStreamTest.cpp
index 8dc4d182..4a869c6e 100644
--- a/tests/utility/filteredStreamTest.cpp
+++ b/tests/utility/filteredStreamTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/utility/filteredStream.hpp"
-#define VMIME_TEST_SUITE filteredStreamTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(filteredStreamTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testDotFilteredInputStream)
diff --git a/tests/utility/outputStreamByteArrayAdapterTest.cpp b/tests/utility/outputStreamByteArrayAdapterTest.cpp
index e1f6810f..93e49fa1 100644
--- a/tests/utility/outputStreamByteArrayAdapterTest.cpp
+++ b/tests/utility/outputStreamByteArrayAdapterTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/utility/outputStreamByteArrayAdapter.hpp"
-#define VMIME_TEST_SUITE outputStreamByteArrayAdapterTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(outputStreamByteArrayAdapterTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testWrite)
diff --git a/tests/utility/outputStreamSocketAdapterTest.cpp b/tests/utility/outputStreamSocketAdapterTest.cpp
index ab8ec841..920c7f47 100644
--- a/tests/utility/outputStreamSocketAdapterTest.cpp
+++ b/tests/utility/outputStreamSocketAdapterTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/utility/outputStreamSocketAdapter.hpp"
-#define VMIME_TEST_SUITE outputStreamSocketAdapterTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(outputStreamSocketAdapterTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testWrite)
diff --git a/tests/utility/outputStreamStringAdapterTest.cpp b/tests/utility/outputStreamStringAdapterTest.cpp
index 9c2e516e..71ab9b38 100644
--- a/tests/utility/outputStreamStringAdapterTest.cpp
+++ b/tests/utility/outputStreamStringAdapterTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
-#define VMIME_TEST_SUITE outputStreamStringAdapterTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(outputStreamStringAdapterTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testWrite)
diff --git a/tests/utility/pathTest.cpp b/tests/utility/pathTest.cpp
index 6b923076..93215586 100644
--- a/tests/utility/pathTest.cpp
+++ b/tests/utility/pathTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/utility/path.hpp"
-#define VMIME_TEST_SUITE pathTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(pathTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstruct1)
diff --git a/tests/utility/seekableInputStreamRegionAdapterTest.cpp b/tests/utility/seekableInputStreamRegionAdapterTest.cpp
index 5cffbb68..3ed024e8 100644
--- a/tests/utility/seekableInputStreamRegionAdapterTest.cpp
+++ b/tests/utility/seekableInputStreamRegionAdapterTest.cpp
@@ -27,14 +27,10 @@
#include "vmime/utility/seekableInputStreamRegionAdapter.hpp"
-#define VMIME_TEST_SUITE seekableInputStreamRegionAdapterTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
using namespace vmime::utility;
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(seekableInputStreamRegionAdapterTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testInitialPosition)
diff --git a/tests/utility/smartPtrTest.cpp b/tests/utility/smartPtrTest.cpp
index ceaf57e1..584adf3b 100644
--- a/tests/utility/smartPtrTest.cpp
+++ b/tests/utility/smartPtrTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/utility/smartPtr.hpp"
-#define VMIME_TEST_SUITE smartPtrTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(smartPtrTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testNull)
diff --git a/tests/utility/stringProxyTest.cpp b/tests/utility/stringProxyTest.cpp
index 0dd5ef73..0d888f6a 100644
--- a/tests/utility/stringProxyTest.cpp
+++ b/tests/utility/stringProxyTest.cpp
@@ -24,11 +24,7 @@
#include "tests/testUtils.hpp"
-#define VMIME_TEST_SUITE stringProxyTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(stringProxyTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstruct)
diff --git a/tests/utility/stringUtilsTest.cpp b/tests/utility/stringUtilsTest.cpp
index d0ba187c..efd623db 100644
--- a/tests/utility/stringUtilsTest.cpp
+++ b/tests/utility/stringUtilsTest.cpp
@@ -26,11 +26,7 @@
#include "vmime/utility/stringUtils.hpp"
-#define VMIME_TEST_SUITE stringUtilsTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(stringUtilsTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testIsStringEqualNoCase1)
diff --git a/tests/utility/urlTest.cpp b/tests/utility/urlTest.cpp
index 524057da..6703ecd3 100644
--- a/tests/utility/urlTest.cpp
+++ b/tests/utility/urlTest.cpp
@@ -27,11 +27,7 @@
#include "vmime/utility/urlUtils.hpp"
-#define VMIME_TEST_SUITE urlTest
-#define VMIME_TEST_SUITE_MODULE "Utility"
-
-
-VMIME_TEST_SUITE_BEGIN
+VMIME_TEST_SUITE_BEGIN(urlTest)
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse1)
diff --git a/vmime/address.hpp b/vmime/address.hpp
index 0faf876f..c6cd6dc6 100644
--- a/vmime/address.hpp
+++ b/vmime/address.hpp
@@ -70,12 +70,14 @@ public:
* @param position position in the input buffer
* @param end end position in the input buffer
* @param newPosition will receive the new position in the input buffer
+ * @param isLastAddressOfGroup will be set to true if this is the last address
+ * of a group (end delimiter was found), or false otherwise (may be set to NULL)
* @return a new address object, or null if no more address is available in the input buffer
*/
static ref <address> parseNext
(const parsingContext& ctx, const string& buffer,
const string::size_type position, const string::size_type end,
- string::size_type* newPosition);
+ string::size_type* newPosition, bool *isLastAddressOfGroup);
};
diff --git a/vmime/context.hpp b/vmime/context.hpp
index 76cc0ee4..c369fb92 100644
--- a/vmime/context.hpp
+++ b/vmime/context.hpp
@@ -109,7 +109,7 @@ protected:
context(const context& ctx);
virtual context& operator=(const context& ctx);
- virtual void copyFrom(const context& ctx);
+ void copyFrom(const context& ctx);
bool m_internationalizedEmail;
charsetConverterOptions m_charsetConvOptions;
diff --git a/vmime/headerField.hpp b/vmime/headerField.hpp
index 72d639c9..a6e80e32 100644
--- a/vmime/headerField.hpp
+++ b/vmime/headerField.hpp
@@ -124,6 +124,23 @@ public:
void setValue(const string& value);
+ /** Parse a header field from a buffer.
+ *
+ * @param ctx parsing context
+ * @param buffer input buffer
+ * @param position current position in the input buffer
+ * @param end end position in the input buffer
+ * @param newPosition will receive the new position in the input buffer
+ * @return parsed header field, or NULL if no more header field can be parsed
+ * in the input buffer
+ */
+ static ref <headerField> parseNext
+ (const parsingContext& ctx,
+ const string& buffer,
+ const string::size_type position,
+ const string::size_type end,
+ string::size_type* newPosition = NULL);
+
protected:
void parseImpl
@@ -140,14 +157,6 @@ protected:
string::size_type* newLinePos = NULL) const;
- static ref <headerField> parseNext
- (const parsingContext& ctx,
- const string& buffer,
- const string::size_type position,
- const string::size_type end,
- string::size_type* newPosition = NULL);
-
-
string m_name;
ref <headerFieldValue> m_value;
};
diff --git a/vmime/net/smtp/SMTPCommandSet.hpp b/vmime/net/smtp/SMTPCommandSet.hpp
index 5b52ba0a..f97c4b2a 100644
--- a/vmime/net/smtp/SMTPCommandSet.hpp
+++ b/vmime/net/smtp/SMTPCommandSet.hpp
@@ -70,7 +70,7 @@ public:
* @return true if all commands have been sent,
* or false otherwise
*/
- const bool isFinished() const;
+ bool isFinished() const;
/** Returns the last command which has been sent.
*