diff --git a/examples/example1.cpp b/examples/example1.cpp index 9948d606..b80fe636 100644 --- a/examples/example1.cpp +++ b/examples/example1.cpp @@ -32,6 +32,8 @@ // #include +#include +#include #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" @@ -41,8 +43,16 @@ int main() { std::cout << std::endl; - // VMime initialization - vmime::platform::setHandler(); + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } try { diff --git a/examples/example2.cpp b/examples/example2.cpp index 56f01b03..67b8d844 100644 --- a/examples/example2.cpp +++ b/examples/example2.cpp @@ -32,6 +32,8 @@ // #include +#include +#include #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" @@ -41,8 +43,16 @@ int main() { std::cout << std::endl; - // VMime initialization - vmime::platform::setHandler(); + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } try { @@ -71,7 +81,7 @@ int main() // Adding an attachment vmime::shared_ptr a = vmime::make_shared ( - "./example2.cpp", // full path to file + __FILE__, // full path to file vmime::mediaType("application/octet-stream"), // content type vmime::text("My first attachment") // description ); diff --git a/examples/example3.cpp b/examples/example3.cpp index 56b3c7e7..a472e05c 100644 --- a/examples/example3.cpp +++ b/examples/example3.cpp @@ -32,6 +32,8 @@ // #include +#include +#include #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" @@ -41,8 +43,16 @@ int main() { std::cout << std::endl; - // VMime initialization - vmime::platform::setHandler(); + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } try { diff --git a/examples/example4.cpp b/examples/example4.cpp index 3dbfe548..1d077575 100644 --- a/examples/example4.cpp +++ b/examples/example4.cpp @@ -32,6 +32,8 @@ // #include +#include +#include #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" @@ -41,8 +43,16 @@ int main() { std::cout << std::endl; - // VMime initialization - vmime::platform::setHandler(); + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } try { diff --git a/examples/example5.cpp b/examples/example5.cpp index 159b503c..849ffa75 100644 --- a/examples/example5.cpp +++ b/examples/example5.cpp @@ -32,6 +32,8 @@ // #include +#include +#include #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" @@ -41,8 +43,16 @@ int main() { std::cout << std::endl; - // VMime initialization - vmime::platform::setHandler(); + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } try { diff --git a/examples/example6.cpp b/examples/example6.cpp index 30767c3e..54f1364b 100644 --- a/examples/example6.cpp +++ b/examples/example6.cpp @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" @@ -916,8 +918,16 @@ static bool menu() int main() { - // VMime initialization - vmime::platform::setHandler(); + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } for (bool quit = false ; !quit ; ) { diff --git a/examples/example7.cpp b/examples/example7.cpp index 241b4d33..e69f65f3 100644 --- a/examples/example7.cpp +++ b/examples/example7.cpp @@ -32,6 +32,8 @@ // #include +#include +#include #include "vmime/vmime.hpp" #include "vmime/platforms/posix/posixHandler.hpp" @@ -39,9 +41,6 @@ int main() { - // VMime initialization - vmime::platform::setHandler(); - // Enumerate encoders vmime::shared_ptr ef = vmime::utility::encoder::encoderFactory::getInstance(); diff --git a/src/vmime/contentDispositionField.cpp b/src/vmime/contentDispositionField.cpp index 33234be8..2331b606 100644 --- a/src/vmime/contentDispositionField.cpp +++ b/src/vmime/contentDispositionField.cpp @@ -42,7 +42,7 @@ contentDispositionField::contentDispositionField(contentDispositionField&) bool contentDispositionField::hasCreationDate() const { - return bool(findParameter("creation-date")); + return hasParameter("creation-date"); } @@ -65,7 +65,7 @@ void contentDispositionField::setCreationDate(const datetime& creationDate) bool contentDispositionField::hasModificationDate() const { - return bool(findParameter("modification-date")); + return hasParameter("modification-date"); } @@ -88,7 +88,7 @@ void contentDispositionField::setModificationDate(const datetime& modificationDa bool contentDispositionField::hasReadDate() const { - return bool(findParameter("read-date")); + return hasParameter("read-date"); } @@ -111,7 +111,7 @@ void contentDispositionField::setReadDate(const datetime& readDate) bool contentDispositionField::hasFilename() const { - return bool(findParameter("filename")); + return hasParameter("filename"); } @@ -134,7 +134,7 @@ void contentDispositionField::setFilename(const word& filename) bool contentDispositionField::hasSize() const { - return bool(findParameter("size")); + return hasParameter("size"); } diff --git a/src/vmime/contentTypeField.cpp b/src/vmime/contentTypeField.cpp index c36535f3..e15608cc 100644 --- a/src/vmime/contentTypeField.cpp +++ b/src/vmime/contentTypeField.cpp @@ -42,7 +42,7 @@ contentTypeField::contentTypeField(contentTypeField&) bool contentTypeField::hasBoundary() const { - return bool(findParameter("boundary")); + return hasParameter("boundary"); } @@ -65,7 +65,7 @@ void contentTypeField::setBoundary(const string& boundary) bool contentTypeField::hasCharset() const { - return bool(findParameter("charset")); + return hasParameter("charset"); } @@ -88,7 +88,7 @@ void contentTypeField::setCharset(const charset& ch) bool contentTypeField::hasReportType() const { - return bool(findParameter("report-type")); + return hasParameter("report-type"); } diff --git a/src/vmime/platforms/posix/posixHandler.cpp b/src/vmime/platforms/posix/posixHandler.cpp index 7ab0341a..e0bfd27f 100644 --- a/src/vmime/platforms/posix/posixHandler.cpp +++ b/src/vmime/platforms/posix/posixHandler.cpp @@ -168,11 +168,7 @@ const vmime::charset posixHandler::getLocalCharset() const { const PLockHelper lock; - const char* prevLocale = ::setlocale(LC_ALL, ""); - vmime::charset ch(::nl_langinfo(CODESET)); - ::setlocale(LC_ALL, prevLocale); - - return (ch); + return vmime::charset(::nl_langinfo(CODESET)); } diff --git a/src/vmime/platforms/windows/windowsSocket.cpp b/src/vmime/platforms/windows/windowsSocket.cpp index 40e69363..cb96481a 100644 --- a/src/vmime/platforms/windows/windowsSocket.cpp +++ b/src/vmime/platforms/windows/windowsSocket.cpp @@ -31,6 +31,7 @@ #include "vmime/platforms/windows/windowsSocket.hpp" +#include "vmime/utility/stringUtils.hpp" #include "vmime/exception.hpp" #include @@ -239,11 +240,11 @@ size_t windowsSocket::getBlockSize() const void windowsSocket::receive(vmime::string& buffer) { const size_t size = receiveRaw(m_buffer, sizeof(m_buffer)); - buffer = vmime::string(m_buffer, size); + buffer = utility::stringUtils::makeStringFromBytes(m_buffer, size); } -size_t windowsSocket::receiveRaw(char* buffer, const size_t count) +size_t windowsSocket::receiveRaw(byte_t* buffer, const size_t count) { m_status &= ~STATUS_WOULDBLOCK; @@ -275,7 +276,7 @@ size_t windowsSocket::receiveRaw(char* buffer, const size_t count) } // Read available data - int ret = ::recv(m_desc, buffer, count, 0); + int ret = ::recv(m_desc, reinterpret_cast (buffer), count, 0); if (ret == SOCKET_ERROR) { @@ -317,7 +318,7 @@ void windowsSocket::send(const char* str) } -void windowsSocket::sendRaw(const char* buffer, const size_t count) +void windowsSocket::sendRaw(const byte_t* buffer, const size_t count) { m_status &= ~STATUS_WOULDBLOCK; @@ -325,7 +326,7 @@ void windowsSocket::sendRaw(const char* buffer, const size_t count) while (size > 0) { - const int ret = ::send(m_desc, buffer, size, 0); + const int ret = ::send(m_desc, reinterpret_cast (buffer), size, 0); if (ret == SOCKET_ERROR) { @@ -350,11 +351,11 @@ void windowsSocket::sendRaw(const char* buffer, const size_t count) } -size_t windowsSocket::sendRawNonBlocking(const char* buffer, const size_t count) +size_t windowsSocket::sendRawNonBlocking(const byte_t* buffer, const size_t count) { m_status &= ~STATUS_WOULDBLOCK; - const int ret = ::send(m_desc, buffer, count, 0); + const int ret = ::send(m_desc, reinterpret_cast (buffer), count, 0); if (ret == SOCKET_ERROR) { diff --git a/src/vmime/platforms/windows/windowsSocket.hpp b/src/vmime/platforms/windows/windowsSocket.hpp index e3f43b7c..cb8a6e67 100644 --- a/src/vmime/platforms/windows/windowsSocket.hpp +++ b/src/vmime/platforms/windows/windowsSocket.hpp @@ -55,11 +55,12 @@ public: void disconnect(); void receive(vmime::string& buffer); - size_t receiveRaw(char* buffer, const size_t count); - + size_t receiveRaw(byte_t* buffer, const size_t count); + void send(const vmime::string& buffer); - void sendRaw(const char* buffer, const size_t count); - size_t sendRawNonBlocking(const char* buffer, const size_t count); + void send(const char* str); + void sendRaw(const byte_t* buffer, const size_t count); + size_t sendRawNonBlocking(const byte_t* buffer, const size_t count); size_t getBlockSize() const; @@ -85,7 +86,7 @@ private: shared_ptr m_timeoutHandler; - char m_buffer[65536]; + byte_t m_buffer[65536]; SOCKET m_desc; unsigned int m_status; diff --git a/src/vmime/utility/path.cpp b/src/vmime/utility/path.cpp index 9f746d54..59685866 100644 --- a/src/vmime/utility/path.cpp +++ b/src/vmime/utility/path.cpp @@ -134,8 +134,7 @@ bool path::operator==(const path& p) const bool equal = true; for ( ; equal && i != m_list.end() ; ++i, ++j) - //equal = (*i == *j); - equal = ((*i).getBuffer() == (*j).getBuffer()); + equal = ((*i).isEquivalent(*j)); return (equal); } @@ -197,7 +196,7 @@ bool path::isDirectParentOf(const path& p) const bool equal = true; for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) - equal = (m_list[i] == p.m_list[i]); + equal = (m_list[i].isEquivalent(p.m_list[i])); return (equal); } @@ -211,7 +210,7 @@ bool path::isParentOf(const path& p) const bool equal = true; for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) - equal = (m_list[i] == p.m_list[i]); + equal = (m_list[i].isEquivalent(p.m_list[i])); return (equal); } @@ -226,7 +225,7 @@ void path::renameParent(const path& oldPath, const path& newPath) list::size_type i; for (i = 0 ; equal && i < oldPath.m_list.size() ; ++i) - equal = (m_list[i] == oldPath.m_list[i]); + equal = (m_list[i].isEquivalent(oldPath.m_list[i])); if (i != oldPath.m_list.size()) return; diff --git a/src/vmime/word.cpp b/src/vmime/word.cpp index 2ee4d3e7..7944fc77 100644 --- a/src/vmime/word.cpp +++ b/src/vmime/word.cpp @@ -723,8 +723,17 @@ bool word::operator!=(const word& w) const } +bool word::isEquivalent(const word& other) const +{ + return getConvertedText(charset(charsets::UTF_8)) == other.getConvertedText(charset(charsets::UTF_8)); +} + + const string word::getConvertedText(const charset& dest, const charsetConverterOptions& opts) const { + if (dest == m_charset) + return m_buffer; // no conversion needed + string out; try diff --git a/src/vmime/word.hpp b/src/vmime/word.hpp index a6e2402e..4122228d 100644 --- a/src/vmime/word.hpp +++ b/src/vmime/word.hpp @@ -85,6 +85,14 @@ public: */ void setCharset(const charset& ch); + /** Returns whether two words actually represent the same text, + * regardless of their charset. + * + * @param other word to compare to + * @return true if the two words represent the same text, or false otherwise + */ + bool isEquivalent(const word& other) const; + word& operator=(const word& w); word& operator=(const string& s); diff --git a/tests/parser/emailAddressTest.cpp b/tests/parser/emailAddressTest.cpp index 378cc065..4916aaa9 100644 --- a/tests/parser/emailAddressTest.cpp +++ b/tests/parser/emailAddressTest.cpp @@ -25,6 +25,9 @@ #include "vmime/platform.hpp" +#include +#include + VMIME_TEST_SUITE_BEGIN(emailAddressTest) @@ -41,6 +44,27 @@ VMIME_TEST_SUITE_BEGIN(emailAddressTest) VMIME_TEST_LIST_END + void setUp() + { + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } + } + + void tearDown() + { + // Restore default locale + std::locale::global(std::locale("C")); + } + + void testParseASCII() { vmime::emailAddress eml1("local@domain"); diff --git a/tests/parser/parameterTest.cpp b/tests/parser/parameterTest.cpp index 3b0edebf..4f6f8677 100644 --- a/tests/parser/parameterTest.cpp +++ b/tests/parser/parameterTest.cpp @@ -23,6 +23,9 @@ #include "tests/testUtils.hpp" +#include +#include + VMIME_TEST_SUITE_BEGIN(parameterTest) @@ -62,6 +65,27 @@ VMIME_TEST_SUITE_BEGIN(parameterTest) (p.getParameterAt(n)->getValue().getBuffer()) + void setUp() + { + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } + } + + void tearDown() + { + // Restore default locale + std::locale::global(std::locale("C")); + } + + void testParse() { // Simple parameter diff --git a/tests/parser/textTest.cpp b/tests/parser/textTest.cpp index 274687a5..f56f972d 100644 --- a/tests/parser/textTest.cpp +++ b/tests/parser/textTest.cpp @@ -23,6 +23,9 @@ #include "tests/testUtils.hpp" +#include +#include + VMIME_TEST_SUITE_BEGIN(textTest) @@ -78,6 +81,27 @@ VMIME_TEST_SUITE_BEGIN(textTest) } + void setUp() + { + // Set the global C and C++ locale to the user-configured locale. + // The locale should use UTF-8 encoding for these tests to run successfully. + try + { + std::locale::global(std::locale("")); + } + catch (std::exception &) + { + std::setlocale(LC_ALL, ""); + } + } + + void tearDown() + { + // Restore default locale + std::locale::global(std::locale("C")); + } + + void testConstructors() { vmime::text t1; diff --git a/tests/utility/pathTest.cpp b/tests/utility/pathTest.cpp index 93215586..d0c1c091 100644 --- a/tests/utility/pathTest.cpp +++ b/tests/utility/pathTest.cpp @@ -26,7 +26,7 @@ #include "vmime/utility/path.hpp" -VMIME_TEST_SUITE_BEGIN(pathTest) +VMIME_TEST_SUITE_BEGIN(utilityPathTest) VMIME_TEST_LIST_BEGIN VMIME_TEST(testConstruct1) @@ -50,6 +50,7 @@ VMIME_TEST_SUITE_BEGIN(pathTest) VMIME_TEST(testIsDirectParentOf) VMIME_TEST(testIsParentOf) + VMIME_TEST(testIsParentOf_EquivalentCharset) VMIME_TEST(testRenameParent) VMIME_TEST_LIST_END @@ -271,6 +272,19 @@ VMIME_TEST_SUITE_BEGIN(pathTest) VASSERT_EQ("4", false, p2.isParentOf(p1)); } + void testIsParentOf_EquivalentCharset() + { + path p1; + p1.appendComponent(comp("foo", "us-ascii")); + + path p2; + p2.appendComponent(comp("foo", "utf-8")); + p2.appendComponent(comp("bar")); + p2.appendComponent(comp("baz")); + + VASSERT_EQ("1", true, p1.isParentOf(p2)); + } + void testRenameParent() { path p1;